10分钟智能合约:进阶实战-4.10 三明治攻击

41 阅读4分钟

欢迎订阅专栏10分钟智能合约:进阶实战

三明治攻击(Sandwich Attack):定义、原理与防御

三明治攻击 是 MEV 中最具代表性的攻击形式之一。攻击者将目标交易“夹”在自己的两笔交易中间:先在前置交易中推高价格,等待目标交易以高价执行,最后在后置交易中卖出,赚取差价。因交易顺序形成“夹心”而得名。

三明治攻击 = 前置交易(Front-run) + 目标交易(Victim) + 后置交易(Back-run)。


1. 攻击原理详解

攻击者监听公开交易池(Mempool),发现一笔会对价格产生显著影响的交易(如用 10 ETH 在 Uniswap 购买某代币)。攻击者随即构造两笔交易:

  1. 前置交易:支付更高 Gas,在目标交易前买入同样的代币,人为抬高价格。
  2. 后置交易:支付更高 Gas,在目标交易后立即卖出之前买入的代币。

攻击流程示意图

区块交易顺序(按Gas价格排序,高到低):
┌─────────────────────────────────────────────┐
│  1. 攻击者买入交易(高Gas)  ← 前置         │
│  2. 用户买入交易(中Gas)    ← 目标         │
│  3. 攻击者卖出交易(高Gas)  ← 后置         │
└─────────────────────────────────────────────┘

价格变化:
  正常价格 → 前置买入推高 → 用户被迫更高价买入 → 后置卖出价格略回落,但攻击者仍获利

简化示例(Uniswap V2 风格)

  • 初始池:10 ETH 和 10,000 代币 A,价格 1 ETH = 1,000 A。
  • 用户交易:想用 10 ETH 买 A。正常应获得 ≈ 5,000 A(考虑滑点)。
  • 攻击者前置:先用 10 ETH 买 A,价格飙升,用户交易时获得更少的 A(比如 2,500 A)。
  • 攻击者后置:卖出之前买入的 A(加上用户买入后池子里的 ETH),获利差价。

实际上,攻击者通过两笔交易原子化(通常使用 Flashbots 捆绑)确保要么全成功,要么全失败。


2. 攻击的关键条件

  • 目标交易滑点大:大额交易相对池子流动性而言足够大,价格影响明显。
  • 低流动性池:越小、越浅的池子越容易被操纵。
  • 公开 Mempool:攻击者能提前看到用户交易。
  • Gas 竞价自由:攻击者愿意支付比用户更高的 Gas 来插队。

3. 攻击的数学本质

设目标交易前池中 x 个 ETH,y 个代币。用户欲用 Δx ETH 买入 Δy 代币。

在没有前置的情况下,用户获得的代币 Δy = y - (x*y)/(x+Δx)

攻击者前置交易买入 α ETH 的代币,进一步改变储备,使得用户最终获得的代币远少于无攻击时应得的数量。攻击者随后卖出,赚取差价。


4. 防御与缓解措施

策略实现方式有效性
私有交易池使用 Flashbots RPC 提交交易,不进入公开 Mempool。直接避免被侦察,最有效。
设置滑点容忍度用户设置 0.5%~1% 的滑点上限,超限交易回滚。基本防护,但可能被高滑点需求覆盖。
使用 TWAP 预言机交易价格基于时间加权平均价,而非瞬时储备。彻底消除三明治,但需要设计。
批量拍卖如 CowSwap,将所有订单聚合成批量,统一结算。完全消除排序攻击,但流动性受限。
Commit-Reveal用户先提交订单哈希,后再揭示订单详情。防侦察,但用户体验复杂。
DEX 层面限制对单笔交易的最大滑点或最大交易量进行限制。增加攻击成本。

代码示例:用户侧使用滑点保护

function swapWithProtection(
    uint amountIn,
    uint minAmountOut,   // 最小期望输出,防止三明治
    address tokenIn,
    address tokenOut
) external {
    uint amountOut = dex.swap(amountIn, tokenIn, tokenOut);
    require(amountOut >= minAmountOut, "Slipped too much");
}

5. 真实案例

  • Jared from Subway bot:以太坊上最著名的三明治攻击机器人,每天获利数十万美元,至今仍活跃。
  • Uniswap 早期 MEME 代币:许多低流动性代币上线后,用户大额购买即被三明治攻击。
  • MEV-保护聚合器:1inch、CowSwap 等的出现正是为了对抗三明治攻击。

6. 总结

三明治攻击的本质

  • 利用交易排序权公开 Mempool 狙击对价格敏感的用户。
  • 攻击者不创造价值,只是重新分配用户损失。

对普通用户

  • 使用支持 MEV 保护的 DEX 聚合器(如 CowSwap、1inch 的“防护”模式)。
  • 设置较小的滑点容忍度。
  • 大额交易拆分成小额,或使用 Flashbots RPC。

对协议开发者

  • 避免依赖瞬时储备定价(使用 TWAP)。
  • 考虑实施批量拍卖或交易延迟机制。
  • 教育用户使用安全的交易工具。

审计三明治风险时,重点关注 DEX 交易对流动性的深度、预言机机制以及是否存在可被轻易操纵的价格计算逻辑。