欢迎订阅专栏:10分钟智能合约:进阶实战
后置交易(Back-running):定义、原理与防御
后置交易 是指攻击者监控公开交易池(Mempool),在发现一笔会对链上状态产生可预测影响的目标交易后,立即将自己的交易打包在目标交易之后(同一区块或紧随的区块),利用目标交易所造成的价格偏移、状态变化或套利机会来获利。
后置交易是 MEV 的常见形式,与抢先交易相反:它不打断目标交易,而是搭便车。
1. 为什么后置交易可行?
- 状态可预测:目标交易执行后,某些变量(如 DEX 储备量、借贷仓位)会确定性改变。
- 排序权可购买:攻击者通过支付更高 Gas,将自己的交易紧贴在目标交易之后。
- 无需对抗:后置交易通常不伤害原始交易者(有时甚至帮助其成交),因此更隐蔽,也较少引起反感。
2. 常见后置交易类型
| 类型 | 描述 | 典型场景 |
|---|---|---|
| 套利 | 目标交易导致两个 DEX 之间出现价差,攻击者在之后立即套利平衡价格。 | Uniswap/Sushiswap 价差套利。 |
| 清算 | 目标交易(如借款人的还款)使某个借贷仓位恰好低于清算线,攻击者随后清算该仓位获利。 | Compound、Aave 清算。 |
| 三明治的后半段 | 在三明治攻击中,后置交易是卖出先前买入的资产(但需前置配合)。 | DEX 大额兑换。 |
| 止损狩猎 | 目标交易触发某人的止损订单,攻击者随后反向交易获利。 | 杠杆交易平台。 |
| 空投狙击 | 目标交易(如 Uniswap V3 增加流动性)导致用户获得 LP NFT,攻击者后置交易购买该 NFT。 | 稀有 LP 位置。 |
3. 攻击原理详解(套利后置为例)
假设 Uniswap 和 Sushiswap 上同一代币对价格存在微小价差。
- 侦察:攻击者监控到一笔在 Uniswap 上购买 10 ETH 代币 A 的交易,该交易将使 Uniswap 上代币 A 的价格暂时高于 Sushiswap。
- 后置交易:攻击者发送一笔更高 Gas 的交易,在同一区块中紧随目标交易之后执行。
- 套利操作:攻击者的交易从 Sushiswap(低价)买入代币 A,然后在 Uniswap(高价)卖出,赚取价差。
- 结果:攻击者获利,且两个 DEX 的价格恢复均衡,原始交易者未受直接损失(甚至因套利者补充流动性而滑点降低)。
简化代码示例(仅逻辑演示):
contract BackrunBot {
function arbitrage(address token, uint amount) external {
// 假设目标交易已经执行,此时 Uniswap 价格 > Sushiswap
uint sushiPrice = getPriceSushi(token);
uint uniPrice = getPriceUni(token);
if (uniPrice > sushiPrice) {
// 从 Sushi 买入
sushi.swapExactETHForTokens{value: amount}(...);
// 在 Uni 卖出
uni.swapExactTokensForETH(...);
}
}
}
实际上,后置交易通常与区块空间拍卖结合,攻击者通过 Flashbots 等工具确保自己的交易紧贴在目标交易之后。
4. 后置交易 vs 抢先交易
| 维度 | 抢先交易 (Front-running) | 后置交易 (Back-running) |
|---|---|---|
| 执行顺序 | 在目标交易之前 | 在目标交易之后 |
| 对用户影响 | 通常有害(滑点增加、抢购失败) | 通常无害或有益(套利降低滑点) |
| 盈利来源 | 抢占用户利润或制造不利价格 | 利用用户造成的状态变化套利 |
| 道德评价 | 负面(被视为攻击) | 中性(被视为市场效率行为) |
| 典型场景 | 抢 NFT 铸造、抢清算 | DEX 套利、清算 |
但后置交易也可能被滥用,例如:攻击者先通过自己的交易制造价差,再后置套利,形成自导自演的“虚假套利”。
5. 防御与缓解措施
虽然后置交易通常不被视为恶意,但在某些协议中,开发者可能希望减少或禁止它。
| 策略 | 实现方式 | 效果 |
|---|---|---|
| 最小化状态变化 | 设计协议时,避免单笔交易产生巨大的价格偏移(例如使用 TWAP 预言机)。 | 降低套利空间。 |
| 批量结算 | 采用如 CowSwap 的批量拍卖机制,将所有订单统一清算,消除套利机会。 | 完全消除后置套利。 |
| 交易延迟与随机排序 | 协议将交易放入队列,随机顺序执行,使攻击者无法预测目标交易后的状态。 | 增加后置交易不确定性。 |
| 使用私有交易池 | 用户通过 Flashbots 等提交交易,避免暴露在公开 Mempool 中,减少被后置跟踪的可能。 | 保护特定交易。 |
| 滑点保护和价格限制 | 用户设置允许的滑点上限,若后置交易导致价格偏离过大,交易回滚。 | 间接防御有害后置。 |
协议设计示例:延迟队列
contract DelayedSwap {
struct Order { address user; uint amount; uint timestamp; }
Order[] public queue;
uint public constant DELAY = 3; // 区块数
function addOrder(uint amount) external payable {
queue.push(Order(msg.sender, amount, block.number));
}
function executeOrders() external {
for (uint i = 0; i < queue.length; i++) {
if (queue[i].timestamp + DELAY <= block.number) {
// 执行,此时价格可能与下单时不同,但无法被后置狙击
}
}
}
}
6. 真实案例
- Uniswap 套利机器人:大量
backrun机器人监控 Uniswap 交易,自动套利,使价格快速回归均衡。 - 清算机器人:在 Aave 上,攻击者监控所有可能触发清算的交易,后置调用
liquidate获得奖励。 - Flashbots 的 “Backrun” 捆绑:矿工直接接受后置交易的捆绑包,确保套利交易紧跟目标交易。
7. 总结
- 后置交易是 MEV 的中性形式:它利用目标交易造成的状态变化获利,通常不损害原始用户,甚至有助于市场效率。
- 但仍需警惕:恶意后置可能组合其他攻击(如先前置制造价差,再后置套利),或用于操纵预言机。
- 防御核心:
- 对用户:使用私有交易池或滑点保护。
- 对协议:采用批量清算、延迟执行、TWAP 等机制减少可被后置利用的瞬时状态。
审计时,应检查协议是否存在可被后置交易持续套利的“可预测状态变化”,并评估这种套利是否会影响协议经济安全(如持续抽取资金)。