# Incorrect fee calculation on LBPair (fees collected on swaps are less than what they "should" be)

Trader Joe LBPair SwapHelper.getAmounts applies getFeeAmountFrom instead of getFeeAmount, under-collecting swap fees by 0.1% per bin and growing with multi-bin swaps.

- Payout: Contest reward
- Severity: medium
- Program: Trader Joe
- Credited: sha256yan
- Disclosed: 2022-12-22
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-10-traderjoe-findings/issues/470
- Library page: https://bugbountylibrary.com/r/c4%3A2022-10-traderjoe%3AM-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:fee-bypass

**Target:** LBPair/LBRouter/SwapHelper Solidity libraries (DEX swap fee math)
**Root cause:** SwapHelper.getAmounts computes fees with FeeHelper.getFeeAmountFrom (fee = amountIn*totalFee/(PRECISION+totalFee)) when liquidity suffices, instead of getFeeAmount (amountIn*totalFee/PRECISION); the overflow condition also checks fees on _maxAmountInToBin rather than amountIn, and LBRouter.getSwapIn computes fees on amountInToBin instead of amountIn.
**Steps:**
1. Call LBPair.swap with amountIn=1e10, totalFee=0.00125e18, PRECISION=1e18, price=1.
2. Observe fee collected via getFeeAmountFrom = 12484394 vs correct getFeeAmount = 12500000.
3. Run `forge test --match-contract Report -vv` to see testSingleBinSwapFeeDifference and testMultiBinGrowth showing deficit grows per bin.
4. Check SwapHelper.getAmounts condition `_maxAmountInToBin + fees.total <= amountIn` causing false-positive bin deactivation.
5. Compare with patched getAmountsV2 using getFeeAmount(amountIn) and `_maxAmountInToBin < amountIn - fees.total`.
6. Call LBRouter.getSwapIn/getSwapOut to observe simulated fee mismatch.
**How found:** Warden read SwapHelper.getAmounts and noticed fee computed via getFeeAmountFrom on amountIn (which is already the excess transferred amount), then compared formulas numerically and built forge tests to quantify the deficit and false-positive bin deactivation.
**Exploitation:** Not an attack; LPs and protocol passively lose a fraction of swap fees (up to ~1.6-2% of expected fees) on every swap, growing with multi-bin swaps and high volatility volume.
**Insight:** When a contract receives tokens first and derives amountIn as balance minus reserves, fees must be taken as a percentage of that gross amount (getFeeAmount), not grossed-up from a net amount (getFeeAmountFrom); check which side of the fee the variable represents before picking the helper.
