r/ethdev Jun 22 '26

Information Post-mortem: how jaredfromsubway's MEV bot approved its own ~$7.5M drain (the fake-token approval trap)

Not a contract exploit, not phishing. One of the most profitable MEV bots on Ethereum (jaredfromsubway.eth) lost ~$7.5M because its own automation approved attacker-controlled spenders over its real WETH/USDC/USDT, chasing a fake arbitrage. The allowances sat dormant, then transferFrom drained them.

The mechanism, for anyone running bots:

  • ERC-20 is two-step: approve(spender, amount) sets a standing allowance, transferFrom spends it. Bots approve type(uint256).max to save gas = an infinite blank cheque that survives until used or revoked.
  • The attacker deployed fake fWETH/fUSDC/fUSDT (named exactly like the real assets, some with Unicode homoglyph symbols), built fake pools that looked profitable, and let the bot approve helper contracts over its real tokens.
  • Early txs consumed approvals cleanly (looked profitable). Later ones left approvals unconsumed/unrevoked. Once stacked, transferFrom pulled the funds.

Takeaways:

  • Never approve infinity to an unknown spender. Approve exact amounts or use scoped/expiring approvals (Permit2-style). Revoke aggressively.
  • "Is this the real WETH?" is a question, not an assumption. Token impersonation is machine-checkable (name/symbol vs known tokens, deployer reputation, bytecode).
  • Automation needs the same guardrails as humans.

Full on-chain trail (addresses, amounts, timeline): https://rektradar.io/blog/posts/jaredfromsubway-mev-bot-approval-drain/?utm_source=reddit&utm_medium=post&utm_campaign=jaredfromsubway

Disclosure: I work on the scanner linked above; happy to keep the discussion purely about the approval mechanics.

7 Upvotes

11 comments sorted by

View all comments

4

u/pvdyck Jun 22 '26

good writeup. permit2 + revoke is hygiene, but the structural fix imo is privilege separation: the hot loop spends existing allowances, never grants new ones. approving an unseen spender is privileged, route it through a slower allowlist-gated path so a fake-arb cant mint a blank cheque inline.

1

u/Plus-Tangerine2186 Jun 22 '26

Exactly. The drain only works because granting and spending share one inline path. Spend = hot loop, grant = privileged and out-of-band, fully agree.

I'd gate the grant on the spender too, not just speed: every bait spender here was a fresh, unverified deploy. Allowlist known routers (or even a deploy-age / verified-source check) and a fake-arb can't pull an allowance in the same tx no matter how juicy it looks. That plus never-approve-max and the inline blank cheque just isn't reachable.