ethereum/mev-protection

MEV Protection and Flashbots Guide

ethereumguide👥 Communityconfidence highhealth -2%
v1.0.0·Updated 3/20/2026

MEV Types Quick Reference

TypeMechanismVictimScale
Sandwich AttackInsert transactions before and after target swap to capture price differenceDEX usersMost common
FrontrunningCopy target transaction with higher gas to execute firstNFT minters, arbitrageurs
BackrunningExecute after target transaction to capture price impactNo direct victim (arbitrage)
Liquidation MEVRace to trigger liquidations for rewardsLiquidated users

User-Side Protection

1. Use Private RPC (Simplest)

# Flashbots Protect RPC (Mainnet, free)
https://rpc.flashbots.net

# MEV Blocker (aggregated protection)
https://rpc.mevblocker.io

# Metamask setup: Settings → Networks → Ethereum Mainnet → Replace RPC URL

Private RPCs send transactions directly to validators, bypassing the public mempool so bots cannot monitor them.

2. Set Reasonable Slippage

- Mainstream tokens (ETH/USDC): 0.1% - 0.5%
- Medium liquidity: 0.5% - 1%
- Don't exceed 1% (unless liquidity is extremely poor)
- Don't use "auto" (Uniswap defaults to 0.5%, but increases during market volatility)

Contract-Side Protection

1. Commit-Reveal (Prevent NFT Mint Frontrunning)

// Phase 1: Submit hash (without revealing content)
mapping(address => bytes32) public commits;
function commit(bytes32 hash) external {
  commits[msg.sender] = hash;
}

// Phase 2: Reveal (verify hash matches)
function reveal(uint256 choice, bytes32 salt) external {
  require(commits[msg.sender] == keccak256(abi.encode(choice, salt, msg.sender)));
  // Execute operation
}

2. Minimize Slippage Window (AMM Integration)

// ❌ Unprotected: allows arbitrary price slippage
router.exactInputSingle({..., amountOutMinimum: 0});

// ✅ On-chain TWAP verification (prevent large deviations)
uint256 twapPrice = getTWAP(pool, 30 minutes);
uint256 minOut = twapPrice * amountIn * 99 / 100;  // Allow 1% deviation
router.exactInputSingle({..., amountOutMinimum: minOut});

3. Use Flashbots Bundles (Contract Interaction)

import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle"

const flashbotsProvider = await FlashbotsBundleProvider.create(
  provider,
  authSigner,  // Random signer for authentication
  'https://relay.flashbots.net'
)

const bundle = [
  { transaction: tx1, signer: wallet },
  { transaction: tx2, signer: wallet },
]

const targetBlock = await provider.getBlockNumber() + 1
const response = await flashbotsProvider.sendBundle(bundle, targetBlock)

Bundle characteristics:

  • Atomicity: all succeed or all fail
  • Does not enter public mempool
  • Gas only paid on success

4. Price Protection (Protocol Layer)

// Limit single transaction impact
uint256 constant MAX_PRICE_IMPACT = 500; // 5%

function swap(uint amountIn) external {
  uint priceBefore = getPrice();
  _executeSwap(amountIn);
  uint priceAfter = getPrice();
  
  uint impact = (priceBefore - priceAfter) * 10000 / priceBefore;
  require(impact <= MAX_PRICE_IMPACT, "Price impact too high");
}

MEV Monitoring Tools

  • EigenPhi (eigenphi.io) — MEV visualization and analysis
  • Flashbots Explorer (explorer.flashbots.net) — Bundle history
  • mev-inspect-py — Self-hosted MEV analysis
  • libmev — Real-time MEV data API