SharkTeam:十大智能合约安全威胁之三明治攻击
问:我们常提到的智能合约漏洞真的是实际中威胁最大、发生最频繁的安全漏洞吗?
答:完全不是那样。例如“溢出”、“外部调用”等常提到的智能合约安全漏洞并不是最常发生,威胁最大的。
到底哪些安全威胁从发生频率和危害性上能称为Top10的呢?SharkTeam合约安全系列课程之【十大智能合约安全威胁】和您一起讨论和深入。第七课【详解三明治攻击】。
一、什么是三明治攻击
三明治攻击( Sandwich Attack):一种抢先交易,主要针对Defi协议和服务。在三明治攻击中,恶意交易者在他们选择的网络上寻找待处理交易,例如以太坊。三明治攻击的发生是在交易前和交易后各下一个订单。从本质上讲,攻击者会同时进行 前置(front-run) 和后置( back-run) 交易,而原来的待处理交易则夹在中间。
根据上图所示,三明治攻击主要流程如下:
(1) 攻击者提前洞察了受害者的交易意图,认为有利可图,提前通过利用10个TokenA兑换了100个TokenB,同时抬高了TokenB的价格
(2) 受害者在不知情的情况下,通过意外价格滑点,以5个TokenA兑换了40个TokenB,原本5个TokenA可以兑换50个TokenB
(3) 攻击者再将100Token B兑换成12.5个TokenA,获利2.5个TokenA
在以X * Y = k理论基础的DEX生态中,每次购买Token时候,对应的价格将会上涨。因此,如果我们先购买它,然后其他人购买其他Token,价格就会上涨。如果我们随后立即卖出,我们将获利,因为我们低买高卖,实现了套利。套利在某种程度上,是可以维护市场价格生态的平衡。但是,三明治攻击会牺牲正常交易者的利益为代价,攻击者最终谋取利润。
三明治攻击可能通过以下两种方式:
(1)流动性获得者攻击流动性获得者
流动性获得者试图攻击在区块链上有待处理的AMM交易的流动性获得者。看到等待批准的交易,掠夺者发出两个后续交易(前置和后置)以从交易者的交易中受益。现在,通过一个流动性池和货币对连接了三个待处理的交易。矿工必须选择哪笔交易首先获得批准。这就是掠夺者可以通过实际贿赂矿工来影响这个决定的地方,即支付更高或更低的交易费用。
(2)流动性提供者攻击流动性获得者
在这种情况下,流动性提供者试图攻击流动性获得者。一切的开始都是一样的,攻击者在区块链上看到一个待处理的交易,然后执行三个交易:
(a)消除流动性:抢占先机(通过减少资产的市场流动性来增加受害者的滑点)
(b)添加流动性:恢复运行(将资金池中的流动性恢复到攻击前的水平)
(c)用B交换A:返回运行(将A的资产余额恢复到攻击前的状态)
在这次攻击中,攻击者在受害者的交易执行之前从流动性池中提取所有资产。在这样做的过程中,掠夺者放弃了受害者交易的佣金。流动性提供者根据他们向AMM提供的流动性收取佣金。
但是,这些攻击都不一定有效。要使攻击有效,需要同时满足两个条件:
(1)利润需要高于gas费(矿工为处理每笔交易收取的费用):因为利润如果很小,用户需要获得相当多的Token数量才能克服gas费
(2)减少滑点:滑点是指用户在交易中愿意接受的理想价格的最大偏差。由于交易不是立即执行的,在同一Token内操作的其他交易可能会先被执行,从而导致价格的变化。这意味着想要购买Token的用户无法知道他们的交易执行时的确切价格。这就带来了购买可能经历过大幅价格变化的Token问题。
二、攻击分析
观察下图可知,三明治攻击是经常发生的。在经常被利用的十大合约中,Uniswapv2 Router2、Uniswap v3 Router2占比较多。截至2022年10月28日,在最近30天中,Uniswap v3 Router2占58.0%。
在最近30天中,三明治攻击监测如下图所示:
我们来分析一个三明治攻击,Tx hash:0x65a6d6e7b88a3d7c6c11ef4658765bcd94e2a0f831a1e9752f711bbecc08740a。
该三明治攻击大概过程如下:
(1)受害者的地址(0x37a…d80fa)计划出售 1.4 WETH 换取 APE
(2)攻击者一直在扫描内存池(mempool),并且观测到受害者的意图
(3)攻击者的地址(0x01b…b0159)发起卖出 44.233706 WETH 换 176.994496 APE 的交易,并且降低了WETH 价格,提高了APE价格
(4)在 WETH 的较低价格下,受害者(0x37a…d80fa)只能获得 3.919601 APE,他本来可以获取更多
(5)攻击者(0x01b…b0159) 以 44.546633 WETH 的价格出售了 176.994496 APE
(6)最终,攻击者(0x01b…b0159) 获得 0.312927 WETH,扣除以太坊上的一些成本
(7)在此过程中,攻击者(0x01b…b0159) 发送 Miner (0x829…3a830) 0.2 WETH 用来提高交易排序
三、预防措施
回顾了相关事件后,我们应该采取哪些适当的措施去避免三明治攻击?
(1)gas限制
三明治攻击之所以会发生,因为更高的gas费用交易优先于其他交易。通过对该gas费用设置一定的限制,影响将不会那么明显。其实,永远无法完全消除这个问题,因为gas费用总是存在差异的。但是,通过让这种差异变小,攻击的发生速度也会变慢。
(2)避免低流动性池
缺乏良好的流动性对这个问题是不利的。流动性池越小,投资者获得好价格的机会就越小,因为这更容易产生滑点。滑点越高,从三明治攻击中获得的利润就越多。
(3)小额交易
三明治攻击对较大的交易额感兴趣,交易额越大,利润空间越大。避免三明治攻击的一种方法是将我们的交易分成几个较小的交易,因为这些小额交易对于抢跑者来说不太具有吸引力。
关于我们:SharkTeam的愿景是全面保护Web3世界的安全。团队成员分布在北京、南京、苏州、硅谷,由来自世界各地的经验丰富的安全专业人士和高级研究人员组成,精通区块链和智能合约的底层理论,提供包括智能合约审计、链上分析、应急响应等服务。已与区块链生态系统各个领域的关键参与者,如Polkadot、Moonbeam、polygon、OKC、Huobi Global、imToken、ChainIDE等建立长期合作关系。