2023年3月13日,我们的系统检测到 Euler Finance 的借贷池遭受了闪电贷攻击,导致损失1.97亿美元。我们首先向社区发出警报,然后提供了分析以帮助识别根本原因。
1/ @eulerfinance is attacked. The root cause is due to the lack of liquidity check in the function donateToReserves()https://t.co/stWtPWK900
— BlockSec (@BlockSecTeam) March 13, 2023
See the detailed attack steps below. https://t.co/bm10OJHiXu pic.twitter.com/TDbYuzVWHe
此次事件的根本原因在于 donateToReserves() 函数缺乏无力偿还检查。具体来说,存在漏洞的合约允许用户将其抵押品捐赠给协议,但却没有检查该用户的头寸是否无力偿还。更糟的是,为了摆脱这种不良头寸,协议以很大的折扣提供给清算人,让他们能够以较低的价格清算该头寸。攻击者通过利用此功能创建了一个大头寸,并使其无力偿还。然后,他能够以折扣价购买其抵押品以获利。
背景
Euler Finance 概述
Euler Finance 是一个基于以太坊的借贷协议,允许用户借入和借出指定的代币。当贷方将资金存入 Euler 的流动性池时,会铸造相应数量的 ETokens(计息 ERC20 代币)并发送给他们。这些 ETokens 可以兑换成他们存入的底层资产。
另一方面,借款人获得流动性后会收到 DTokens。这些 DTokens 符合 ERC20 标准,并阻止持有者自行销毁它们。具体来说,它们不能被发送给任何人,但可以被任何人拿走,而接受它们需要获得批准。在底层资产方面,借款人负责支付贷款利息,其中一部分利息用于弥补协议上的坏账。
Euler Finance 的杠杆借贷(又称自借)和软清算机制是帮助我们更好地理解此次攻击原因的两个关键概念。
杠杆借贷
Euler Finance 提供杠杆借贷功能,允许用户模拟递归借贷策略。简而言之,用户可以存入抵押品并铸造 ETokens,然后将其用作抵押品以借入更多 ETokens。合约还将铸造相应数量的 dTokens 作为债务代币。用户头寸的健康状况是根据 ETokens 和 dTokens 的价值计算的。根据 Euler Finance 的文档,用户最多可以获得 19 倍的杠杆。杠杆借贷功能在此次事件中起到了至关重要的作用。如果没有此功能的帮助,攻击者将无法获利。通过杠杆借贷,攻击者将其头寸规模放大了近 11 倍于从闪电贷获得的初始资金。
软清算
正如 Euler Finance 的白皮书中所述,软清算机制使清算人能够帮助被清算方灵活地偿还债务,而不是像 Compound 和 Aave 等协议那样受限于固定的清算系数。软清算意味着,头寸的健康状况越差,可用于清算的抵押品就越多——根据此事件的数据,在发生坏账的情况下,最高可达 75%。因此,大量打折抵押品的清算使得攻击者能够偿还闪电贷并获得利润。
漏洞分析
主要漏洞,即缺乏无力偿还检查,存在于 donateToReserves() 函数中,该函数用于用户将其头寸中的 ETokens 作为捐赠转移到协议储备中。对于普通用户来说,通常没有动机或理由执行此类操作。事实上,漏洞在于 donateToReserves() 函数在将 ETokens 从用户头寸中转移出来时,没有进行健康检查。这使得攻击者可以直接从通过杠杆借贷创建的大头寸中捐赠 ETokens,导致头寸的健康状况跌破 100%,从而产生坏账。

根据设计,Euler Finance 使用动态清算系数来“软清算”头寸。简而言之,头寸越不健康,可以清算的该头寸中的抵押品比例就越高。在发生坏账的情况下,清算比例可能高达头寸中抵押品的 75%(根据实际攻击交易计算)。因此,大量打折抵押品的清算使得攻击者能够偿还闪电贷并获得利润。
攻击分析
有多个攻击交易针对不同的池:
- 0xc310a0affe2169d1f6feec1c63dbc7f7c62a887fa48795d327d4d2da2d6b111d (DAI)
- 0x71a908be0bef6174bccc3d493becdfd28395d8898e355d451cb52f7bac38617 (WBTC)
- 0x62bd3d31a7b75c098ccf28bc4d4af8c4a191b4b9e451fab4232258079e8b18c4 (wstETH)
- 0x465a6780145f1efe3ab52f94c006065575712d2003d83d85481f3d110ed13d9 (USDC)
- 0x3097830e9921e4063d334acb82f6a79374f76f0b1a8f857e89b89bc58df1f311 (stETH)
- 0x47ac3527d02e6b9631c77fad1cdee7bfa77a8a7bfd4880dccbda5146ace4088f (WETH)
攻击步骤如下(以第一次攻击交易为例):
- 攻击者通过闪电贷在 AAVE 中借入 3000 万 DAI。
- 攻击者存入 2000 万 DAI 并获得了 2000 万 eDAI。
- 由于 Euler Finance 提供杠杆借贷功能,攻击者可以铸造 1.95 亿 eDAI 和 2 亿 dDAI。现在攻击者持有 2.15 亿 eDAI 和 2 亿 dDAI。
- 继续上述步骤。偿还了 1000 万债务,以便攻击者可以铸造更多的 eDAI。现在攻击者持有 2.15 亿 eDAI 和 1.9 亿 dDAI。
- 重复步骤 3。现在攻击者持有 4.1 亿 eDAI 和 3.9 亿 dDAI。
- 攻击者调用 donateToReserve 函数捐赠 1 亿 eDAI。然而,在此过程中,并未检查攻击者的健康因子。在这种情况下,该头寸现在可以被清算(3.1 亿 eDAI 对比 3.9 亿 dDAI),这带来了获利的机会。
- 攻击者使用另一个地址合约作为清算人(0xa0b3...)清算了该头寸。清算人(0xa0b3...)收到了 3.1 亿 eDAI 和 2.59 亿 dDAI。
- 攻击者销毁了 3890 万 eDAI 以提取 3890 万 DAI(由于无力偿还检查,无法提取更多)在清算人的头寸(0xa0b3...)中。
- 攻击者偿还了闪电贷。
关键的步骤 2-7 在交易跟踪中进行了标记。

总结
这是 2023 年最大的黑客攻击事件,一位名叫 Federico Jaime 的 20 岁阿根廷人创纪录地窃取了 1.97 亿美元,他向媒体提供了“一段蜿蜒、有时令人困惑,甚至自相矛盾的叙述”。尽管如此,“所有可追回的资金”后来都被归还给了 Euler Finance 的金库地址。然而,一小部分资金(约 20 万美元)被“无意中”发送给了 Lazarus 集团——一个被美国财政部制裁的据称由朝鲜支持的犯罪集团。您可以参考这些链接,即链接 2 和 链接 2,以获取详细且有趣的故事。
此次事件的根本原因是缺乏无力偿还检查,这是一个教训。事实上,对于借贷协议来说,评估是否应该对任何可能影响用户头寸的程序实施头寸健康检查至关重要。此外,项目团队应主动监控其借贷协议,关注重大的清算事件,并建立有效的警报系统,以便及时发现和响应此类事件。
阅读本系列的更多文章:
- 引言:2023 年十大“精彩”安全事件
- #1:利用 Flashbots Relay 中的漏洞收割 MEV 机器人
- #3:KyberSwap 事件:通过极其微妙的计算巧妙利用舍入误差
- #4:Curve 事件:编译器错误导致无害源代码生成错误字节码
- #5:Platypus Finance:幸运地躲过了三次攻击
- #6:Hundred Finance 事件:催化了脆弱的叉协议中与精度相关的攻击浪潮
- #7:ParaSpace 事件:与时间赛跑,阻止行业最关键的攻击
- #8:SushiSwap 事件:笨拙的救援尝试导致一系列模仿攻击
- #9:MEV 机器人 0xd61492:在一次巧妙的攻击中从猎人变成猎物
- #10:ThirdWeb 事件:受信任模块之间的不兼容性暴露了漏洞



