On 20 June 2026, the JaredFromSubway MEV bot lost 4,424 ETH (~$7.5M) due to an approval hijacking flaw. The attacker deployed fake arbitrage pools and bait tokens that appeared to offer profitable trading opportunities, causing the bot’s automated strategy to interact with malicious contracts and grant token approvals.
The core issue was that these approvals were not fully consumed or revoked after execution. As a result, the attacker was able to activate the bait contracts and use the remaining allowances to drain the bot’s WETH, USDC, and USDT reserves.Background
Background
Jaredfromsubway.eth is a MEV (Maximal Extractable Value) bot, meaning an automated program that monitors pending transactions on the blockchain and reorders their execution to capture a profit. Its specialty is the sandwich attack, which consists of front-running and back-running a user's transaction with two of the bot's own orders to profit from the price difference.
When a user submits a swap on a decentralized exchange, the transaction may become visible before it is included on-chain. MEV bots monitor this flow, simulate the impact of pending trades on liquidity pools, and identify opportunities where a user’s transaction is likely to move the price of an asset.
Key Addresses
Address
Label
0x3e37f4A10d771Ba9dE44b6d301410b1BEdeA65d0
Exploiter, main message sender
0x74Dc5b93586D248D5Aec64b3586736FF0A0D0e65
Exploiter
0x71d4416A7A85e08a5Fe7227Ca3B44Fc639e94e97
Exploiter
0xd8C125efCBc99408eC8723E9BBd81d1E8D39D845
Exploiter
0xe3Da36E4bd1a5738fa5D6Ef4F0e4dF40bDeB5f17
Exploiter
0x139bE50D7c0829E0db6E9A444454517e24AbeE7a
Exploiter
0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1
Exploiter, frontrunning markStatusAndTip() caller
0x19Ff2017803a832eE968454848DAb48fF39C881A
Exploiter
0x7B4F24a4522bc2AEE9D1686FFB7d6c9dAC514e20
Exploiter
0x81f248ff583d3f8592ea0354a7b8dbe66de40091
helper contract for deploying fake tokens
0xEEE172A069f5171b407eBf47e8FCFB637E944ec2
helper contract for managing fake dex
0xFeFA329dA857DaF61450E009631c203de312b880
Caps (example fake token)
0x76ec37bfBeC2C3c6Bc7c9475fB5F37174Df1faCc
fCap (example fake wrapped token)
0x68ca6A0c6db92bf2D4424C7c9fba8655992187c6
“fWETH”, fake WETH derivative, example approval bait
0x4EE0B6e9f9C4886bEeef2ebD7fC27223169531CE
“fWETH”, fake WETH derivative, example approval bait
0xC12AE43FEfF0e35ad59Dd8D31D51D2c19DF576C4
SwapV2Pair, example set-up pool
0x0e97bf999521e019d652e61ee6512d93bd29fa41
SwapV2Pair, example set-up pool
0x4dE8C729A064Ff6087Cc84A4152969349e4FEb98
helper contract to conduct swap on set-up pools
0xae2Fc483527B8EF99EB5D9B44875F005ba1FaE13
jaredfromsubway.eth
0x1f2F10D1C40777AE1Da742455c65828FF36Df387
jaredfromsubway MEV Bot, main victim
Attack Flow
Preparation:
So to entice MEV bots, one would need set-up imbalanced pools with some real assets in it
Attacker deployed several helper contracts that is used to set up such traps:
0x81f248ff583d3f8592ea0354a7b8dbe66de40091 for deploying fake tokens
0xb84db016324e8F2BFdD8DD9c260338AEE0A8DF52 for coordinating token status and profit extraction
0xEEE172A069f5171b407eBf47e8FCFB637E944ec2 for creating fake pools
0x4dE8C729A064Ff6087Cc84A4152969349e4FEb98 for conducting swaps
Deploying 131 fake token contracts as bait through method 0x9045f3f9() (txn (opens in a new tab))
These bait contracts appear in the form of restaked WETH/USDC tokens.
That you get exactly 1 such token for 1 WETH/USDC wrapTo() it, the wrapTo() method requires approvals to call but is binded by the coordinate contract.
i) When ‘owner_a_0_19’ is not set up, wrapTo() called _safeTransferFrom() and the allowance was consumed.
ii) After ‘owner_a_0_19’ is set up (to coordinator contract), getStatus() returns _getStatus == block.number.
iii) If _getStatus is not up to blocknumber, then setStor3 is called to remind attacker that _getStatus should be reset.
iv) If _getStatus is up to blocknumber and status == 1, wrapTo() skipped transferFrom — the allowance was not consumed; the amount is also updated in the coordinator to keep track of newly acquired allowances.
At block 25354425 (txn (opens in a new tab)), jaredfromsubway.eth took the bait in its first interaction with SwapV2Pair_0x0e97. When assuming 1 fWETH = 1 WETH, the token balances on the two fake SwapV2Pairs present an arbitrage opportunity in swap route fWETH->fCAP->WETH:
SwapV2Pair_0x0e97: 0.1 fWETH, 0.1 fCAP
SwapV2Pair_0xc12a: 0.086034434021378528 fCAP, 0.116281374898538093 WETH
The MEV bot approved and wrapped 7,391,033,126,027,264 WETH to the bait, which in turn minted the same amount to SwapV2Pair_0x0e97.
It then swapped out 6,863,125,844,328,448 wei fCAP for 8,566,811,964,473,344 wei WETH.
The MEV bot netted 0.002351557676892158 WETH; the approval is properly spent normally as status coordinator ‘owner_a_0_19’ hasn’t been set.
Wait patiently for nearly a day, as MEV builds trust for the setup.
Attacker set up (txn (opens in a new tab)) the ‘owner_a_0_19’ for the bait tokens to coordinator.
Starting from block 25360428, the attacker calls markStatusAndTip() (txn (opens in a new tab)) with some bribe to frontrun Jared and set ‘_getStatus’ to block.number.
The ensuing wrapTo() (txn (opens in a new tab)) during MEV arbitrage would not cost the allowance.
Wait for the MEV to conduct more swaps to accumulate unrevoked approvals. It didn’t take long as it seems MEV fully trusts the set-up now and grews greedy by conducting hundreds of swaps per txn, In fact the attacker only conducted a dozen ‘_getStatus’ updates / 0xb6e808af() to get the allowance it needed.
Then at blockheight 25360696, activate 66 approval bait contracts (txn (opens in a new tab)), 60 of which have approval of the target MEV Bot, and transfer funds to the attacker.
Vulnerability
The arbitrage bot approves wrapper contracts to spend its tokens for wrapTo() operations, assuming the allowance is fully consumed. However, the bot never verifies this consumption or revokes unspent allowances. If a wrapper avoids calling transferFrom, this lingering approval creates a persistent vulnerability, allowing it to drain the bot's funds.
Fund Flow
The attacker 0x3e37f4A10d771Ba9dE44b6d301410b1BEdeA65d0 was able to drained 2,869,812.43 USDC, 2,032,769.62 USDT, and 1,474 wETH ($2,567,708) then swapped (opens in a new tab) all the stablecoins for ETH.
The funds were then sent to these 5 addresses:
0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1
0x71d4416A7A85e08a5Fe7227Ca3B44Fc639e94e97
0x74Dc5b93586D248D5Aec64b3586736FF0A0D0e65
0xe3Da36E4bd1a5738fa5D6Ef4F0e4dF40bDeB5f17
0xd8C125efCBc99408eC8723E9BBd81d1E8D39D845
Finally, the attacker deposited (opens in a new tab)3,000 ETH into Tornado Cash and swapped 1,422 ETH for ~$2.44M in DAI, which is still in wallet 0x7B4F24a4522bc2AEE9D1686FFB7d6c9dAC514e20.