# LeetSwap: public fee-transfer function drains pair reserves

LeetSwap pair's public _transferFeesSupportingTaxTokens let anyone drain pair reserves, then sync() and swap to extract ~$630K.

- Payout: Real-world hack
- Severity: high
- Program: LeetSwap
- Analysis by: DeFiHackLabs
- Disclosed: 2023-08-01
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-08/Leetswap_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230801-leetswap
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:access-control vuln:business-logic

**Target:** LeetSwap AMM pair contract on Base
**Root cause:** The pair exposes _transferFeesSupportingTaxTokens as an unrestricted external function, letting any caller move the pair's token balance out to an arbitrary recipient without authorization.
**Steps:**
1. Fork Base at block 2031746; fund attacker with 0.001 WETH.
2. Approve Router and swap 0.001 WETH for axlUSDC via `swapExactTokensForTokensSupportingFeeOnTransferTokens` to establish position.
3. Call `Pair._transferFeesSupportingTaxTokens(address(axlUSDC), axlUSDC.balanceOf(address(Pair)) - 100)` to drain nearly all axlUSDC from the pair.
4. Call `Pair.sync()` to update reserves to the drained state.
5. Approve and swap the received axlUSDC back to WETH via the Router, capturing the value.
**Exploitation:** Attacker called the unprotected fee-transfer function to move the pair's axlUSDC balance to themselves, synced reserves, then swapped the stolen axlUSDC for WETH through the router, netting ~$630K.
**Insight:** On forked AMMs, audit every external function on the pair contract—especially fee/tax helpers—for missing access control; a public balance-moving function plus sync() is a direct reserve drain.

