2022年4月30日,攻击者利用Nerve Bridge事件中相同的漏洞攻击了Saddle Finance。总共攻击了4,900个以太坊。幸运的是,其中1,360个以太坊被我们成功挽救。该事件的详细描述可以在官方事后分析中找到。


尽管利用的是相同的漏洞,但攻击方式与之前的攻击方式不同。由于新的攻击方式不像人们预期的那样直接,我们认为它值得付出更多努力进行深入调查。在本报告中,我们首先简要介绍该漏洞,然后回顾Nerve Bridge事件的原始攻击方法。之后,我们将专注于Saddle Finance事件,通过剖析攻击过程来揭示新的攻击方式。
0x1. 关于已部署的合约
相关的合约地址如下:
- 受害者MetaSwap合约:0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
- 易受攻击的MetaSwapUtils合约:0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17
值得注意的是,与已验证的MetaSwap合约关联的MetaSwapUtils合约的显示代码与已部署的MetaSwapUtils合约不等效,后者在Settings中指定了地址,如下所示:

所以,请不要混淆这两个MetaSwapUtils合约:)
0x2. 漏洞分析
易受攻击的合约属于MetaPool,这在之前的博客中已详细讨论过。 简而言之,MetaPool最初由Curve设计,允许用户将一种代币与另一个(基础)池中的所有代币进行交易,而不会稀释其流动性。它本质上是一个由稳定币和基础池的LP代币组成的池,而基础池又包含几种其他稳定币。 MetaPool的设计存在一个问题,即MetaPool基本上是一个稳定币池,用于维持稳定币的价格,而基础稳定币池的LP代币不是稳定币。
事实上,基础稳定币池的LP代币价格可以通过调用基础池的getVirtualPrice函数来获得,并且随着基础池收取费用的累积,其价格会稳步上涨。
为了解决这个问题,MetaPool在计算价格之前会扩大LP代币的储备,如下所示。

因此,如果用户用LP代币兑换稳定币,LP代币的金额将在计算价格之前被扩大。 或者,如果用户用稳定币兑换LP代币,计算出的LP代币金额将在转移和记账之前被缩小。

上面的swapUnderlying函数的代码片段用于在MetaPool中的稳定币和基础池中的稳定币之间进行兑换。如两个红色方框所示,该函数会扩大进入的LP代币的数量,并缩小兑换的LP代币的数量。
然而,swap函数的实现与swapUnderlying函数的实现不一致。具体来说,漏洞的根本原因在于swap函数(即_calculateSwap函数)中实现的计算存在缺陷,未能正确地缩小和扩大LP代币的金额。如下图所示,左侧是MetaPool的易受攻击代码,右侧是修复后的版本。

Nerve Bridge事件的攻击者利用了swap函数和swapUnderlying函数之间的不一致性。
(注意,Nerve Bridge是Saddle Finance的分叉项目。)
之后,Saddle Finance修复了该漏洞,并立即重新部署了MetaSwapUtils库的新版本(即V2)。
不幸的是,由于未知原因,以太坊上的sUSD V2 MetaPool仍然部署了旧的、易受攻击的MetaSwapUtils库。 结果,该漏洞在4月30日再次被攻击者成功利用。有趣的是,与Nerve Bridge事件中使用的攻击方式不同,采用了不同的方式来攻击易受攻击的MetaPool。
0x3. Nerve Bridge事件的原始攻击方法
我们重新使用下图(见之前的博客)来回顾原始攻击方法。

由于易受攻击的swap函数没有缩小兑换的LP代币(Nerve 3-LP)的金额,第3步中的兑换金额(36,959)比正常情况要大。
然后,攻击者调用swapUnderlying函数(没有漏洞)将36,959 Nerve 3-LP(在第4步和第5步)兑换成51,494 fUSDT,获利1,143 fUSDT。
从道理上讲,这种利润可以解释为:攻击者在第3步中获得了更多的Nerve 3-LP,然后利用swap函数和swapUnderlying函数之间的不一致性以“正常”价格出售它们。
0x4. Saddle Finance事件的新攻击方法
近期Saddle Finance事件的攻击者使用了不同的方法来攻击相同的易受攻击的swap函数,而无需涉及swapUnderlying函数。
在这里,我们以一个攻击交易为例来演示该过程。

直观地,似乎不应该存在任何利润,因为第3步和第4步的任何暗示都会被抵消。
具体来说,在第3步中,由于没有缩小兑换的LP代币(即saddleUSD),攻击者可以兑换出更多的saddleUSD。
然而,在第4步中,由于易受攻击的swap函数在计算价格之前没有扩大进入的saddleUSD的数量,攻击者不可避免地兑换出更少的sUSD。
然而,如上图所示,攻击者通过第3步和第4步的兑换组合获利2,059,771 sUSD。 要弄清楚利润的原因,我们必须深入研究定价机制,并进行深入调查以理解攻击过程。
0x4.1 定价机制
Saddle Finance的MetaPool继承了Curve的定价公式:

函数图(当n=2时)显示在下图中用蓝色曲线表示。 (公式的设计可以在Curve StableSwap白皮书中找到。)

现在的问题是:MetaPool如何使用这个公式来计算每次兑换的价格?
假设n=2,用户用dx0个token0兑换dx1个token1。
我们可以模拟dx1的计算过程。
在每次兑换中,A可以被视为常数,
而D是唯一可以影响价格曲线的变量。事实上,D随着池子收取费用的累积而增加。
具体来说,计算过程可总结为以下三个步骤:
- 步骤I:将当前池的储备(x0和x1)代入公式计算当前的
D,该D决定了当前的价格曲线。 - 步骤II:将x0增加dx0,并将当前的
D和x0代入公式计算新的x1。 - 步骤III:然后,dx1是新x1与旧x1之间的差值。
如果token0是基础池的LP代币,那么步骤II将变为:

这里,baseVirtualPrice/1e18在攻击期间约为1.0033。 或者,如果代币是基础池的LP代币,那么步骤III将变为:

为了理解D如何影响价格曲线,我们也用一个例子来描述它。
假设用户首先用dx0个token0兑换dx1个token1,然后用dx1个token1兑换dx0'个token0。

如上图所示,由于步骤②对第一次兑换收取了费用,D增加,将价格曲线向上移动(从黑线到蓝线)。
此外,该图清楚地描述了为什么dx0'小于dx0'。
0x4.2 攻击分析
为了分析利润的原因,我们本地部署了易受攻击和已修复的MetaSwapUtils库,并利用当时受害者池的状态来模拟攻击。
此外,在此模拟过程中,我们还记录了一些有助于理解攻击过程的值,即此时A为10,000,x_sUSD为8,130,463,x_saddleUSD为9,688,608,D为17,818,392。

上图描述了盈利性兑换对的过程:
- 兑换-I:用14,800,272 sUSD兑换9,657,586 saddleUSD
- 兑换-II:用9,657,586 saddleUSD兑换16,860,043 sUSD
具体来说,兑换-I可以分为以下两步:
- ①:用14,800,272 sUSD兑换9,625,654 saddleUSD。此时,由于收取的费用,
D增加到17,931,435。 - ②:由于易受攻击的MetaPool没有缩小已兑换的saddleUSD的金额,池子损失了31,932 saddleUSD。损失使
D减少到15,736,195,这进一步将价格曲线向下移动(从黑线到灰线)。
类似地,兑换-II也可以分为两步:
- ③:由于价格曲线向下移动,同样的9,625,654 saddleUSD可以兑换出16,891,906 sUSD,远超成本:14,800,272 sUSD。
- ④:由于易受攻击的MetaPool在计算价格之前没有扩大进入的saddleUSD的金额,MetaPool中留下了31,863 sUSD,这使得价格曲线向上移动(从灰线到蓝线)。 尽管如此,兑换对仍然获利2,059,771 sUSD。
显然,上述分析清楚地阐述了攻击者为何能通过使用新的攻击方法获利。 此外,由于兑换-II中MetaPool中留下的sUSD,原始攻击方法似乎比新方法更有效。当然,攻击者可以发起多次攻击来耗尽池子,这在实际中已经观察到。
0x5. 一些启示
调查表明,两个事件中利润的根本原因相同。具体来说,第一次兑换(兑换LP代币)会降低易受攻击的MetaPool的D值,从而将其价格曲线向下移动。这种移动极大地影响了后续的定价,是后续利润的主要原因。
关于BlockSec
BlockSec是一家开创性的区块链安全公司,由一群全球知名的安全专家于2021年创立。公司致力于提升新兴Web3世界的安全性和可用性,以促进其大规模采用。为此,BlockSec提供智能合约和EVM链安全审计服务,Phalcon平台用于安全开发和主动阻止威胁,MetaSleuth平台用于资金追踪和调查,以及MetaDock扩展,帮助Web3构建者在加密世界中高效冲浪。
迄今为止,公司已为MetaMask、Uniswap Foundation、Compound、Forta和PancakeSwap等300多家尊贵客户提供服务,并在两轮融资中从Matrix Partners、Vitalbridge Capital和Fenbushi Capital等知名投资者那里获得了数千万美元。
官方Twitter账号:https://twitter.com/BlockSecTeam



