# XDKRecycle: reserve manipulation via recycle sell path drains pair

XDK's recycle sell path moved tokens directly out of its Pancake pair and synced it, letting an attacker flash-borrow GPC and drain 6.84 WBNB.

- Payout: Real-world hack
- Severity: high
- Program: XDKRecycle
- Credited: DefimonAlerts
- Disclosed: 2026-02-16
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-02/XDKRecycle_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260216-xdkrecycle
- Tags: 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:** Solidity token contract with PancakeSwap pair (BSC)
**Root cause:** XDK's sell/recycle path transfers XDK directly out of its Pancake pair and calls sync, letting an attacker manipulate the pair reserves without paying the AMM curve price.
**Steps:**
1. Flash-borrow 99% of GPC from WBNB/GPC Pancake pair via `flashPair.swap(0, borrowAmount, ...)`.
2. If recycle window stale (`block.timestamp > lastRecycleTime + recycleColdTime`), prime it with a small GPC transfer + swap + skim.
3. Loop up to 20x: buy XDK from XDK/GPC pair in ~10% reserve chunks via `swap(amountOut, 0, ...)`.
4. Loop up to 55x: transfer XDK to pair and `skim` to push `thisRecycleBalance` toward `thisRecycleMaxBalance`, exploiting recycle path.
5. Loop up to 27x: sell remaining XDK back to pair for GPC via `swap(0, amountOut, ...)`.
6. Repay flash loan `borrowed*10000/9975+1` GPC, swap surplus GPC→WBNB via router, forward profit.
**How found:** Analysis of XDK's sell path revealed it moves XDK directly out of its Pancake pair and syncs the pair, breaking the AMM invariant; attacker exploited this with a flash loan to repeatedly buy/sell in reserve-sized chunks.
**Exploitation:** Attacker flash-borrowed ~99% of GPC from the WBNB/GPC pair, used it to buy XDK in 10% reserve chunks, repeatedly triggered XDK's recycle sell path (which moves XDK out of the pair and syncs), then sold remaining XDK back for GPC, repaid the flash swap, and converted surplus GPC to 6.84 WBNB.
**Insight:** When a token's sell/recycle function transfers tokens out of its own AMM pair and calls sync, the pair reserves can be desynced from the curve — look for tokens whose transfer/sell logic touches the pair directly rather than routing through the router.
