# Discrepancy in Price Checks in shared_accounts.rs::calculate_fees() Function

Tensor NFT buy price check omits taker fees, so buyers pay more than their stated max_amount, weakening sandwich protection.

- Payout: Contest reward
- Severity: medium
- Program: Tensor
- Credited: joicygiore
- Disclosed: 2025-01-31
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_tensor_nov2024.pdf#3.2.5
- Library page: https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.5
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:solana technique:source-review vuln:business-logic vuln:fee-bypass

**Target:** Solana AMM program shared_accounts.rs calculate_fees / buy_nft
**Root cause:** calculate_fees() validates current_price + mm_fee + creators_fee against user_price but pay_buyer_fees() also transfers tamm_fee, maker_broker_fee and taker_broker_fee, so the enforced cap excludes taker fees.
**Steps:**
1. Call `buy_nft(max_amount)` with max_amount set to the intended spend cap.
2. calculate_fees() checks `current_price + mm_fee + creators_fee > user_price` only.
3. pay_buyer_fees() additionally transfers tamm_fee, maker_broker_fee, taker_broker_fee from taker.
4. Observe buyer balance decrease exceeds max_amount (PoC test asserts actualSpentAmount > maxAmount).
**How found:** Code-reading comparison of the price validation in calculate_fees() against the actual transfer sequence in pay_buyer_fees(), noticing the fee components transferred but not included in the check.
**Exploitation:** A sandwich/MEV attacker can push the effective price up to max_amount plus the omitted taker fees, extracting more from the buyer than the buyer's stated slippage cap allows.
**Insight:** When a slippage/max-amount guard exists, diff the guard's arithmetic against the full set of transfers executed at settlement; fee components added later in the payment path are commonly omitted from the check.
