What Is a Sandwich Attack? How to Avoid Getting Sandwiched
If you've ever swapped on Uniswap and received noticeably less than the quote, even though the market didn't move, there's a decent chance you got sandwiched. It happens every day on Ethereum, it's legal in the sense that nobody broke into anything, and it's almost entirely avoidable once you know how it works.
I'm going to show you the mechanics with actual numbers, because once you see the math, the defences are obvious.
The mechanics in one paragraph
You send a swap to the public mempool. A bot sees it before it's included in a block. It sends a buy of the same token just before your swap, which pushes the price up. Your swap executes at that worse price. Then the bot sells right after your swap, at the higher price your own buy created. Three transactions, in that exact order, in the same block: the bot's buy, your swap, the bot's sell. Your trade is the meat in the sandwich.
The bot makes sure it lands in that order by sending the front-run and back-run as a bundle to block builders, with your public transaction in the middle.
A worked example
Let's use a simple Uniswap V2-style pool with the standard 0.3% fee, and round numbers. These are illustrative, not from a real trade.
- The pool holds 100 ETH and 300,000 USDC, so ETH is about $3,000.
- You want to swap 30,000 USDC for ETH. That's a big trade for this pool.
- Without anyone interfering, you'd get about 9.066 ETH. (Less than 10, because your own trade moves the price. That's normal price impact, not MEV.)
- You set 3% slippage, so your minimum is about 8.794 ETH.
Now the bot calculates the biggest front-run it can do without pushing you below your minimum. In this pool that's about 4,830 USDC. It buys first, you buy at the worse price and get exactly your minimum, 8.794 ETH, then the bot sells its ETH back.
- You lose about 0.272 ETH compared to the clean trade, roughly $800.
- The bot ends up with about $950 before gas and before whatever it pays the builder.
Same pool, same trade, but with a tighter slippage setting:
- 1% slippage: the bot can only front-run about 1,590 USDC, and it makes about $320 gross. You lose about 0.09 ETH.
- 0.5% slippage: about 790 USDC front-run, around $160 gross profit. You lose about 0.045 ETH.
See the pattern? Your slippage tolerance is the attacker's budget. The bot doesn't take a random amount, it takes everything up to your limit. Once gas and the builder payment get bigger than the gross profit, it doesn't bother.
Why it happens to you specifically
Not every swap gets sandwiched. Bots go after the ones where the profit is worth it:
- Loose slippage. The 5%, 10% or "auto with a high cap" settings people use for volatile tokens.
- Big trades relative to the pool. A $30,000 swap barely moves a deep ETH/USDC pool, but it moves a small token pool a lot.
- Public mempool. The bot can only attack what it can see.
- Low-liquidity tokens. Small pools mean bigger price impact per dollar, which means more to extract.
How to avoid getting sandwiched
1. Use a private RPC
This is the biggest one. If your transaction never shows up in the public mempool, a sandwich bot can't see it in time. You just change the RPC URL in your wallet.
- Flashbots Protect sends your transaction to a private mempool, only includes it if it doesn't revert, and can give you refunds if your transaction creates MEV.
- MEV Blocker, built by CoW Protocol, Agnostic Relay and Beaver Build, sends your transaction to builders and lets bots backrun it (which doesn't hurt you), paying you a rebate from their bids.
They're not identical. I compare them in detail in Flashbots Protect vs MEV Blocker.
2. Tighten your slippage
The example above says it all. For deep pairs, 0.5% or lower is usually fine. For tokens with taxes, you need a higher slippage just to cover the tax, which is exactly why those trades are juicy targets. In that case, definitely use a private RPC too.
Don't turn off slippage protection just because you use a private RPC. MEV Blocker's own FAQ says there's no 100% protection, and a small share of transactions can end up public anyway, for example after a reorg. Slippage is your last line of defence.
3. Use an intent-based DEX
CoW Swap works differently from a normal swap. You sign an order off-chain, and solvers compete in an auction to fill it, settling on-chain on your behalf. There's no swap transaction from you sitting in the mempool for a bot to wrap. Other aggregators have intent-based modes too.
4. Split big trades
If your trade is huge compared to the pool, split it into several smaller ones, or use an aggregator that routes it across multiple pools. Less price impact per trade means less room for a sandwich.
5. Avoid thin pools when you can
If the same token trades in a deep pool and a thin one, use the deep one. The aggregator usually does this for you, but check the route on big swaps.
How to check if you were sandwiched
Open your swap transaction on Etherscan, then open the block it's in and look at the transactions right before and right after yours.
The pattern to look for:
- The transaction right before yours is a buy of the same token in the same pool, from an address (often a contract) you don't know.
- The transaction right after yours is a sell of that token by the same address or contract.
- Your transaction received close to your minimum output.
If you see that, you were sandwiched. Tools like EigenPhi also label sandwiches if you'd rather not check manually.
What about the bots: is sandwiching even profitable?
From the bot's side it's harder than it looks. The two trades are separate transactions around yours, so the strategy isn't atomic in the usual sense, and the bot has to hold the token for a moment. Bots have been burned by tokens designed to punish them. The ethereum.org MEV page mentions "salmonella" tokens built specifically for that. And many bots compete for the same victims, so most of the profit gets bid away to the builder.
I don't recommend building sandwich bots. Arbitrage and backruns that don't hurt the user are a better business. I explain the alternatives in how to build a profitable MEV arbitrage bot.
Summary
- A sandwich is a buy before your trade and a sell after it, in the same block.
- The attacker takes up to your slippage tolerance, so loose slippage means more loss.
- A private RPC stops most of them. Tight slippage limits the rest.
- Intent-based swaps like CoW Swap avoid the problem by design.
- Check the transactions around yours to see if it happened.
If you trade new tokens a lot, where high slippage is unavoidable, that's one more reason to use bundles instead of public transactions. The MEVDAO Sniper Bot sends buys as Flashbots bundles, so when Flashbots is available they never sit in the public mempool. It's included in the MEVDAO subscription with a 3-day free trial.
Questions? Message me on Telegram, or join the MEV Secrets email list below.