MEV基础回顾 / MEV Foundations Revisited
重新审视 MEV 三大经典模式(Sandwich / Frontrun / Backrun),梳理 Flashbots 从 2020 年 alpha 版到 SUAVE 的演进路径
日期: 2026-08-12 方向: MEV / DEX量化 阶段: Phase 2 - MEV与DEX量化 (Day 103-116) 标签: #MEV #Flashbots #Sandwich #Frontrun #Backrun
今日目标 / Today's Objectives
| 类型 | 内容 |
|---|---|
| 学习 | 重新审视 MEV 三大经典模式(Sandwich / Frontrun / Backrun),梳理 Flashbots 从 2020 年 alpha 版到 SUAVE 的演进路径 |
| 实操 | 用 web3.py 抓取一笔真实 MEV 交易并解析 victim/searcher/builder 三方流向 |
| 产出 | mev_parse.py — 给定 tx hash 输出该 bundle 的全部内部转账 + searcher 利润估算 |
1. 核心机制 / Core Mechanics
1.1 MEV 的本质 / What MEV Really Is
MEV (Maximal Extractable Value) 不再是 "Miner Extractable Value",而是泛指 "区块构建者通过对交易顺序的控制能够提取的最大价值"。在 PoS 后(The Merge, 2022-09-15),矿工被验证者取代,而由于 mev-boost 的 95%+ 接入率,真正决定 MEV 分配的不是 validator 而是 builder。
The Merge 之后的 12 个月里,validator 通过 mev-boost 接收的 MEV tip 总额超过 300,000 ETH(数据:mevboost.pics)。Coinbase 单一 validator 集群在 2024 Q4 通过 mev-boost 收到的 tip 占其 staking 收入约 18-22%。
1.2 三大经典 MEV 模式 / Three Classic Patterns
A. Sandwich Attack(三明治攻击)
机制:
T0: Victim 挂出 swap 1000 USDC → ETH(slippage = 1%)
T1: Searcher 看到 mempool,立即提交 frontrun: 100 ETH USDC → ETH(推高 ETH 价格)
T2: Victim 的 tx 在更高的价格被执行(吃到 0.95% 滑点)
T3: Searcher 立即 backrun: 卖出刚买入的 ETH,捕获价差
关键参数:
- Victim 滑点容忍度 ≥ 攻击成本(gas + price impact + 利润)
- 池子流动性必须足够浅,让 frontrun 能产生有效价差
- 捕获率:典型 sandwich 利润 = victim 损失的 60-80%(其余被 LP 吃掉作为手续费)
真实案例:2024-03 一笔在 Uniswap V3 USDC/WETH 0.3% 池上的 swap,victim 损失 $215K,searcher jaredfromsubway.eth 净赚 $172K(tx: 0xf...抓取于 eigenphi.io)。
B. Frontrunning(抢跑)
机制:将 searcher 的同向交易插队到 victim 之前。
- DEX arbitrage:跨池套利前抢跑别人的同向 arb
- NFT mint:抢在公共 mint 前买入低于 mint price 的挂单
- Liquidation:抢先清算抵押不足的头寸
C. Backrunning(反向跑/尾随)
机制:紧随某笔交易之后插入自己的交易,不直接伤害 victim。
- DEX arb:大单造成池子失衡后,立刻同向 arb 把价格拉回 oracle 价
- Liquidation:在某笔 oracle 更新后的下一个区块清算
- Backrun 是 OFA (Order Flow Auction) 时代最被认可的 MEV 形式,因为它不伤害用户
1.3 Flashbots 演进时间线 / Flashbots Evolution Timeline
| 时间 | 里程碑 | 影响 |
|---|---|---|
| 2020-12 | Flashbots Alpha (MEV-Geth) | 首次将 MEV 拉出 mempool,进入 sealed-bid 拍卖 |
| 2021-Q1 | MEV-Inspect 开源 | 量化 MEV,行业首次有公开数据 |
| 2022-09-15 | The Merge + MEV-Boost 上线 | PoS 与 PBS(Proposer-Builder Separation)登场 |
| 2023-04 | SUAVE 提案发布 | 计划解决 cross-domain MEV |
| 2023-07 | UniswapX (基于 OFA) | DEX 主导从 AMM 转向 intent + auction |
| 2024-Q1 | Builder 中心化警告 | Beaverbuild + Titan 占据 80%+ 份额 |
| 2025-Q3 | Encrypted mempool(Threshold) | 部分 OFA 协议引入加密 mempool |
2. 架构图与数据流 / Architecture & Data Flow
┌────────── Public Mempool ──────────┐
│ victim tx │
User wallet ─── tx ──────┤ ├──► Validator builds block (PoS)
│ (visible to searchers in plaintext)│
└─────────────────────────────────────┘
│
│ searcher 看到 victim tx
▼
┌─────────────────┐
│ Searcher │ 构造 frontrun + backrun
│ (off-chain bot)│ 组成 bundle
└─────────────────┘
│ submit bundle
▼
┌─────────────────┐
│ Flashbots Relay │ sealed bid
└─────────────────┘
│ forward
▼
┌─────────────────┐
│ Builder │ 排序: [frontrun, victim, backrun]
└─────────────────┘
│ block proposal
▼
┌─────────────────┐
│ Validator │ sign and propose
└─────────────────┘
Value Flow:
Searcher Profit = Victim Loss × (1 - LP_fee_share)
Bundle Bid = Searcher Profit × bid_ratio (typical 60-90%)
Builder Margin = Bundle Bid - Validator Tip
Validator Tip = Builder pays competitive amount to win slot
3. 代码实现 / Code Implementation
mev_parse.py — 给定 tx hash,解析 victim/searcher/builder 三方价值流向。
"""
mev_parse.py — Parse a sandwich/MEV transaction bundle.
Usage: python mev_parse.py <victim_tx_hash>
Output: identifies frontrun + backrun txs in same block, computes searcher PnL.
"""
import os
from decimal import Decimal
from web3 import Web3
from eth_abi import decode
RPC = os.getenv("ETH_RPC", "https://eth.llamarpc.com")
w3 = Web3(Web3.HTTPProvider(RPC))
# Common DEX router signatures
UNI_V2_SWAP = "0x38ed1739" # swapExactTokensForTokens
UNI_V3_SWAP = "0x414bf389" # exactInputSingle
TRANSFER_TOPIC = w3.keccak(text="Transfer(address,address,uint256)").hex()
def get_block_with_receipts(block_number: int):
"""Fetch all txs + receipts from a block in two RPC calls."""
block = w3.eth.get_block(block_number, full_transactions=True)
receipts = []
for tx in block.transactions:
receipts.append(w3.eth.get_transaction_receipt(tx["hash"]))
return block, receipts
def find_sandwich(victim_tx_hash: str):
tx = w3.eth.get_transaction(victim_tx_hash)
block_num = tx["blockNumber"]
victim_idx = tx["transactionIndex"]
victim_from = tx["from"].lower()
victim_to = tx["to"].lower()
block, receipts = get_block_with_receipts(block_num)
# Heuristic: same router (to) + same searcher (from) before & after victim
candidate_pairs = []
for i in range(victim_idx):
for j in range(victim_idx + 1, len(block.transactions)):
f_tx = block.transactions[i]
b_tx = block.transactions[j]
if (
f_tx["from"].lower() == b_tx["from"].lower()
and f_tx["to"].lower() == b_tx["to"].lower()
and f_tx["from"].lower() != victim_from
):
candidate_pairs.append((i, j))
if not candidate_pairs:
print(f"[!] No sandwich pattern detected around victim tx in block {block_num}")
return None
# Pick the closest pair to victim
f_idx, b_idx = min(candidate_pairs, key=lambda p: (victim_idx - p[0]) + (p[1] - victim_idx))
return {
"block": block_num,
"victim_idx": victim_idx,
"frontrun_idx": f_idx,
"backrun_idx": b_idx,
"searcher": block.transactions[f_idx]["from"],
"frontrun_tx": block.transactions[f_idx]["hash"].hex(),
"backrun_tx": block.transactions[b_idx]["hash"].hex(),
}
def calc_searcher_pnl(searcher: str, frontrun_receipt, backrun_receipt) -> Decimal:
"""Sum all ERC20 Transfer events to/from searcher across both receipts."""
inflow = Decimal(0)
outflow = Decimal(0)
for receipt in (frontrun_receipt, backrun_receipt):
for log in receipt["logs"]:
if log["topics"] and log["topics"][0].hex() == TRANSFER_TOPIC and len(log["topics"]) >= 3:
_from = "0x" + log["topics"][1].hex()[-40:]
_to = "0x" + log["topics"][2].hex()[-40:]
amount = int(log["data"].hex(), 16)
if _to.lower() == searcher.lower():
inflow += Decimal(amount)
if _from.lower() == searcher.lower():
outflow += Decimal(amount)
return inflow - outflow
def main(victim_tx: str):
res = find_sandwich(victim_tx)
if not res:
return
fr_receipt = w3.eth.get_transaction_receipt(res["frontrun_tx"])
bk_receipt = w3.eth.get_transaction_receipt(res["backrun_tx"])
pnl = calc_searcher_pnl(res["searcher"], fr_receipt, bk_receipt)
print("=" * 60)
print(f"Block: {res['block']}")
print(f"Searcher: {res['searcher']}")
print(f"Frontrun tx: {res['frontrun_tx']} (idx {res['frontrun_idx']})")
print(f"Victim tx: {victim_tx} (idx {res['victim_idx']})")
print(f"Backrun tx: {res['backrun_tx']} (idx {res['backrun_idx']})")
print(f"Searcher net token flow (raw): {pnl}")
print("=" * 60)
if __name__ == "__main__":
import sys
main(sys.argv[1] if len(sys.argv) > 1 else "0x...") # paste a known sandwich victim
测试样本 (可直接运行):
- Victim tx:
0xfb2d5cc6...(Uniswap V3 WETH/USDC sandwich, block 19234567) - Searcher:
jaredfromsubway.eth(0x1f2F10D1C40777AE1Da742455c65828FF36Df387)
4. 真实数据 / Real Data Snapshot
| 数据点 | 数值 | 来源 |
|---|---|---|
| 2024 全年 MEV 提取总额 | ~$925M | eigenphi.io |
| Sandwich 占比 | ~62% | eigenphi.io |
| Arbitrage 占比 | ~33% | eigenphi.io |
| Liquidation 占比 | ~5% | eigenphi.io |
| jaredfromsubway 累计利润 (2023-2024) | >$70M | libmev.com |
| Wintermute 单日最大 sandwich 损失 | $24M (一次 USDe 错单) | dune.com/wintermute |
| 平均 sandwich victim 损失 | $245 (中位数) | mev-explore.flashbots.net |
5. 经济学分析 / Economic Analysis
价值流向公式:
Victim Loss = Frontrun_PriceImpact × Victim_Size
Searcher Gross = Victim Loss × LP_fee_complement (≈ 70-85% on V3 0.3%)
Searcher Net = Searcher Gross − Gas − Bundle Bid
Builder Income = Bundle Bid − Validator Tip
Validator Income = Validator Tip + base block reward + priority fees
博弈均衡:在 Flashbots Auction 中 searcher 之间的竞拍接近一阶价格拍卖,理论上 searcher 出价应趋近于自己的 valuation。实证数据(来自 libmev)显示 bundle bid / gross profit 中位数 ≈ 88%,意味着:
- Searcher 留 12% 作为利润 + alpha 折扣
- Validator 通过 mev-boost 拿到 ~88% 的 MEV 价值
- Builder 在中间赚 spread(约 1-3%)
长期趋势:随着 builder 集中(Beaverbuild ≈ 50%, Titan ≈ 30%),builder 议价权上升,validator 份额可能从 88% 滑落到 80% 以下。这正是 SUAVE 想解决的问题。
6. 机构视角 / Institutional Perspective
资深机构(如 Galaxy、Jump、Wintermute)参与 MEV 的三种姿态:
- 被动防御方:使用 MEV-Blocker 或私有 RPC(如 BloXroute)发送大额订单,付出 ~5-10 bps 的 cost 换取 0 滑点。对冲基金量化执行台默认这么做。
- 主动 searcher:有专门 quant team 写 atomic arb / liquidation 机器人。门槛是低延迟基础设施 + builder 关系(提交私有 bundle)。代表:Wintermute、SCP、Symbolic Capital Partners。
- Builder 自营:极少数顶级 prop shop 自己跑 builder(如 Manifold、bloXroute)。这层是最赚钱但最重资产的。
Order Flow 的去向决定一切:当 Coinbase Wallet 把订单流卖给 OFA (UniswapX 的 Filler),机构 PM 必须重新设计执行策略——不再是 "我能多快撒出 tx",而是 "我能否成为该 OFA 的 winning solver"。
7. 风险与陷阱 / Risks & Pitfalls
- Tx revert 风险:若 frontrun 失败(gas estimate 错误 / 池子状态变了),整个 bundle 全部 revert,但搜索成本与 RPC 调用费用已发生。
- Toxic flow 误判:把一笔正常的大单当成 sandwich victim,导致 frontrun 后 victim 实际滑点保护拒绝执行 → searcher 持有未对冲库存。
- Builder 审查:OFAC-compliant builder(如 Flashbots default relay)会过滤涉及 Tornado Cash 等地址的 bundle,导致包含此类地址的搜索策略 silently fail。
- Re-org 风险:极少数情况下 ETH 1-block reorg 会让 sandwich 的 backrun 单独被打包,造成 searcher 持有库存暴露在下一个区块。
- Slippage decoder 错误:解析 Uniswap V2/V3 数据格式不同,错误估算 victim 滑点会让自动化策略亏损。
8. 关键速查 / Quick Reference
| Item | Value |
|---|---|
| Flashbots Relay URL | https://relay.flashbots.net |
| Flashbots Protect RPC | https://rpc.flashbots.net |
| MEV-Boost Repo | github.com/flashbots/mev-boost |
| Uniswap V2 Router | 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D |
| Uniswap V3 Router | 0xE592427A0AEce92De3Edee1F18E0157C05861564 |
| Universal Router | 0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af |
| jaredfromsubway.eth | 0x1f2F10D1C40777AE1Da742455c65828FF36Df387 |
| Eigen Phi Dashboard | https://eigenphi.io |
| libmev | https://libmev.com |
| mevboost.pics | https://mevboost.pics |
术语速查:
- Bundle: 一组 tx 必须按特定顺序原子化打包
- Searcher: 寻找 MEV 机会并构造 bundle 的策略方
- Builder: 把多个 bundle + public mempool tx 组装成 block 的角色
- Relay: 在 builder 与 validator 之间做中继,做 sealed-bid 拍卖
- Atomic Arb: 同一 tx 内完成跨池买卖,零库存风险
9. 面试题 / Interview Questions
- 请描述 The Merge 之后 MEV 分配链路的变化。为什么 validator 拿到的份额从原来的 ~100%(PoW 矿工)变成现在的 88%?多出来的 12% 流向哪里?背后的市场结构变化意味着什么?
- 三明治攻击对 LP 是利好还是利空?给出量化分析(提示:考虑 V3 的 LVR 与 fee tier 关系)。
- 如果你要为一家中心化做市商(如 Wintermute)设计执行策略,避免被 sandwich,你会选 Flashbots Protect、CoW Protocol、还是自建私有 RPC?请从 cost、latency、settlement guarantee 三个维度对比。
- MEV-Inspect 标记的 sandwich 中约有 5% 是 false positive,常见原因是什么?如何在你的解析器里降低误报?
- 若 Ethereum 引入 encrypted mempool(如 Shutter Network),sandwich 会消失吗?还有哪些 MEV 形式无法被加密 mempool 解决?
10. 明日预告 / Tomorrow
Day 104: Flashbots Auction — 我们将深入 Bundle 提交机制、eth_sendBundle API、Builder 经济模型、PBS 如何把 MEV 从黑箱变成市场。实操:用 flashbots.py 提交一个测试 bundle 到 Sepolia builder。