TraceFast blog

Anatomy of a Sandwich: Reconstructing a Single MEV Attack Block-by-Block

On October 9, 2023, the Ethereum Foundation sold 1,700 ETH on Uniswap — and got sandwiched. We reconstruct the entire attack, transaction by transaction, using TraceFast.

On October 9, 2023, the Ethereum Foundation — the organization that stewards the protocol itself — swapped 1,700 ETH for USDC on Uniswap. A sandwich bot was waiting. Three transactions, one block, and about $9,100 quietly moved from the Foundation’s execution price into a searcher’s pocket.

This post reconstructs that attack end to end using TraceFast. Every link below opens the actual on-chain data, so you can follow along and check every claim yourself.

Sandwich attacks in four sentences

A sandwich attack targets a pending swap that the attacker can see coming. The attacker buys the same asset immediately before the victim’s trade (pushing the price up), lets the victim buy at the worse price, then sells immediately after (pocketing the difference). The victim’s own slippage tolerance is what makes this possible — the attacker sizes the front-run so the victim’s trade still executes, just at the worst price the victim agreed to accept. That’s the theory; everything from here on is one concrete, real attack.

Step 1 — Three transactions, one block

Open block 18,311,676 on TraceFast. It looks unremarkable at first: 155 transactions, 73% gas utilization, built by Titan Builder (0x4838…5f97). One stat stands out on the block page — 1,736 ETH moved, above the recent p95. Nearly all of that is one trade.

TraceFast block 18,311,676 overview: 1,736 ETH moved — above recent p95, built by Titan Builder

Now look at the top of the transaction list. The first three slots in the block are:

PositionTxFromToWhat it is
00x031763…5cd5b50xfac9…da00MEV bot 0x0000…6b40Front-run
10x198f7f…7aca3dEthereum Foundation 0x9ee4…313dUniswap Universal RouterVictim
20xefc259…e2d93d0xfac9…da00MEV bot 0x0000…6b40Back-run

Same sender wrapped around the victim, same bot contract on both sides, positions 0-1-2. This is the canonical sandwich shape, and once you know to look for it, it’s unmistakable.

Transactions tab of block 18,311,676: the sandwich at positions 0–2 — MEV bot, the Ethereum Foundation's 1,700 ETH swap, MEV bot again

Step 2 — The front-run (position 0)

Open the front-run transaction. A few things worth reading off the page:

Zero ETH value, 15 token transfers. The transaction sends no ETH itself — all the action happens inside the bot contract. TraceFast flags it as storage-heavy: 1,058,480 gas consumed, over a million gas of state manipulation packed into slot 0 of the block.

The capital was borrowed — and the position was parked. Decode the transfer list and an elegant structure appears. The bot contributed just 243.83 WETH of its own inventory, then flash-borrowed 7,300 WETH from Balancer, deposited it into Aave as collateral, borrowed 1,632.42 WETH against it, and swapped that into 2,640,314.64 USDC in the Uniswap v3 USDC/WETH 0.05% pool — the front-run itself. Here’s the clever part: a flash loan must be repaid within the same transaction, but the sandwich position has to survive across the victim’s transaction. So the searcher parked the USDC in Aave as collateral (leaving the WETH debt open), withdrew enough WETH to repay Balancer, and exited the transaction holding the short-ETH position inside a lending protocol. This is why a “simple” front-run needs 15 token transfers.

Gas tells a story, but not the one it used to. The front-run paid 9.1 gwei against a block base fee of 8.1 gwei — a priority fee of just 1 gwei. Pre-Merge, sandwich bots fought for position with gas-price ladders, outbidding each other in the public mempool. In the MEV-Boost era, position is bought privately: the searcher submits the bundle to a builder and pays for ordering out of profits. The gas price is almost vestigial. Keep this in mind for the back-run below, where the real payment shows up.

The effect of the front-run: the attacker’s buy pushed the ETH/USDC price in the pool up by roughly 46 basis points (per EigenPhi) — small enough to stay inside the victim’s slippage tolerance, large enough to matter on a $3M trade.

Front-run transaction, Token Transfers tab: the 7,300 WETH Balancer flash loan and the Aave/Uniswap legs — 15 transfers, zero ETH value

Step 3 — The victim (position 1)

The victim transaction is the Ethereum Foundation’s treasury sale: 1,700 ETH sent to the Uniswap Universal Router, executed via the standard execute method, returning exactly 2,738,345.58 USDC.

The transfer list shows the router split the order across three routes: 1,445 WETH through the USDC/WETH 0.05% pool (0x88e6…5640), 170 WETH through the 0.3% pool, and 85 WETH via a WBTC hop. Note which route the attacker chose: the front-run hit only the 0.05% pool — the leg carrying 85% of the order. Sandwich bots don’t attack transactions, they attack pool legs, and they size their capital to the leg that matters.

The USDC/WETH 0.05% pool page on TraceFast: Uniswap v3, factory-event provenance, ~$19M daily volume — the leg that carried 85% of the Foundation's order

Nothing about this transaction was careless in an obvious way. It paid a normal gas price (8.1 gwei — exactly base fee), used the canonical router, and executed successfully. Its only sin was being visible: the swap sat in the public mempool where every sandwich bot on the network could see a $3M market order coming. For a searcher, a pending seven-figure swap with default-ish slippage settings is not an opportunity — it’s an invoice.

Victim transaction, Token Transfers tab: all nine legs of the split route and the final 2,738,345.58 USDC transfer from the Universal Router to the Foundation

Step 4 — The back-run (position 2)

The back-run closes the loop with the mirror image of the front-run: flash-borrow 7,300 WETH from Balancer again, unlock the parked position in Aave, pull the 2,640,314.64 USDC back out, and swap it into 1,638.04 WETH through the same 0.05% pool — at the better price the victim’s trade just created. Repay the 1,632.42 WETH debt, repay Balancer, and the bot walks away with 249.45 WETH against the 243.83 WETH it started with.

Gross profit: exactly 5.6159 WETH (~$9,100). No estimates — that’s the difference between the WETH that left the bot in transaction 0 and the WETH that returned in transaction 2.

One more number on this page matters: the transaction carries 3.0944 ETH of value into the bot contract — and the bot’s ETH balance is zero both before and after the block, so that ETH left within the same transaction. Reconstruct Titan Builder’s ledger for the block and the destination is clear: Titan collected ≈3.33 ETH in direct payments on top of just 0.036 ETH in priority fees, and this transfer accounts for 93% of it. That’s 3.0944 / 5.6159 = 55.1% of gross revenue paid to the builder — the price of positions 0 and 2. This is the modern gas ladder: the bribe doesn’t show up in the gas price; it shows up as a direct transfer to the block builder.

Net result for the searcher: ~$4,060 after the builder’s cut and gas. More than half the extracted value went to the builder — a detail that says a lot about where bargaining power sits in today’s MEV supply chain.

Step 5 — Who was behind it?

TraceFast’s address pages turn a one-off observation into a profile.

The bot contract 0x0000…6b40 is auto-labeled MEV Bot, and its stats justify the label: 452,596 transactions, delegatecall and factory-pattern risk flags, and — remarkably — it was still active as of July 2026, nearly three years after this attack. The leading-zeros vanity address (0x00000000003b…) is itself a tell: cheaper calldata when the address appears in payloads, a common micro-optimization among high-volume searchers.

The operator EOA 0xfac9…da00 has been running since August 2022, has sent 11,977 transactions, deployed 35 contracts, and burned 186 ETH in gas fees over its lifetime. An account that spends six figures on gas is not a hobbyist — it’s infrastructure. Sandwiching the Ethereum Foundation wasn’t a special operation for this operator; it was Tuesday.

Address profile of the MEV bot 0x0000…6b40: auto-labeled MEV Bot, 452,596 transactions

Step 6 — The victim’s P&L

Let’s put the Foundation’s side of the ledger together:

  • Sold: 1,700 ETH
  • Received: 2,738,345.58 USDC
  • Execution shortfall: ~$9,100 — the attacker’s gross revenue is, almost by definition, the victim’s missed price. On a ~$3.08M trade, that’s roughly a 0.3% invisible tax.

The transaction “succeeded.” No error, no revert, nothing on the receipt hints anything went wrong. That’s what makes sandwich MEV insidious: the cost is invisible unless you reconstruct the counterfactual — what the pool would have paid without the front-run sitting in front of you. That reconstruction is exactly what the block-level view makes possible.

Could this have been avoided?

Three practical takeaways, in increasing order of effort:

  1. Use private order flow for size. A swap submitted through a private RPC (MEV-protected relays, direct-to-builder flow) never touches the public mempool, so there is nothing to front-run. For a $3M treasury operation, this is table stakes — and the fact that the Foundation’s swap was public is the most surprising detail of the whole story.
  2. Cut the trade into tranches. Ten swaps of 170 ETH each move the pool far less per trade and shrink the sandwich margin, often below the attacker’s break-even (builder cut + gas + flash-loan fees).
  3. Set slippage deliberately. Sandwich profit is bounded by your slippage tolerance. Tight tolerance on large trades means an attack either becomes unprofitable or your transaction reverts — and a revert is annoying, but $9,100 cheaper than this one.

How to spot a sandwich in any block

Once you’ve dissected one attack, the pattern generalizes into a checklist you can run on any block in about a minute:

  1. Same sender at symmetric positions. One EOA appearing at positions k and k+2 (or wrapping a small cluster of swaps) is the strongest single signal.
  2. A large swap in between. The victim is almost always the biggest trade in the pool for that block — sandwiching small trades doesn’t clear the builder’s cut.
  3. Zero-value, storage-heavy transactions on both sides. Bot contracts hold the logic internally; the wrapper transactions carry no ETH and burn six-figure gas.
  4. Mirrored token flows. The front-run buys exactly what the victim is about to buy; the back-run sells it. Compare the transfer lists on both sides — they’re near-inverses of each other.
  5. A payment to the builder. Look for a direct ETH transfer to the block’s fee recipient inside one of the bot transactions. No bribe, no slot 0.

None of these requires special access — just a block view that shows transaction ordering, token flows, and state changes side by side.

Reproduce this analysis yourself

Everything in this post came from public data. Open block 18,311,676, find the three transactions at the top, and walk the same path: block → transactions → addresses. Then try it on a block from today — sandwich structure hasn’t changed, only the pools and the operators have. The DeFi pools view and gas analytics are good places to spot where the action currently is.

Next in the series: who actually builds Ethereum’s blocks — and why more than half of this attacker’s profit went to the builder.


Sources