# XSDWETHpool: reentrancy via swap callback drains 56.9 BNB

Reentrancy in XSDWETHpool's swap callback let attacker re-enter via fallback, call systemCalculations, and drain ~56.9 BNB.

- Payout: Real-world hack
- Severity: high
- Program: XSDWETHpool
- Analysis by: DeFiHackLabs
- Disclosed: 2023-09-26
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-09/XSDWETHpool_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230926-xsdwethpool
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:flash-loan vuln:oracle-manipulation vuln:reentrancy

**Target:** BSC DEX pool (XSD/WBNB) with flash-loan-funded swap
**Root cause:** The pool's swap() sends ETH/WBNB to the caller before state is finalized, and the attacker's fallback re-enters swap() and PIDController.systemCalculations() to manipulate reserves/pricing.
**Steps:**
1. Flash loan 3000 BNB from DPPOracle, then 1000 BNB from DPPAdvanced.
2. Call `Router.swapXSDForETH(9_840_000_000_000_000_000, XSD.balanceOf(this))` to obtain WBNB.
3. Transfer `swapAmount` XSD to XSDWETHpool and call `XSDWETHpool.swap(0, attackAmount + exploitAmount, address(this))`.
4. In the ETH/WBNB receive fallback, transfer `attackAmount` WBNB back to the pool and call `XSDWETHpool.swap(swapAmount, 0, address(this))` (reentrancy).
5. Call `PIDController.systemCalculations()` and `Router.swapETHForBankX{value: 1e12}(100)` to finalize manipulation.
6. Repay flash loans; net ~56.96 BNB profit.
**Exploitation:** Attacker flash-borrowed BNB, swapped into the XSD/WBNB pool, then re-entered the pool from the ETH receive hook to swap again and trigger PIDController recalculation, extracting ~56.9 BNB before repaying loans.
**Escalation:** Chained two flash loans (DPPOracle + DPPAdvanced) to scale capital and amplify the reentrancy-driven reserve manipulation.
**Insight:** Pools that push native/ERC20 value to the caller before updating reserves are reentrancy-prone; watch for external calls (ETH transfer, token transfer) preceding state writes and for oracle/PID recalculation hooks reachable mid-swap.

