常见的 MEV 套利
以太坊交易的执行顺序大致可以分为以下步骤
交易者提交交易到 mempool
矿工对 mempool 中的交易排序、打包获得一定利润
- 矿工会先模拟执行每一笔交易,把失败的交易剔除。然后根据 gas 费大小进行排序。
- 如果 gas 费相同的两笔交易则根据时间排序
给矿工支付手续费有两种方式
3.1 交易者在提交交易的时候携带 gas 费
3.2 交易者在合约中通过
coinbase.transfer
向矿工支付手续费
在 EIP-1559 以后: gasPrice = basePrice + tipPrice
basePrice
会被直接燃烧掉,tipPrice
是给矿工的
什么是 MEV
最大可提取价值 (Maximal Extractable Value, 简称 MEV)
MEV 详细解释可参考: MAXIMAL EXTRACTABLE VALUE (MEV)
MEV 套利的参与者一般有两个: 搜寻者(searcher)和矿工(miner)
searcher
通过监听 mempool
发现套利机会执行交易,并将利润的一部分分给矿工
。发现机会的searcher
会有很多,矿工会根据searcher
给的利润大小决定交易执行的先后顺序,所以 gas 费的大小也很重要。如果交易被排到后面执行可能利润已经被前面的searcher
吃掉了导致套利失败。
searcher
分为两种类型:
直接发现交易机会
通过监听 mempool
中的交易机会,直接发送套利交易。
观察其他套利者的机会
另一种searcher
是通过观察mempool
中其他套利者提交的交易,把签名信息替换成自己的地址。然后以更高的 gas price 提交给矿工抢先成交。
这两种套利交易如果直接发送到mempool
中,由于所有的searcher
都能看到所有交易信息。而且套利者很多,最后就会造成 gas 费的恶性净增,最后矿工成了唯一赢家。所以真实的套利机器人大多都会采用flashbots
方案
Flashbots
因为 MEV 的恶性 gas 费竞争,会导致链上 GAS 居高不下,普通用户交易一笔成本很高,套利者的利润也会变得很小。为了解决这种恶性竞争问题。falshbots
提供了一种服务。可以把交易者的交易不发送到mempool
中,而是直接发送给矿工。这样其他 searcher 就无法在mempool
中监听到自己的交易。
由于我们在链上执行交易时,对于没有利润的套利我们需要拒绝执行,但是对于失败的交易也需要支付手续费。所以有可能套利没套到,最后手续费损失一大把。但是使用flashbots
则可以规避这种情况
flashbots
有以下几个特性:
- 交易者的交易直接发送给矿工,避免了暴露套利机会给其他 searcher,防止抢跑
- 可以将一笔或多笔交易捆绑(bundle)直接发送给矿工
- 如果交易失败,不收取费用(如果不使用 flashbots,则失败交易,也要支付 gas 费)
flashbots 会按照以下规则执行 bundle 交易
- 模拟独立执行所有的 bundle,记录每个 bundle 的 price,
bundle_price =矿工从 bundle 中获得的总收益 / bundle 的总 gas_use
,具体计算公式参考: bundle pricing - 将 bundle_price 从高到低排序,按照顺序模拟执行一遍,把包含失败(revert)交易的 bundle 剔除掉,剩下成功的 bundle 按照既定顺序打包上链(include),在一下个区块中,这些 bundle 会排在最前面
- 如果一个 bundle 中包含多笔交易,只要其中一笔交易失败,整个 bundle 都不会被 include,searcher 也不会有任何损失(但是有 5%的概率发生 uncle bandit 攻击,bundle 会被泄露到 mem pool 中被其它矿工执行,如何避免被 uncle,参考: uncle bandit risk
Mempool
从上面所诉我们可以看到,通过mempool
观察套利机会很有用。普通用户没有使用flashbots
节点的交易都会发送到mempool
中。mempool
中的交易即还未被打包的pending
状态的交易
由于套利竞争很激烈,及时性对于我们能否第一时间找到套利机会很重要,所以我们一般会选用专门的mempool
服务,给我们提供及时交易机会提醒。这类服务例如:
对于blocknative
我们可以通过配置面板来过滤我们想要的交易数据。通过集成 SDK 来实时监听链上交易
闪电贷/闪电兑换
闪电贷/闪电兑换: 是一种无抵押借贷。只要我们保证在一个区块内完成借款和还款即可
当我们进行链上套利的时候,一般需要有一定资金来启动资金来交易。例如两个 DEX 间套利,我们发现 Uniswap 上的 ETH 价格是 1000U,而 sushiswap 上的价格是 1200U。那么我们可以通过在 Uniswap 上买入 ETH,在 sushiswap 上卖出实现套利。我们如果使用闪电贷套利的话,可以从 Uniswap 上借出 ETH,在 sushiswap 上卖掉。然后将 USDT 或者 ETH 还回去。即可实现无成本或无风险套利。
套利流程
结合上面的技术点组合起来可以有以下套利流程
- 通过监听 mempool 中的套利机会
- 发现机会以后,通过闪电贷/闪电交易借出资金
- 通过 flashbots 捆绑交易并提交交易
- 还回借出的资金和利息。检查交易是否有利可图,如果有利可图,则执行交易,否则中断执行
交易风险
理论上 mev 套利是无风险的,但是对于三明治夹击,有一种情况需要注意。
之前出现过一种针对三明治夹击的钓鱼攻击: 沙门氏菌,这种攻击先部署了一个 token,然后在 uniswap 上添加流动性并发送调用 swap 交易,吸引机器人进行三明治夹击。机器人的第一笔交易用 100 个 ETH 买入 token,第二笔交易卖出 token 失败,导致 100 个 ETH 留在池子中。
所以后面的三明治机器人优化了策略。一般通过两种措施来防止这种事故发生
- 在发送 bundle 之前先在模拟测试环境中模拟交易执行,如果模拟失败则不发送
- 在 bundle 交易的第二笔卖出 token 时再支付 gas 费,前一笔买入不支付。这样如果交易失败,矿工拿不到奖励,则不会 include bundle
但是这个 Salmonella token 有效地绕过了这两项防御措施,实施了对机器人的攻击,具体可参考:https://twitter.com/bertcmiller/status/1381296074086830091
常见 MEV 套利方法
三明治夹击(单一 DEX 套利)
当 searcher 在 mempool 中监听到一笔大的 A->B 的交易是,并且滑点设置的较大。则攻击者先进行一笔 A->B 的交易,这样 B 的价格会被拉高。然后等用户的交易执行完以后,在反向执行 B->A 的交易。顺序如下
searcher: A->B
用户: A->B
searcher: B->A
这样把用户的交易夹在中间,通过改变交易前后的汇率来实现套利。所以成为三明治夹击
多 DEX 间套利
这种套利是监听两个 DEX 之间的价差。例如 A 平台 ETH 价格是 1000U,B 平台 ETH 价格是 1200U。则套利者的套利执行顺序如下
1. 从A借出ETH
2. 在B平台出售
3. 归还借款和利息给A平台
借贷平台利率差进行套利
这种方式是通过两个借贷平台的借贷利率差。例如 A 平台借贷利率是 10%,B 平台借贷利率是 5%。则套利顺序如下
1. 从A平台抵押USDT借出ETH
2. 将ETH抵押到B平台借出USDT
3. 将USDT还回A平台
其他套利模式 比如跨链 dex 套利、多中心化交易所套利、中心化交易所和 DEX 进行套利等,这种比较靠近做市商思路,暂未深入研究
注意风险
- 沙门氏菌钓鱼攻击: salmonella