# DLMC: reserve-derived livePrice manipulation drains USDT reserves

DLMC's reserve-derived livePrice was inflated by a second buy via a child affiliate, letting attacker sell max DLMC and drain 222,560 USDT.

- Payout: Real-world hack
- Severity: critical
- Program: DLMC
- Credited: DeFiHackLabs
- Disclosed: 2026-06-24
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-06/DLMC_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260624-dlmc
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:chained vuln:business-logic vuln:flash-loan vuln:oracle-manipulation

**Target:** BSC staking/token contract with buy/sell and affiliate registration
**Root cause:** livePrice is derived from the token contract's own USDT reserve, so a large buy inflates the price used to compute the sell payout; sell() pays out based on this manipulable reserve-derived price.
**Steps:**
1. Flash-swap 1,420,000 USDT from Pancake USDT/WBNB pair via `pair.swap(FLASH_USDT, 0, this, ...)`
2. In pancakeCall, call `dlmc.registerAffiliate(REGISTERED_REFERRER)` to gain investment capacity
3. First buy: `usdt.approve(DLMC, max)` then `dlmc.buy(420_000e18)`
4. Deploy DLMCBuyHelper, transfer 1,000,000 USDT, helper calls `registerAffiliate(coordinator)` then `dlmc.buy(1_000_000e18)` to inflate reserve-derived livePrice
5. Compute `sellAmount = min(balanceOf(this), usdt.balanceOf(DLMC)*1e18/livePrice())` and call `dlmc.sell(sellAmount)`
6. Repay Pancake pair `(FLASH_USDT*10000)/9975+1` and transfer remaining USDT to profit receiver
**How found:** Attacker observed that livePrice is computed from the token contract's own USDT reserve and that buy() moves that reserve, making the sell payout price manipulable within one transaction; affiliate registration was used to satisfy buy/sell capacity checks.
**Exploitation:** Single-transaction flash swap funds two staged buys through affiliate-linked contracts; the second buy pumps the reserve-derived livePrice, then the first contract sells the maximum DLMC backed by the contract's USDT balance, extracting ~222,560 USDT before repaying the flash loan.
**Insight:** When a token's sell price is derived from its own quote-token reserve (usdt.balanceOf(token)/livePrice), any buy() that grows that reserve inflates the payout; check whether affiliate/referrer registration gates buy capacity and can be chained to stack buys before a single sell.
