概述
2023年4月13日,YearnFinance遭到黑客攻击,导致大约损失1000万美元。本文将分析攻击过程以及漏洞产生的原因。
攻击分析
这是一笔攻击交易:
https://etherscan.io/tx/0xd55e43c1602b28d4fd4667ee445d570c8f298f5401cf04e62ec329759ecda95d
攻击者从Balancer发起了闪电贷,借了500万DAI、500万USDC和200万USDT:
然后在Curve上,攻击者将500万DAI兑换成了695,000USDT,并将350万USDC兑换成151USDT:
攻击者调用IEarnAPRWithPool的recommend函数来检查当前的APR。此时,只有Aave的APR不等于0:
Lightyear获2500万美元A轮融资:金色财经报道,英国金融科技公司Lightyear在由 Lightspeed Venture Partners 领投的一轮融资中筹集了 2500 万美元。 本轮融资的其他投资者包括 Richard Branson 的 Virgin Group、Mosaic Ventures、Taavet+Sen 和 Metaplanet。 该公司还宣布进军 19 个欧盟国家。(The Block)[2022/7/14 2:13:35]
接下来,攻击者将800,000USDT转移到了攻击合约0x9fcc1409b56cf235d9cdbbb86b6ad5089fa0eb0f中。在该合约中,攻击者多次调用了Aave:LendingPoolV1的repay函数,帮助其他人偿还债务,以使Aave的APR等于0:
攻击者调用了yUSDT的deposit函数,抵押了900,000USDT,并获得了820,000yUSDT:
接下来,攻击者调用了bZxiUSDC的mint函数,使用156,000USDC铸造了152,000bZxiUSDC,并将其转移到了YearnyUSDT:
yearn.finance宣布yDAI保管库已恢复:2月9日消息,yearn.finance官方发推表示,yDAI保管库已恢复,Yearn与YFI共同开设一个制造商保险库,铸造970万个DAI,并使yDAI Vault完整。这是一次“有仪式的庆祝活动”,不要指望它再次发生,下次一定要确保购买保险。[2021/2/9 19:20:56]
攻击者调用Yearn:yUSDT的withdraw函数,将820,000yUSDT兑换成1,030,000USDT。此时,合约中只剩下攻击者转移的bZxiUSDC:
接下来攻击者调用Yearn:yUSDT的rebalance函数,销毁bZxiUSDC:
然后攻击者向yUSDT合约转移了1/e6个USDT,并调用了deposit函数,抵押了10,000USDT,获得了1,252,660,242,850,000yUSDT:
慢雾:yearn攻击者利用闪电贷通过若干步骤完成获利:2021年02月05日,据慢雾区情报,知名的链上机池yearnfinance的DAI策略池遭受攻击,慢雾安全团队第一时间跟进分析,并以简讯的形式给大家分享细节,供大家参考:
1.攻击者首先从dYdX和AAVE中使用闪电贷借出大量的ETH;
2.攻击者使用从第一步借出的ETH在Compound中借出DAI和USDC;
3.攻击者将第二部中的所有USDC和大部分的DAI存入到CurveDAI/USDC/USDT池中,这个时候由于攻击者存入流动性巨大,其实已经控制CruveDAI/USDC/USDT的大部分流动性;
4.攻击者从Curve池中取出一定量的USDT,使DAI/USDT/USDC的比例失衡,及DAI/(USDT&USDC)贬值;
5.攻击者第三步将剩余的DAI充值进yearnDAI策略池中,接着调用yearnDAI策略池的earn函数,将充值的DAI以失衡的比例转入CurveDAI/USDT/USDC池中,同时yearnDAI策略池将获得一定量的3CRV代币;
6.攻击者将第4步取走的USDT重新存入CurveDAI/USDT/USDC池中,使DAI/USDT/USDC的比例恢复;
7.攻击者触发yearnDAI策略池的withdraw函数,由于yearnDAI策略池存入时用的是失衡的比例,现在使用正常的比例体现,DAI在池中的占比提升,导致同等数量的3CRV代币能取回的DAI的数量会变少。这部分少取回的代币留在了CurveDAI/USDC/USDT池中;
8.由于第三步中攻击者已经持有了CurveDAI/USDC/USDT池中大部分的流动性,导致yearnDAI策略池未能取回的DAI将大部分分给了攻击者9.重复上述3-8步骤5次,并归还闪电贷,完成获利。参考攻击交易见原文链接。[2021/2/5 18:58:47]
Yearn.Finance:YIP-51提案更改费用结果仅针对v2版本yVault有效:Yearn.Finance官方刚刚发推称,针对已经通过的YIP-51治理提案需要作出几点澄清:YIP-51提案会影响即将发布的v2版本的yVault费用,包括提现费用。v1版本(目前部署)yVault并没有改变其费用结构,仍然需要0.5%的提现费用。[2020/11/11 12:16:11]
然后在Curve上,攻击者将70,000yUSDT兑换成5,990,000yDAI,将4亿yUSDT兑换成4,490,000yUSDC,将1,240,133,244,352,200yUSDT兑换成1,360,000yTUSD:
然后在yearn:yDAI和yearn:yUSDC中分别调用withdraw,提取678万个DAI和562w万个USDC,并归还闪电贷:
漏洞分析
这次攻击中最关键的一点,是攻击者使用100,000USDT铸造了1,252,660,242,850,000个yUSDT。查看deposit函数的实现:
yearn.finance:创建veCRV只允许受批准的钱包:8月2日消息,yearn.finance发推表示:目前yearn.finance已经有142346veCRV的配额,Curve让我们知道如何成为受批准的智能钱包。创建veCRV必须使用受批准的智能钱包。
Curve对此回复道:需要一份合约来检查受批准的智能钱包,以及一份治理提议来设置这个检查器。[2020/8/24]
可以看到share的数量和变量pool相关,pool越小,share越大,而pool的值由_calcPoolValueInToken获得:
攻击者在调用rebalance函数后,合约中只存在了USDC,但是_balance()获取的是USDT的余额,USDC的余额并不计入其中,因此此时的pool为1:
这里显然是项目方的配置错误,yUSDT合约中应当都是USDT类的代币,但是其fulcrum变量却是USDC相关的bZxIUSDC代币,因此yUSDT中的USDC不计入balance中:
攻击者为什么能调用rebalance函数来burn掉bZxiUSDC代币呢?查看rebalance函数的实现:
可以看到在_withdrawFulcrum()中会存在redeem和burn操作,因此我们需要让"newProvider!=provider"成立,其中recommend()的实现:
攻击者通过控制IIEarnManager(apr).recommend(token)的返回值,使其为都为0来操控newProvider:
如何让其都为0呢,该函数的返回值和计算出的各个DeFi中的APR相关,由于Compound,bZx,dydx中没有池子,因此只需要控制Aave(Aave:LendingPoolCoreV1)即可:
要使其值返回为0,需要让apr.calculateInterestRates函数的第一个返回值为0:
即让currentLiquidityRate为0,该值和_totalBorrowsStable、_totalBorrowsVariable相关,当这两个个值都为0时,currentLiquidityRate为0:
_totalBorrowsVariable为0,即Aave:LendingPoolCoreV1此时没有人存在债务,为了达成这个条件,攻击者将池中所有人的债务进行了repay:
最后,攻击者让_totalBorrowsVariable变为0,所以它能够调用rebalance函数burn掉bZxiUSDC代币:
总结
此次Yearn攻击事件的根本原因是项目方的配置错误。攻击者通过一系列精妙的手法利用了该漏洞,最终获利大约1000万美元。
关于我们
AtEoceneResearch,weprovidetheinsightsofintentionsandsecuritybehindeverythingyouknowordon'tknowofblockchain,andempowereveryindividualandorganizationtoanswercomplexquestionswehadn'tevendreamedofbackthen.
了解更多:Website|Medium|Twitter
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。