# NGP token: spot oracle manipulation drains PancakeSwap pool

NGP token's spot-reserve price oracle plus premature fee/sync logic let an attacker flash-loan-manipulate the PancakeSwap pair and drain ~$2M USDT.

- Payout: Real-world hack
- Severity: critical
- Program: NGP
- Credited: DeFiHackLabs
- Disclosed: 2025-09-18
- Write-up quality: 8/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-09/NGP_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250918-ngp
- 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:** BEP-20 token price oracle and PancakeSwap NGP/USDT pair
**Root cause:** getPrice() derives price from instantaneous NGP/USDT pair reserves, and _update() deducts sell fees from the pair and calls sync() before the seller's tokens transfer, so reserves can be skewed within one transaction.
**Steps:**
1. Flash-loan ~211M USDT from Morpho/Venus.
2. Swap USDT->NGP via router with recipient=DEAD (whitelisted) to bypass maxBuyAmountInUsdt and cooldown, dumping NGP into dead address and crushing pair NGP reserve.
3. Swap accumulated NGP->USDT; _update() deducts fees from mainPair and calls IUniswapV2Pair.sync() before seller transfer, inflating price.
4. Sell at inflated price to drain pair USDT.
5. Repay flash loan; convert proceeds to ETH.
**How found:** Analysis of getPrice() using raw pair reserves and _update() calling sync() before seller transfer, plus noticing DEAD address in whitelist bypassing buy limits.
**Exploitation:** Single atomic tx: flash loan USDT, use whitelisted DEAD address to bypass buy limits/cooldown, reduce pair NGP reserves to ~0.035 tokens breaking k=xy, then sell NGP at manipulated high price to drain ~$2M USDT from the pool.
**Escalation:** Chained three flaws (spot oracle, premature fee/sync, DEAD whitelist) into one flash-loan tx to bypass all limits and drain full liquidity.
**Insight:** Check whether token fee logic mutates AMM pair balances and calls sync() before the actual transfer; combined with a reserve-ratio oracle this lets you skew price mid-transaction. Also grep whitelists for burn/dead addresses that skip limits.
