# DEXRouter: arbitrary external call drains BNB balance

DEXRouter's functionCallWithValue made an arbitrary external call, letting an attacker drain the contract's ~$4K BNB balance to themselves.

- Payout: Real-world hack
- Severity: high
- Program: DEXRouter
- Analysis by: DeFiHackLabs
- Disclosed: 2023-09-29
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-09/DEXRouter_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230929-dexrouter
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm technique:source-review vuln:access-control vuln:business-logic

**Target:** Unverified BSC DEXRouter contract (functionCallWithValue/update)
**Root cause:** functionCallWithValue forwards an attacker-supplied target and calldata, performing an arbitrary external call; combined with update() setting state, the attacker redirects the call to themselves and the contract transfers its BNB balance.
**Steps:**
1. Fork BSC at block 32161325 against victim 0x1f7cF218B46e613D1BA54CaC11dC1b5368d94fb7.
2. Call `DEXRouter.update(address(this), address(this), address(this), address(this))` to set state to attacker addresses.
3. Call `DEXRouter.functionCallWithValue(address(this), abi.encodePacked(this.a.selector), address(DEXRouter).balance)` to trigger arbitrary call to attacker with full BNB balance.
4. Attacker's `a()` payable returns true; contract sends its BNB balance to attacker.
**How found:** Researcher noted the unverified contract's functionCallWithValue performs an arbitrary external call and that update() lets the caller control the target, enabling redirection of the router's balance.
**Exploitation:** Attacker first calls update() to point router config at their own contract, then invokes functionCallWithValue targeting themselves with the router's entire BNB balance as value; the router forwards the funds, netting ~$4K.
**Insight:** On unverified router contracts, look for a public functionCallWithValue-style helper that forwards caller-supplied target+calldata; if a preceding setter (update) lets you control the target, you can redirect the contract's own balance to yourself.

