# ShadowFi: public burn() drains SDF/WBNB pair reserves

ShadowFi SDF token's public burn() let an attacker burn the pair's SDF reserves, then sync() to skew the pool and drain WBNB via a swap.

- Payout: Real-world hack
- Severity: high
- Program: ShadowFi
- Analysis by: DeFiHackLabs
- Disclosed: 2022-09-02
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-09/Shadowfi_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20220902-shadowfi
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** SDF token contract and SDF/WBNB PancakeSwap pair on BSC
**Root cause:** The SDF token exposes an unrestricted burn(address,uint256) that lets anyone destroy tokens held by any address, including the liquidity pair, without authorization.
**Steps:**
1. Fork BSC at block 20969095 and fund the attacker contract with 0.01 BNB wrapped to WBNB.
2. Swap WBNB for SDF via the PancakeSwap router (`swapExactTokensForTokensSupportingFeeOnTransferTokens`).
3. Call `SDF.burn(address(Pair), SDF.balanceOf(address(Pair)) - 1)` to burn nearly all SDF held by the pair.
4. Call `Pair.sync()` to force the pair to update reserves to the manipulated balances.
5. Swap the acquired SDF back to WBNB via the router, extracting value from the skewed pool.
**Exploitation:** Attacker bought a small amount of SDF, then used the public burn() to destroy the pair's SDF reserve, called sync() to commit the skewed reserves, and swapped back to WBNB at the manipulated price, draining the pool's WBNB.
**Insight:** When auditing a token, check whether burn/mint/transfer hooks accept an arbitrary address argument; a burn() callable on the LP pair lets you delete reserves and sync() to reprice the pool for a one-block drain.

