# BeefyZapRouter: arbitrary external call drains vault token allowances

BeefyZapRouter.executeOrder executed caller-supplied route steps, letting an attacker call transferFrom on vault tokens to drain victims' allowances for ~$6.6k.

- Payout: Real-world hack
- Severity: high
- Program: BeefyZapRouter
- Credited: DeFiHackLabs
- Disclosed: 2025-08-13
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-08/BeefyZapRouter_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250813-beefyzaprouter
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** BeefyZapRouter.executeOrder on Arbitrum
**Root cause:** executeOrder's direct execution path only checks msg.sender == order.user, then executes arbitrary caller-supplied route steps (target + calldata) from the router's context, so any calldata including ERC20 transferFrom can be invoked against tokens holding third-party allowances to the router.
**Steps:**
1. Set order.user and order.recipient to the attacker/helper contract so the msg.sender==order.user check passes.
2. Build route steps with target = Beefy vault token addresses and data = `transferFrom(victim, attacker, amount)`.
3. Call `executeOrder(order, route)` on 0xf49F7bB6F4F50d272A0914a671895c4384696E5A.
4. Router executes each step, spending victims' allowances to the router and transferring vault tokens to attacker.
**Exploitation:** Attacker deployed a helper contract, set order.user to itself to satisfy the auth check, and supplied two route steps targeting Beefy vault tokens A and B with transferFrom calldata pulling victims' balances (2.78e21 and 2.78e21) to the attack contract, netting ~6,584.95 USD.
**Insight:** Zap/router contracts that execute arbitrary user-supplied (target, calldata) steps are dangerous when they hold ERC20 allowances: any token with an outstanding allowance to the router becomes drainable via transferFrom calldata, so audit routers for unrestricted external-call primitives and check which tokens grant them allowances.
