# Last buy might charge the wrong fee

On the final bonding-curve buy, price recomputation changes actual SOL paid but fee was precomputed on the original input, mischarging fees and risking account closure.

- Payout: Contest reward
- Severity: medium
- Program: Pump Science
- Credited: shaflow2
- Disclosed: 2025-02-26
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-01-pump-science#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2025-01-pump-science%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:rust tech:solana technique:source-review vuln:accounting-error vuln:fee-bypass

**Target:** Solana bonding curve program (curve.rs apply_buy)
**Root cause:** Fee is computed from exact_in_amount before apply_buy, but the last-buy branch recomputes sol_amount from reserves, so the actual SOL paid differs from the amount the fee was based on.
**Steps:**
1. Call buy with exact_in_amount such that token_amount >= real_token_reserves (last buy).
2. Observe fee_lamports = calculate_fee(exact_in_amount) computed pre-call.
3. apply_buy sets virtual_sol_reserves to 115_005_359_056 and recomputes sol_amount via get_sol_for_sell_tokens, changing actual SOL paid.
4. Fee no longer matches actual payment; if actual SOL increases, user lamports check (>= exact_in_amount + min_rent) is not revalidated, risking account closure.
**How found:** Code reading of the buy flow: noticed fee computed before apply_buy while the last-buy branch mutates sol_amount afterward, creating a mismatch.
**Exploitation:** Attacker times a buy to be the final purchase so the recomputed sol_amount diverges from exact_in_amount; pays an incorrect fee and, if actual cost rises, may leave insufficient lamports for rent causing account closure.
**Insight:** When a function recomputes the actual input amount internally (curve-fitting last-buy), any fee or balance check done on the pre-call input is stale; audit ordering between fee computation and amount-mutating branches.
