# MEVBOT 0xbad: arbitrary call in dYdX callback drains WETH

MEV bot 0xbad's dYdX flashloan callback callFunction allowed arbitrary execution, letting an attacker make the bot approve its WETH and drain 1,101 ETH.

- Payout: Real-world hack
- Severity: critical
- Program: MEVBOT
- Analysis by: DeFiHackLabs
- Disclosed: 2022-09-28
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-09/MEVbadc0de_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20220928-mevbadc0de
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** dYdX Solo Margin flashloan callback (callFunction) on an arbitrage contract
**Root cause:** The bot's dYdX flashloan callback (callFunction) performed arbitrary execution of attacker-supplied calldata instead of validating the caller and operation, so the attacker could invoke token approve/transfer on the bot's behalf.
**Steps:**
1. Attacker calls dYdX Solo Margin `operate` with an ActionType.Call action whose otherAddress is the MEVBOT contract and data is crafted calldata.
2. dYdX invokes the bot's `callFunction` with the attacker-controlled data, which the bot executes without validation.
3. Crafted calldata causes the bot to `approve` the attacker's contract for its full WETH balance.
4. Attacker calls `transferFrom(MEVBOT, attacker, weth.balanceOf(MEVBOT))` to drain all WETH.
**How found:** Attacker noticed the bot's dYdX flashloan callback (callFunction) executed arbitrary calldata without validating the caller or operation, allowing them to make the bot approve tokens to an attacker-controlled contract.
**Exploitation:** Attacker used dYdX's flashloan callback path to force the MEVBOT contract to approve the attacker's contract for its entire WETH balance, then pulled the WETH out via transferFrom, taking the 800 ETH just earned plus the rest of the 1,101 ETH in the bot's wallet.
**Insight:** Flashloan callbacks that execute arbitrary calldata are a direct path to making the victim contract approve or transfer its own funds; audit any callback invoked by a lending router for missing caller/operation validation.

## Proof of concept (copied exactly from the original report)

**Drain WETH via transferFrom after approval**

```
weth.transferFrom(MEVBOT, exploiter, weth.balanceOf(MEVBOT));

        emit log_named_decimal_uint("MEV Bot WETH balance After exploit:", weth.balanceOf(MEVBOT), 18);

        emit log_named_decimal_uint("Exploiter WETH balance After exploit:", weth.balanceOf(exploiter), 18);

        assertEq(weth.balanceOf(MEVBOT), 0);
```

