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 又可以用作抵押品来借入更多的 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,从清算人(0xa0b3...)的头寸中提取了 3890 万 DAI(由于偿付能力检查,无法提取更多)。
- 攻击者偿还了闪电贷。
关键的步骤 2-7 在交易追踪中已标记。

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



