# UniV2ClassDex.sol#uniClassSell() Tokens with fee on transfer are not fully supported

OpenLeverage's uniClassSell checked minBuyAmount against getAmountOut output instead of actual received balance, so fee-on-transfer buy tokens caused slippage beyond the minimum.

- Payout: Audit contest
- Severity: medium
- Program: OpenLeverage
- Found by: WatchPug
- Disclosed: 2022-03-09
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-01-openleverage-findings/issues/208
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-openleverage%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** UniV2ClassDex.sol swap helper (Solidity DEX adapter)
**Root cause:** uniClassSell() validates minBuyAmount against the getAmountOut() estimate rather than the actual buyToken balance delta at the payee, so fee-on-transfer buy tokens deliver less than the checked amount.
**Steps:**
1. Call the sell path that invokes `uniClassSell()` with a buyToken that charges a transfer fee
2. `uniClassSell` computes `buyAmount = getAmountOut(...)` and calls `swap(buyAmount, 0, payee, "")`
3. `require(buyAmount >= minBuyAmount)` passes on the estimate
4. Payee receives `buyAmount - fee`, less than minBuyAmount; compare with `uniClassBuy` which measures `balanceOf(payee)` delta
**How found:** Noticed asymmetry: uniClassBuy measures actual received balance via before/after balanceOf, while uniClassSell trusts getAmountOut() output for its minBuyAmount check.
**Exploitation:** A user swapping into a fee-on-transfer token receives less than their stated minimum; the slippage check passes on the pre-fee estimate, leaking value to the user's detriment.
**Insight:** When auditing swap adapters, compare every buy/sell pair for symmetric accounting: if one side measures real balance deltas and the other trusts a quote, the trusting side breaks on fee-on-transfer or rebasing tokens.
