# Zeed Finance: LP pool drained via skim and flash loan

Zeed Finance LP pool on BSC was drained via flash loan and repeated skim() calls exploiting incorrect reserve calculation, netting attacker ~$1M.

- Payout: Real-world hack
- Severity: high
- Program: Zeed Finance
- Analysis by: DeFiHackLabs
- Disclosed: 2022-04-21
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-04/Zeed_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20220421-zeed
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm vuln:accounting-error vuln:business-logic vuln:flash-loan

**Target:** PancakeSwap LP pairs and Zeed Finance token contracts on BSC
**Root cause:** Incorrect calculation in Zeed Finance's LP pool allowed an attacker to manipulate reserves through repeated skim() calls, exploiting the difference between actual token balances and recorded reserves.
**Steps:**
1. Flash loan from USDT-YEED-HoSwap pair via `swap(0, _reserve1 - 1, address(this), new bytes(1))`.
2. In callback, transfer borrowed YEED to USDT-YEED pair.
3. Loop 10 times: `usdtYeedPair.skim(address(hoYeedPair))`, `hoYeedPair.skim(address(zeedYeedPair))`, `zeedYeedPair.skim(address(usdtYeedPair))`.
4. Skim remaining tokens from all three pairs to attacker.
5. Repay flash loan with `yeed.transfer(msg.sender, (amount1 * 1000) / 997)`.
6. Swap remaining YEED for USDT via PancakeRouter to realize profit.
**Exploitation:** Attacker used a flash loan to borrow nearly all YEED from a PancakeSwap pair, then manipulated reserves across three Zeed-related pairs by repeatedly calling skim() to transfer excess tokens between them, ultimately draining value and repaying the loan with a small fee.
**Insight:** Repeated skim() calls can be used to manipulate reserves in pools that rely on balance-based calculations, especially when multiple pools share tokens; flash loans amplify the effect.

