# HackDao: skim() manipulation drains WBNB from LP pairs

HackDao token skim() on its BSC PancakeSwap pairs let an attacker burn LP-held tokens and swap out WBNB via flash loan.

- Payout: Real-world hack
- Severity: high
- Program: HackDao
- Analysis by: DeFiHackLabs
- Disclosed: 2022-05-24
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-05/HackDao_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20220524-hackdao
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:business-logic vuln:oracle-manipulation

**Target:** HackDao token and its PancakeSwap V2 WBNB/USDT pairs on BSC
**Root cause:** The HackDao token's transfer/skim behavior on the LP pairs allowed an attacker to inject tokens and call skim() to move the pair's excess token balance, desyncing reserves so a subsequent swap paid out more WBNB than fair.
**Steps:**
1. Flash loan 1900 WBNB from DODO (`flashLoan(1900e18,0,...)`).
2. Swap WBNB for HackDao via PancakeSwap router (`swapExactTokensForTokensSupportingFeeOnTransferTokens`).
3. Transfer all HackDao to Pair1 (HackDao/WBNB) and call `Pair1.skim(address(Pair2))`, then `Pair1.sync()`.
4. Call `Pair2.skim(address(Pair1))` to move HackDao/USDT pair excess into Pair1.
5. Read Pair1 reserves, compute amountIn = HackDao.balanceOf(Pair1) - reserve0, and call `Pair1.swap(0, amountout, attacker, "")` to extract WBNB.
6. Repay 1900 WBNB to DODO; keep profit.
**Exploitation:** Attacker flash-borrowed 1900 WBNB, bought HackDao, dumped it into the WBNB pair, then abused skim()/sync() across both pairs to inflate the pair's token balance relative to reserves, and swapped the excess for WBNB, repaying the loan and keeping the remainder.
**Insight:** On fork-V2 pairs, watch for tokens whose transfer hooks or skim()/sync() let you desync reserve0 from actual token balance; injecting tokens then swapping against stale reserves yields outsized output.

