三明治攻击最可怕的地方就在攻击开始的第一步攻击者就将获利金额计算的非常清楚
三明治套利是一种颇受争议的套利方式,也被称为三明治攻击,是一种利用抢先交易的方式攻击受害者的交易进行套利的攻击方式。在2022年11月9日每周三的技术分享会由真格基金的代码家@daimajia带来了MEV、闪电贷、三明治套利方面的科普,并根据DODO USDT/DAI攻击事件作为具体案例分析了三明治套利,内容很多,干货很足。
一、MEV、闪电贷、三明治套利科普
1、MEV是什么?
MEV(Miner Extractable Value),指最大可提取价值,之前也叫做矿工可抽取价值。矿工在以太坊中可以打包交易、生成区块,而在其产生的区块内,矿工可以将交易包括进来、排除在外、对交易进行排序等。除了交易费用和区块奖励之外,矿工还可以通过上述操作提取出更多的价值,而这个价值就是MEV。
在PoS区块链中对MEV的最新定义是:
在给定环境状态和所有可用操作的情况下,验证者可以跨区块(或一系列区块)提取的总值
验证者可执行的操作包括重新排序、审查和插入交易。它们还可以加入更多的利基策略,比如改变块时间戳、操纵“随机性”、执行其他验证器等等。
通常来说验证者不能改变其环境的状态,包括区块链规则、区块链上的智能合约代码、其内存池中的交易集等。
2、闪电贷
闪电贷是一种无抵押借贷工具,由于区块链交易的原子性和回滚特性得以诞生。用户需要在一个原子交易内完成借款和还款并且不需要任何抵押品。让用户拥有在接近0成本情况下使用巨量资金的能力。
闪电贷必须在同一交易中偿还。就闪电贷而言,可以认为“交易程序”由三部分组成:接受贷款,用贷款做事,偿还贷款,然而这一切都发生在一瞬间。
交易会提交到网络,暂时把这些资金借给你,你可以利用这些资金做一些事情(交易的第二部分),只要资金能及时回到第三部分,你想做什么就做什么。如果资金没有及时回来,区块链网络就会拒绝这个这笔交易,这意味着贷款人会拿回资金。其实,在区块链概念里,他们一直拥有资金。
这就解释了为什么贷款人不要求你提供抵押物,偿还资金是通过合约代码来强制执行的。
3、三明治套利
三明治套利亦被称为三明治攻击,是一种利用抢先交易的方式攻击受害者的交易进行套利的攻击方式。
三明治套利由套利机器人发起,当套利机器人侦测到一笔交易可能引发数字资产的价格滑点的时候,攻击者会采用支付更高的gas费的方式争夺一个区块的打包权。当成功之后,套利机器人立刻抢先购买一定量的数字资产,迫使该资产价格上涨,然后在被攻击交易结束之后抛售出刚买入的数字资产借以实现无成本套利。
三明治套利不是一种和平的套利方式——这种套利手段一定包括对某一个受害者用户的攻击并导致该受害者在资产上的损失。
在以太坊交易中,为抢夺优先打包的权利,攻击者需要付出更高的gas费用,这是因为ETH采用了最优gas费竞拍的方式,即付出最高gas费用的用户能够获得优先打包的权利。为了获得抢先打包区块的行为,攻击者将会在gas费用上产生恶性的竞争,但是由于以太坊的gas费用是每一笔交易(无论成功与否)都需支付的。因此,在攻击者进行恶性竞争的时候,普通用户的利益一定是遭到损害的。
二、Step by Step分析DODO USDT/DAI攻击事件
北京时间 2022年 11 月 3 日,以太坊 (Ethereum) 去中心化交易平台 DODO 遭到攻击,攻击者利用合约漏洞频繁更换代币从而完成了一次三明治攻击,但通过研究链上数据以后会发现整个过程的盈亏比并没有那么夸张,反而还很无奈,攻击者一通操作下来用超出350万USDT的闪电贷本金最后仅仅盈利了26.4USDT,不禁令人唏嘘,整个过程如下:
1、三明治攻击的第一步:攻击者的第一笔交易FrontRun
交易由0xf480地址发起,与一个被Etherscan标记为MEVbot的合约(攻击者合约1)进行了交互,向该合约(即自己的账户)转了12840美金,随后又转入了下一个合约(攻击者合约2)。
2、第二步:借闪电贷将Tether换成DAI
攻击者做了一笔闪电贷的借款,向Balancer借了355万美金,又把这些钱在地址中做了一次划转,将Tether转到了DODO质押代币代USDT的池子,又给攻击者转回了一笔钱,这笔钱就是一笔swap(即一次token的互换)。
这笔swap攻击者转入了355万美金的USDT,转出了353万美金的DAI,从而攻击者账户中的钱从Tether变成了DAI。
3、频繁更换代币
1)利用Psm将DAI换成USDC
接下来攻击者又做了一笔转账,将DAI转向了一个Public合约DssPsm,Psm是一个完成赎回的合约,用户可以向Psm转入DAI换成USDC,Psm会将用户转入的DAI进行销毁。
攻击者向Psm打了3538543个DAI,Psm合约将这些钱打到了零地址(即把这些DAI都烧掉了),然后给攻击者重新转了3538543个USDC。
2)USDC又转USDT
之后攻击者又用换来的USDC在DODO的USDT/USDC的池子中做了一次swap:攻击者合约给DODO打了353万个USDC,DODO给攻击者合约打了353万个USDT。
4、第三步:抽取佣金BackRun完成闭环
随后攻击者将DODO又给一个多签钱包(DODOteam的地址)转了70美金,这一步是DODO在交易过程中抽取佣金。最后攻击者将所有的USDT(3551259个)全部还掉,此次闪电贷结束。
三、总结
总的来说,攻击者在DODO的两个池子里换了两次稳定币,过程为:3551259个USDT——3538543个DAI(这一步产生了很大的滑点)——3538543个USDC——3538419个USDT。
可以发现,最后换出的USDT并不够还闪电贷借出的钱,差价在为3551259-3538149=12840,此时在第一步攻击者给自己转的12840美金就派上了用场。
至此我们会产生疑问,攻击者自己垫付的12840美金不是亏了吗?这是为了实现什么目标呢?
实际上攻击者的这番操作(用USDT换DAI时)让DODO的池子变得更加不平衡,借用这个不平衡的池子换出了更多的USDT(套利过程),利用一个逆过程反向收获了26.4美金(减去Gas和DODO抽取的佣金后)。
因此我们看到其实这样的攻击存在幸存者偏差,在链上发现这样的机会的攻击者和进行这样的攻击其实非常多,大部分我们只能看到攻击成功的案例,更多的时候进行三明治攻击的机器人是要挨打的,很多机器人会被其他机器人反套利,这也就是为什么说现在MEV非常卷的原因。