T09 · Insecure Skill Coding Practices
Error
- Location
- src/pool.ts:61
- Finding
- Initial Token Purchase Executes Without Slippage Protection<![CDATA[ ## Vulnerability Details **File Location**: `src/pool.ts:61-71` **Vulnerability Type**: Unbounded swap slippage **Risk Level**: High ### Vulnerable Code ```ts firstBuyParam: { buyer: payer.publicKey, buyAmount: new BN(firstBuyLamports), minimumAmountOut: new BN(0), referralTokenAccount: null, }, ``` ### Technical Analysis The initial token purchase explicitly sets `minimumAmountOut` to zero. This means the swap imposes no lower bound on the number of tokens the user must receive in exchange for the specified SOL amount. The pool creation and initial purchase are submitted as separate transactions. After the pool-creation transaction is confirmed and before the purchase transaction is executed, pool conditions may change. Because the purchase remains valid at any output amount, adverse price movement, front-running, sandwich activity, or other pool-state changes cannot cause it to fail based on unacceptable execution price. The behavior exceeds the minimum financial authority required for an initial purchase: the wallet authorizes spending a fixed quantity of SOL without enforcing a corresponding minimum return. ### Attack Path 1. The user invokes the Skill with a positive `--first-buy` value. 2. The Skill constructs the purchase with `minimumAmountOut` equal to zero. 3. The pool-creation transaction is submitted and confirmed. 4. Before the separate purchase transaction is confirmed, an attacker or ordinary market activity changes the pool price. 5. The purchase executes at the worsened price because no minimum output is enforced. 6. The user spends the requested SOL while potentially receiving substantially fewer tokens than expected. ### Impact Assessment An attacker does not gain system privileges or direct control of the wallet. However, an attacker capable of influencing transaction ordering or pool state may extract financial value from the purchase through adverse execution. The scope is limited to the SOL authorize ...[truncated 178 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Obtain a current output quote immediately before constructing the purchase transaction. 2. Require a user-configurable maximum slippage percentage with a conservative default. 3. Calculate a nonzero minimum output: ```ts const minimumAmountOut = expectedAmountOut .mul(new BN(10_000 - slippageBps)) .div(new BN(10_000)); ``` 4. Pass the calculated value to `minimumAmountOut` instead of zero. 5. Reject stale quotes and rebuild the transaction if the pool state changes materially. 6. Validate that `--first-buy` is finite, nonnegative, and below a configurable maximum. 7. Display the expected output, minimum output, SOL expenditure, slippage tolerance, and destination pool before requesting confirmation. 8. Abort the purchase when a reliable quote cannot be obtained. ]]>
