# BurnsDefi: spot-price manipulation in burnToHolder drains rewards

BurnsDefi's burnToHolder priced burns via spot Burns/WBNB reserves, letting an attacker flash-loan BUSDT, skew the pair, and mint excess Burns for ~$67K profit.

- Payout: Real-world hack
- Severity: high
- Program: BurnsDefi
- Analysis by: DeFiHackLabs
- Disclosed: 2024-02-05
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-02/BurnsDefi_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20240205-burnsdefi
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:business-logic vuln:flash-loan vuln:oracle-manipulation

**Target:** BEP-20 BurnsBuild contract burnToHolder/receiveRewards on BSC
**Root cause:** burnToHolder computes burn amounts using getAmountsOut against the live Burns/WBNB Pancake pair reserves, so an attacker who moves the pair price gets a favorable burn rate and inflated rewards.
**Steps:**
1. Flash-loan 250,000 BUSDT from DVM DSP via `DSP.flashLoan(250_000e18, 0, address(this), data)`.
2. Swap borrowed BUSDT into BUSDT/WBNB pair to obtain WBNB, then deposit WBNB into Burns/WBNB pair and swap out Burns, skewing the Burns/WBNB reserves.
3. Call `BurnsBuild.burnToHolder(amounts[0], exploiter)` where `amounts[0] = PancakeRouter.getAmountsIn(50e18, [Burns, WBNB])` — burn priced off manipulated reserves.
4. Call `burnToHolder` again with `getAmountsIn(address(Burns).balance - 50e18, path)` to burn remaining Burns.
5. Call `BurnsBuild.receiveRewards(address(this))` to collect inflated rewards.
6. Wrap ETH to WBNB, swap WBNB→BUSDT and Burns→WBNB→BUSDT to realize profit.
7. Repay flash loan `BUSDT.transfer(address(DSP), baseAmount)` and transfer remaining BUSDT to exploiter.
**How found:** Attacker likely noticed burnToHolder and receiveRewards rely on PancakeRouter.getAmountsOut against live Burns/WBNB reserves, making the reward calculation manipulable via a flash-loan-funded swap on the same pair.
**Exploitation:** Attacker flash-borrowed 250K BUSDT, used it to push WBNB into the Burns/WBNB pair and pull out Burns, manipulating the pair reserves that burnToHolder reads. With reserves skewed, burnToHolder minted/burned at a favorable rate, and receiveRewards paid out based on the manipulated state. Attacker then unwound positions through Pancake swaps and repaid the loan, netting ~$67K.
**Insight:** When a reward/burn function calls getAmountsOut on a DEX pair, check whether the caller can move that pair's reserves in the same transaction — flash-loan-funded swaps into the reward pair are the standard trigger.
