# Hack Analysis: 0xbaDc0dE MEV Bot, September 2022

0xbad MEV bot's unverified proxy executed arbitrary encoded calls via dYdX SoloMargin callback, auto-approving attacker for all WETH, drained 1,101 WETH (~$1.46m).

- Payout: Real-world hack
- Severity: critical
- Program: 0xbaDc0dE MEV Bot
- Credited: Immunefi
- Disclosed: 2023-01-25
- Write-up quality: 9/10
- Original: https://immunefi.com/blog/bug-fix-reviews/hack-analysis-0xbadc0de-mev-bot-september-2022/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-0xbadc0de-mev-bot-september-2022
- Tags: domain:web3 impact:funds-loss kind:incident platform:immunefi sev:critical tech:evm tech:solidity technique:chained technique:reverse-engineering technique:source-review vuln:access-control vuln:business-logic

**Target:** Unverified Ethereum MEV bot proxy contract (0xbaDc0dE) with delegatecall implementation 0xDd6B
**Root cause:** The bot's callFunction callback, reachable via dYdX SoloMargin.operate, decoded attacker-supplied data to make arbitrary external calls and auto-approved the caller for its full token balance when allowance was zero, with no validation of target addresses or return values.
**Steps:**
1. Read storage slots of 0xbaDc0dE via Foundry vm.load; slot 0x00 holds implementation 0xDd6B, slot 0x03 holds dYdX SoloMargin (authorized caller).
2. Decompile 0xDd6B with EtherVM/Dedaub; identify callFunction(address,(address,uint256),bytes) as SoloMargin callback.
3. Call SoloMargin.operate with ActionType.Call, otherAddress=0xbaDc0dE, owner=attacker, data encoding calls to Curve.exchange and UniswapV2Router.swapExactTokensForTokens.
4. Replace encoded target addresses with attacker contract; observe bot approves attacker for full WETH balance when allowance is 0.
5. Implement exchange() and swapExactTokensForTokens() returning the original tx's return values (e.g. 231461923843, 231447057390) to satisfy bot checks.
6. After operate returns, call WETH.transferFrom(mevBot, attacker, WETH.balanceOf(mevBot)) to drain all 1,101 WETH.
**How found:** Investigated the bot's profitable arbitrage tx, noticed all logic routed via delegatecall to unverified 0xDd6B; read storage slots to find owner and dYdX SoloMargin as authorized callers; decompiled to find callFunction callback; traced successful past callFunction txs to see encoded call data, hypothesizing no address/signature validation existed.
**Exploitation:** Attacker triggers dYdX SoloMargin.operate with a Call action targeting the MEV bot, passing crafted data that redirects the bot's hardcoded external calls to the attacker contract. The bot auto-approves the caller for its full WETH balance; attacker-supplied functions return spoofed values so the bot's sanity checks pass, then attacker pulls all WETH via transferFrom.
**Insight:** Unverified MEV bot contracts that whitelist flash-loan protocols as callers can be reached permissionlessly through those protocols' callbacks; decompile the implementation, replay a known successful callback's data field, then swap encoded target addresses for your own contract and spoof return values to pass sanity checks.
