2025-04-08
欧拉金融攻击:它如何发生,我们能从中得到什么教训
3月13日,Euler Finance遭受了一次闪电贷款攻击,损失超过1.95亿美元。这次攻击像瘟疫一样蔓延到多个去中心化金融(DeFi)协议,除了Euler以外,还有至少11个协议因为这次攻击遭受了损失。接下来的23天里,许多Euler用户都松了一口气,攻击者退还了所有被利用的资金。但尽管加密社区可以庆祝资金的归还,问题仍然存在:此类攻击是否可能在将来造成巨大的损失?分析攻击发生的方式以及开发人员和用户能否采取任何措施来帮助防止此类攻击,可能会有所帮助。幸运的是,Euler的开发者文档清楚地解释了该协议的工作原理,而区块链本身也保存了这次攻击的完整记录。
第一次攻击在第同一个区块中包含了20笔交易。首先,Euler Exploit Contract 1在Aave中以闪电贷款的形式借入了3,000万DAI。然后,它将这笔贷款发送到借款人账户。在收到3,000万DAI后,借款人将其中的2,000万美元存入Euler。作为回应,Euler铸造了大约1,960万eDAI并发送给借款人。这些eDAI硬币是存款的收据,所以在这个过程没有铸造相应数量的dDai。而且,由于每个eDAI都可以兑换略多于一个DAI,因此借款人只收到了1,960万美元而不是完整的2,000万美元。在进行初始存款后,借款人铸造了大约19.57亿eDAI。作为回应,Euler铸造了2亿dDAI并发送给借款人。在这个过程中,借款人接近他们的eDAI铸造上限,因为他们现在借入的DAI是存款金额的10倍左右。所以他们的下一步是偿还一些债务。他们存入了他们持有的另外1,000万美元,实际上偿还了1,000万美元的贷款。作为回应,Euler从借款人的钱包中取走了1,000万dDAI并销毁它,从而减少了借款人的1,000万美元债务。
作为回应,Euler启动了清算过程。它首先从借款人那里取走了约2.54亿dDAI并将其销毁,然后铸造了2.54亿新的dDAI并发送给清算者。这两个步骤将2.54亿美元的债务从借款人转给了清算者。接下来,Euler铸造了额外的5,080万dDAI并发送给清算者。这使清算者的债务达到2.6亿美元。最后,Euler从借款人那里转移了约3.109亿eDAI给清算者,完成了清算过程。最终,借款人剩下没有eDAI,也没有DAI,还有1.46亿美元的dDAI。这意味着该账户没有资产,而有1.46亿美元的债务。另一方面,清算者拥有约3.109亿eDAI和2.6亿美元的dDAI。清算完成后,清算者兑换了3,800万eDAI(价值3,890万美元),得到了3,890万美元DAI作为回报。然后,他们归还了3,000万美元加上利息给Euler Exploiter Contract 1,该合约使用它来偿还从Aave的贷款。最终,清算者剩下约890万美元的利润,这是利用其他该协议用户而获得的。这次攻击重复了对包括wrapped Bitcoin(WBTC)、staked Ether(stETH)和USDC在内的多种代币,总额达到1.97亿美元的加密货币。
Euler Finance是如何工作的
根据协议的官方文档,Euler是一个与Compound或Aave类似的借贷平台。用户可以存入加密货币,并允许协议将其借给其他人,或者他们可以使用存款作为抵押物来借入加密货币。用户的抵押物价值必须始终高于他们所借的金额。假设用户的抵押物价值低于抵押物价值债务价值的具体比率。在这种情况下,平台将允许他们“清算”,这意味着他们的抵押物将被出售以偿还债务。用户所需的抵押物数量取决于所存入的资产与所要借的资产。eToken是资产,而dToken是债务
每次用户存入Euler,都会收到代表存入硬币的eToken。例如,如果用户存入1,000美元硬币(USDC),他们将以相同数量的eUSDC换取。由于存款赚取利息后,eToken的价值会比底层硬币更高,因此eToken在价值上不与底层资产完全对应。Euler还允许用户通过铸造eToken来获得杠杆,但这样做时,协议将发送债务代币(dToken)来平衡所创建的资产。例如,文档中提到,如果用户存入1,000 USDC,他们可以铸造5,000 eUSDC。但是,如果这样做,协议也会发送5,000个名为“dUSDC”的债务代币。dToken的转账功能与标准ERC-20代币编写方式不同。如果您拥有债务代币,您不能将其转让给另一个人,但任何人如果想要的话,都可以从您那里拿走dToken。相关:Liquidity protocol Sentiment被利用,损失超过50万美元
根据Euler文档,用户只能铸造与他们通过重复存入和借款能够铸造的同样数量的eToken一样多的eToken,正如它所陈述的,“铸造函数模仿了用户存入1,000美元USDC,然后借入900美元USDC,然后将这900美元USDC重新存入,再借入810美元USDC,以此类推。”如果健康分数下降到1或以下,用户将被清算
根据Euler的一篇博客帖子,每个用户都有一个基于其钱包中持有的eToken的价值与持有的dToken的价值的“健康分数”。用户需要eToken的价值高于dToken的价值,但多少更多取决于他们正在借人或存入的特定硬币。无论如何,拥有足够eToken的用户将会有一个大于1的健康分数。如果用户几乎低于所需的eToken数量,他们将有一个精确的健康分数为1。这将使他们面临“软清算”。清算机器人可以调用一个功能将用户的一些eToken和dToken转让给自己,直到借款人的健康分数回升到1.25。由于仅略低于抵押要求的使用户仍然拥有比债务更多的抵押物,所以清算机器人应该从这笔交易中获利。如果用户的健康分数下降到1以下,那么根据健康分数有多糟糕,清算机器人会得到相应的增量折扣。健康分数越糟糕,清算机器人获得的折扣就越大。这是为了确保在账户积累太多的坏债务之前,一定会有人进行清算。Euler的帖子声称其他协议提供“固定折扣”用于清算,并辩称为什么它认为可变折扣更优越。攻击如何发生
区块链数据揭示,攻击者进行了一系列攻击,从协议中吸干了各种代币。第一次攻击从Dai(DAI)存款池中耗尽了价值约890万美元的Dai。然后,在耗尽总额之前,重复对其他存款池进行了同样的操作。攻击者使用了三个不同的以太坊地址来进行攻击。第一个是一个智能合约,由Etherscan标记为“Euler Exploit Contract 1”,用于从Aave借入资金。第二个地址用于在Euler存入和借入,第三个地址用于进行清算。为了避免反复声明Etherscan未标记的地址,下面的第二个账户将被称为“借款人”,第三个账户称为“清算者”,如下所示:
相关:Allbridge为被闪电贷款攻击盗取了57.3万美元的攻击者提供赏金
攻击者随后可以继续铸造更多的eDAI。借款人又铸造了1.957亿eDAI,将他们的eDAI铸造总额提高到大约3.914亿。这1,960万的eDAI存款收据使借款人eDAI总额达到约4.11亿。作为回应,Euler又铸造了2亿dDAI并发送给借款人,将借款人的总债务提高到4亿美元。一旦借款人达到了他们eDAI铸造的极限,他们将1亿eDAI发送到零地址,实际上将其销毁。这使他们的健康分数远远低于1,因为他们现在有4亿美元的债务,而资产约为3.2亿美元。这时,清算者账户就派上用场了。它调用了清算功能,将借款人的地址作为要清算的账户。

Euler攻击中的问题是什么
区块链安全公司Omniscia和SlowMist分析了攻击,试图确定可以防止该攻击的事情。根据Omniscia 3月13日的一篇报告,Euler的主要问题是其“donateToReserves”功能。这个功能允许攻击者向Euler储备金捐赠他们的eDAI,从他们的钱包中去除资产,而不减少相应数量的债务。Omniscia表示,此功能不在Euler的原始版本中,而是在Euler改进计划14(eIP-14)中引入的。eIP-14的代码揭示了它创建了一个名为donateToReserves的功能,允许用户将余额中的代币转移到协议变量“assetStorage.reserveBalance”。每当调用此功能时,合约都会发出一个“RequestDonate”事件,提供有关交易的信息。区块链数据显示,“RequestDonate”事件以1,000万代币的数值发出。这正是Etherscan显示被烧毁的数值,将账户推向破产。相关:Euler团队否认在黑客案件中是被怀疑的对象
在3月15日的一份分析中,SlowMist同意了Omniscia对donateToReserve功能重要性的观点,表示:联系到Euler团队以了解攻击者是否能够将他们的eToken转让给另一个用户或零地址,而不是捐赠。作为回应,公司的一位代表告诉我们,这是不可能的,因为“转让EToken总是执行健康检查。”代表指出,EToken.sol合约的第345行调用了checkLiquidity函数。“Omniscia及其合作者是正确的,此检查也应在donateToReserves函数中执行,”代表说。