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 的流动性池存入资产时,系统会铸造相应数量的 EToken(计息型 ERC20 代币)并发送给他们。这些 EToken 可用于赎回所存入的底层资产。
另一方面,获取流动性的借款人会收到 DToken。这些 DToken 符合 ERC20 标准,但持有者无法独立销毁它们。具体来说,与其允许代币发送给任何人,不如说任何人都可以主动获取它们,但接受它们需要获得授权。就底层资产而言,借款人负责为其贷款支付利息,其中一部分利息用于弥补协议上的坏账。
Euler Finance 的杠杆借贷(即自我借贷)和软清算机制是帮助我们更好理解此次攻击原因的两个关键概念。
杠杆借贷
Euler Finance 提供杠杆借贷功能,使用户能够模拟递归借贷策略。简而言之,用户可以存入抵押品并铸造 EToken,这些 EToken 随后可作为抵押品借入更多 EToken。合约还会铸造相应数量的 dToken 作为债务代币。用户头寸的健康状况根据 EToken 和 dToken 的价值进行计算。根据 Euler Finance 的文档,用户最高可使用 19 倍杠杆。杠杆借贷功能在此次事件中发挥了关键作用。若没有该功能的协助,攻击者将无法获利。通过杠杆借贷,攻击者将其头寸规模放大至从闪电贷获得的初始资金的近 11 倍。
软清算
如 Euler Finance 的白皮书所述,软清算机制使清算人能够灵活地协助被清算方偿还债务,而非像 Compound 和 Aave 等协议那样采用固定系数进行清算。软清算意味着头寸健康度越低,可被清算的抵押品比例越高——根据此次事件的数据,在发生坏账的情况下,最高可达 75%。因此,以大幅折扣清算抵押品使攻击者得以偿还闪电贷并获取利润。
漏洞分析
主要漏洞,即缺乏偿债能力检查,存在于 donateToReserves() 函数中。该函数供用户将其头寸中的 EToken 作为捐赠转移至协议的储备金。对于普通用户而言,通常没有动机或理由执行此类操作。事实上,漏洞在于 donateToReserves() 函数在从用户头寸中转出 EToken 时未执行健康度检查。这使攻击者能够直接将通过杠杆借贷创建的大型头寸中的 EToken 进行捐赠,导致头寸健康度降至 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。
- 攻击者在清算人头寸(0xa0b3...)中销毁了 3890 万 eDAI,提取了 3890 万 DAI(由于偿债能力检查,无法提取更多)。
- 攻击者偿还闪电贷。
关键攻击步骤 2-7 已在交易追踪记录中标注。

总结
这是 2023 年损失最大的黑客事件,创纪录地损失了 1.97 亿美元,实施攻击的是一名 20 岁的阿根廷人,名叫 Federico Jaime,他向媒体提供了"一段曲折、有时令人困惑、甚至前后矛盾的陈述"。尽管如此,"所有可追回的资金"后来均已归还至 Euler Finance 的国库地址。然而,一小部分资金(约 20 万美元)被"无意中"转给了 Lazarus Group——一个据称由国家支持、受美国财政部制裁的朝鲜犯罪组织。您可以参阅以下链接,即 link2 和 link2,了解这段详细而有趣的故事。
此次事件的根本原因是缺乏偿债能力检查,值得引以为戒。事实上,对于借贷协议而言,评估是否应为任何可能影响用户头寸的操作实施头寸健康度检查至关重要。此外,项目团队应主动监控其借贷协议中的大额清算行为,并建立有效的预警系统,以便及时发现并响应此类事件。
阅读本系列其他文章:
- 引言:2023年十大"精彩"安全事件
- #1:利用 Flashbots Relay 漏洞收割 MEV 机器人
- #3:KyberSwap 事件:以极为精妙的计算对舍入误差实施精湛利用
- #4:Curve 事件:编译器错误从无辜源代码生成错误字节码
- #5:Platypus Finance:三次攻击中侥幸生存
- #6:Hundred Finance 事件:在存在漏洞的分叉协议中催生精度相关漏洞利用浪潮
- #7:ParaSpace 事件:与时间赛跑,挫败迄今业内最关键的攻击
- #8:SushiSwap 事件:笨拙的救援尝试引发一系列模仿攻击
- #9:MEV 机器人 0xd61492:从猎手到猎物的精巧利用
- #10:ThirdWeb 事件:受信模块间的不兼容性暴露安全漏洞



