mt logoMyToken
总市值:
0%
恐慌指数:
0%
币种:--
交易所 --
ETH Gas:--
EN
USD
APP
Ap Store QR Code

Scan Download

Cream 被盗 1.3 亿美金始末:利用借贷池缺陷,恶意操控价格

收藏
分享

原文标题:《DeFi 平台 Cream Finance 再遭攻击,1.3 亿美金被盗》

2021 年 10 月 27 日,Cream Finance 再次遭受攻击,损失约 1.3 亿美金, 慢雾安全团队 第一时间介入分析,并将简要分析分享如下。

攻击核心

本次攻击的核心在于利用 Cream 借贷池对抵押物价格获取的缺陷,恶意操控拉高了其抵押物的价格,使得攻击者可以从 Cream 借贷池借出更多的代币。

攻击细节

首先攻击者从 DssFlash 中闪电贷借出 5 亿个 DAI,随后将借出的 5 亿个 DAI 抵押至 yearn 的 yDAI 池中,以获得约 4.5 亿个 yDAI 凭证。

 

借贷

 

随后攻击者将获得的 yDAI 代币在 Curve 的 yDAI/yUSDC/yUSDT/yTUSD 池子中进行单币流动性添加,以获得相应的流动性凭证。紧接着攻击者就将获得的凭证抵押到 yvWBTC 池子中以获得 yUSD 凭证,为后续在 Cream crYUSD 借贷池中抵押做准备。

 

借贷

 

之后攻击者开始向 Cream 的 crYUSD 借贷池中抵押其获得 yUSD 凭证,为了扩大其抵押规模,攻击者从 AAVE 闪电贷借出约 52.4 万个 WETH,并将其抵押到 Cream 的 crETH 池子中。

 

借贷

 

攻击者通过在 crETH 池子中抵押大量 ETH,来使得其有足够的借贷能力将 crYUSD 池子中的 yUSD 全部借出并重复抵押到 crYUSD 池子中,随后通过在 crYUSD 池子中进行循环贷以杠杆的形式扩大了本身在 crYUSD 池子中 yUSD 的抵押规模,为后续操控价格获利做准备。

 

借贷

 

随后为了获得 yDAI/yUSDC/yUSDT/yTUSD 4Pool 凭证以操控价格,攻击者用约 1,873 个 ETH 从 Uniswap V3 中兑换出约 745 万个 USDC,并通过 Curve 3Pool 将其兑换成 DUSD 代币约 338 万 个。

 

借贷

 

接下来攻击者通过获得的 DUSD 代币从 YVaultPeak 中赎回

yDAI/yUSDC/yUSDT/yTUSD 4Pool 凭证,并利用此凭证从 yUSD(yvWBTC) 池子中取回 yDAI/yUSDC/yUSDT/yTUSD 代币。

 

借贷

 

随后攻击者开始进行此次攻击的 关键操作 ,其将约 843 万个 yDAI/yUSDC/yUSDT/yTUSD 代币直接转回 yUSD 池子中,由于其不是通过正常抵押操作进行抵押的,所以这 843 万个 yDAI/yUSDC/yUSDT/yTUSD 代币并没有被单独记账,而是直接分散给了 yDAI/yUSDC/yUSDT/yTUSD 凭证的持有者,这相当于直接拉高了其 share 的价格。

 

借贷

 

在 crToken 中由于其抵押物价格被恶意拉高了,因此攻击者抵押的大量 yUSD 可以使其借出更多的资金,最后攻击者将 Cream 的其他 15 个池子全部借空。接下来我们跟进 Cream 的 crToken 借贷池中具体借贷逻辑。

从 cToken 合约中我们可以看到,主要借贷检查在 borrowAllowed 函数中:

 

借贷

 

我们跟进 borrowAllowed 函数,可以看到在 427 行,其会根据

getHypotheticalAccountLiquidityInternal 函数检查实时状态下的该账户所对应的所有 cToken 的资产价值总和和借贷的资产价值总和,并通过对比 cToken 的资产价值和借贷的 Token 价值和,来判断用户是否还可以继续借贷。

 

借贷

 

我们跟进

getHypotheticalAccountLiquidityInternal 函数,可以发现对于抵押物的价值获取来自 886 行的 oracle.getUnderlyingPrice。

 

借贷

 

我们跟进预言机的 getUnderlyingPrice 函数,可以容易的发现其将通过代币 150 行的 getYvTokenPrice 函数进行价格获取。

 

借贷

 

继续跟进 getYvTokenPrice 函数,由于 yvTokenInfo.version 为 V2,因此将通过 yVault 的 pricePerShare 函数进行价格获取。

 

借贷

 

借贷

 

借贷

 

跟进 pricePerShare 可以发现其直接返回了 _shareValue 作为价格,而 _shareValue 是通过 _totalAssets 除合约的总 share 数量(self.totalSupply) 来计算单个 share 的价格的。因此攻击者只需要操控 _totalAssets 将其拉高就可以提高单个 share 的价格从而使得攻击者的抵押物价值变高以借出更多的其他代币。

 

借贷

 

借贷

 

我们可以查看下 _totalAssets 是如何获取的,从 772 行我们可以很清晰的看到,_totalAssets 是直接取的当前合约的 yDAI/yUSDC/yUSDT/yTUSD 代币数量,以及抵押在策略池中的资产数额相加获得的。因此攻击者通过直接往 yUSD 合约中转入 yDAI/yUSDC/yUSDT/yTUSD 代币就可以拉高 share 价格从而完成获利。

 

借贷

 

通过 Ethtx.info 可以清晰的看到 pricePerShare 前后变化:

 

借贷

 

最后攻击者在借空其他池子后归还了闪电贷获利离场。

总结

本次攻击是典型的利用闪电贷进行价格操控,由于 Cream 的借贷池在获取 yUSD 池子 share 价格时直接使用了其 pricePerShare 接口,而此接口是通过合约的抵押物余额与策略池抵押资产数额相加除总 share 数来计算单个 share 的价格的。因此用户直接往 yUSD 转入抵押物就可以很容易的拉高单个 share 价格,最终使得 Cream 借贷池中抵押物可以借出更多的资金。

免责声明:本文版权归原作者所有,不代表MyToken(www.mytokencap.com)观点和立场;如有关于内容、版权等问题,请与我们联系。