T09 · Insecure Skill Coding Practices
Error
- Location
- client/src/solana/index.js:274
- Finding
- Incorrect SPL Token Decimal Conversion Can Cause 1,000× Overpayment<![CDATA[ ## Vulnerability Details **File Location**: `client/src/solana/index.js:274-280` **Vulnerability Type**: Incorrect cryptocurrency amount conversion **Risk Level**: Critical ### Vulnerable Code ```js const transferInstruction = createTransferInstruction( sourceTokenAccount, destTokenAccount, this.publicKey, amount * Math.pow(10, 9) // Convert to smallest unit ); ``` The same module assumes that BOB has six decimal places when verifying transfers: ```js return { amount: amount / Math.pow(10, 6), // Convert from smallest unit (BOB has 6 decimals) recipient, tokenMint, source: accountKeys[sourceIndex].toBase58() }; ``` ### Technical Analysis The payment sender converts the human-readable token amount to base units using `10^9`, while the payment verification logic converts base units back using `10^6`. Under the module's stated assumption that BOB has six decimals, the sender creates a transfer 1,000 times larger than intended. For example, a displayed price of `0.05 BOB` is converted into `50,000,000` base units. With six decimals, that value represents `50 BOB`, not `0.05 BOB`. The code also uses JavaScript floating-point arithmetic for token amounts. This can introduce rounding or precision errors and is unsuitable for constructing exact on-chain integer amounts. ### Attack Path 1. A consumer selects an API advertised at a particular BOB price. 2. The HTTP provider or P2P listing supplies the price to the client. 3. `sendPayment()` multiplies that price by `10^9`. 4. The resulting transaction is signed with the consumer's private key and submitted to Solana. 5. If the mint uses the six decimals assumed elsewhere in the module, the provider receives 1,000 times the intended amount. A malicious provider can deliberately encourage calls with an apparently inexpensive price and benefit from the erroneous conversion. ### Impact Assessment Successful exploitation or ordinary use can cause direct and irreversible ...[truncated 258 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Query the mint's actual decimal count from Solana instead of hardcoding it. - Convert amounts with integer or `BigInt` arithmetic. - Use a decimal parsing routine that rejects values with excessive fractional precision. - Reject `NaN`, infinity, negative values, zero values where inappropriate, and amounts exceeding configured limits. - Present the exact base-unit and human-readable amount to the user before signing. - Add unit and integration tests for fractional prices, maximum values, and the configured mint's actual decimals. - Ensure sending and verification use the same decimal value and conversion utility. ]]>
