区块链技术博客
www.b2bchain.cn

区块链技术慢雾:在defi贷款协议alchemix中的aleth合同漏洞事件的技术细节

第20439篇区块链技术文章区块链技术慢雾:在defi贷款协议alchemix中的aleth合同漏洞事件的技术细节

事故发生的主要原因是,阿尔希米通过Transmuter三次添加故障,最终导致通过错误的元素获得错误的利益

原题:“最长的路是我自己的套路——阿尔希米事件分析”
作者:于丹,在慢雾安全团队工作

据慢雾地区新闻报道,2021年6月16日,以太坊defi项目中alchemix的aleth合同被怀疑存在安全问题。17日,alchemix发布事故分析报告,慢雾安全小组迅速介入分析。在官方分析报告的基础上,梳理了整个事件的来龙去脉和关键点,供大家参考

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

太长了,不要看这个系列

这篇分析文章很长。让我们从结论开始,这样我们才能有一个大致的了解。这起事故的主要原因是alchemix通过Transmuter添加了三次故障,导致收入信息记录在错误的元件上。调用Transmuter的harvest函数时,没有传入正确的索引值,导致通过错误的元素获取错误的收入,并将错误的4300eth收入发送给适配器合同,帮助用户偿还aleth的贷款,导致收入增加的问题,导致悲剧的原因根据官方的事故分析报告,这次事故的原因是官方的aleth部署脚本意外地创建了额外的保险库,导致alchemix在保险库数组中使用了错误的索引并计算了错误的奖励,使Transmuter使用所有奖励来偿还用户的所有债务。我知道这个简单的分析有点混乱,所以我们只能把重点放在官方交易上,看看是否能根据官方交易找到真相,通过分析工具ethtx.info,不难发现这个交易调用了炼金术士契约的收获函数,并传入参数vaultid=0返回
“4308144937764982868765”和“4308144937764982866415”的值,以便更好地理解收获函数的功能,我们需要分析整个函数:

核心分析——Round 1

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

不难发现,收获函数实际上包含两个重要的操作,即收获报酬和将报酬分配给转化者契约。其中,金库是一个库合同,收货逻辑如下:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

通过代码分析不难发现,金库合同的收货功能实际上是检查外部适配器的资金总量,然后根据适配器中的资金量减去用户的充值次数来计算收入这里,我们可以将此适配器理解为一个策略池,用于管理用户的资金和收益。然后我们回到alchemiseth契约中用户开始时的收获函数,并发现“4308144937764982868765”和
“4308144937764982866415”的返回值实际上对应于要提取的令牌数和要从适配器(策略池)检索的令牌数,这些令牌数是由保险存储合同的收获函数计算的。由于与该适配器对应的令牌是精度为18位的weth,因此“4308144937764982866415”被转换为“4308.144937764982866415”weth

,换句话说,在该收获操作中获得了4300 eth以上的收入,然后在下一步中传递收入。DistributeTomuter函数给出要分配的Transmuter合同。让我们来看看分布过程的逻辑:

为了理解为什么要增加4300以太币,我们必须了解炼金术士的资本储存过程。在炼金术士合同中,合同的总补给量是使用金库库的数据结构记录的,然后通过flushactive vault函数更新相应的总存款,然后depositall函数将充值的令牌金额键入相应的适配器(策略池)。然后,在下一次收获中,通过适配器(策略池)获得的总价值将是用户的本金加上策略池的收入。为了计算收益过程中的主体,我们调试了官方交易,发现主体只有9000 eth,适配器加上主体的收益是13000 eth,也就是说,9000 eth的主体产生4300 eth,按照上述分析的逻辑,用户的委托人不会产生那么多收益,问题一定是适配器获得的总价值。也就是说,适配器不仅有炼金术士充值令牌,还有其他收入渠道。为了验证我们的想法,慢雾安保团队对适配器的所有代币收入进行了分析,发现了一个异常的转入行为,金额刚好可以匹配4300 eth的收入。也就是说,这就是问题所在:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

通过查看事务数据,发现这是一个调用收获操作的事务,调用的契约是一个Transmuter契约:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

也就是说,收获函数有问题,收获函数的逻辑如下:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

也调用了vault的收获函数,熟悉公式,熟悉口味。我们再次调试,发现了一个惊人的事实:当我们获得收入时,保险库的总存款为0,这导致4300 eth的收入直接分配给适配器。结果,适配器获得的总值是错误的,还有4300 eth。这就是为什么这里,我们非常接近真相,剩下的问题就是为什么总存款是0?我们检查了Transmuter合同,在合同中我们可以更改总存款,发现只有plantorrecallexcessfunds函数可以更改此值,此函数的上层调用distribute函数。转化者契约的分配函数在收益时被炼金术士契约调用。也就是说,进程本身应该是:

但问题是uplantorrecallexcessfunds函数。因为在记录充值信息时,我们使用 Last()获取最新的保险库,所以充值信息会叠加在最后一个元素上。但是项目方调用了三次setactivevault函数,所以充值信息被叠加在了vaults数组的第三个元素上,即索引为2的vault元素上。但是Transmuter合同是在harvest时传入的,vaultid为0。元素0没有充值记录,所以Transmuter合同错误地把所有收入都给了适配器。它导致了悲剧,到现在,整个事情已经变得非常清楚了。由于某种原因,alchemix项目方通过Transmuter添加了三次保险库,导致收入信息记录在一个错误元素中,调用Transmuter的收获函数时没有传入正确的索引值,导致通过错误的元素获得错误的收入,而错误的收入被发送到适配器合同,导致收入的增加和悲剧

慢雾安保团队提醒我们,defi是一个复杂的系统。在执行defi操作时,我们应该记住检查业务逻辑中的每个流程,以防止发生意外。必要时,我们可以联系专业的安全团队进行专业的安全审核,以防止事故发生

参考链接

官方事故分析报告:
https://forum.alchemix.fi/public/d/137-incident-report-06162021

核心分析——Round 2

收入计算错误交易
https://etherscan.io/tx/0x3cc071f9f40294bb250fc7b9aa6b2d7e6ca5707ce4d6d222157d7a0feef618b3

来源链接:mp.weixin.qq.com

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

然后 depositAll 函数会将充值的代币金额打到对应的 adapter(策略池) 中,那么在下一次 harvest 的时候,通过 adapter(策略池) 获取的 totalValue,就会是用户的本金加上策略池的收益。为了计算收益过程中的本金部分,我们对官方给出的交易进行 debug,发现本金仅为 9000 ETH,从 adapter 获取的收益加上本金共有 13000 ETH,也就是说 9000 ETH 的本金产生了 4300 ETH 的收益。

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

但是,按照上面分析的逻辑,用户的本金是不会产生那么大的收益的,问题肯定是出在了 adapter 获取的 totalValue。也就是说 adapter 不止只有 AlchemistEth 充值代币,还存在其他的收益渠道。为了验证我们的想法,慢雾安全团队分析了 adapter 的所有代币收入,果然发现了一笔异常的转入行为,并且金额也能刚好对上多出的 4300 ETH 的收益。也就是说,问题就在这里了。

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

通过查看交易数据,发现这是一笔调用 harvest 操作的交易,调用的合约是 transmuter 合约:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

也就是说,是这个 harvest 函数出问题了,harvest 函数的逻辑如下:

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

同样是调用了 vault 的 harvest 函数,熟悉的配方,熟悉的味道。我们再次进行 debug,发现一个惊人的事实 ——在进行收益的时候,vault 的 totalDeposit 竟然为 0,导致 4300 ETH 的收益直接分发给了 adapter,导致了 adapter 获取的 totalValue 错误了,多了 4300 个 ETH,原因就是在这里。

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

到了这里,我们已经很接近真相了,剩下要解决的就是为什么 totalDeposit 会为 0?我们查询了 transmuter 合约中能改变 totalDeposit 的地方,发现只有 _plantOrRecallExcessFunds 函数可以改变这个值,而这个函数上层调用的又是 distribute 函数。而 transmuter 合约的 distribute 函数是 AlchemistEth 合约在收益的时候进行调用的。也就是说本身的流程应该是:

  1. AlchemistEth 合约调用 harvest 进行收益
  2. AlchemistEth 合约调用 transmuter 合约的 distribute 函数记录收益情况,并把收益部分给 adapter
  3. adapter 收到了 transmuter 的收益,根据收益偿还用户的 alETH 的贷款

但是问题就出在了 _plantOrRecallExcessFunds 函数中。由于在记录充值信息的时候,用的是 _vaults.last() 来获取最新的 vault,所以其实充值信息叠加在了最后一个元素上。但是项目方调用了三次 setActiveVault 函数,所以其实充值信息是叠加到了 _vaults 数组的 3 号元素,也就是 index 为 2 的 vault 元素上。但是在 transmuter 合约在 harvest 的时候传入的 _vaultId 却是 0,0 号元素是没有任何充值记录的,所以 transmuter 合约就误将所有的收益都给了 adapter 了。导致了悲剧的发生。

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

慢雾:技术详解 DeFi 借贷协议 Alchemix 中 alETH 合约漏洞事件

总结

到这里,整个事情已经变得很清晰了,Alchemix 项目方由于某种原因,通过 transmuter 添加了 3 次 vault,导致收益信息记录在了一个错误的元素上,而在调用 transmuter 的 harvest 函数时也没有传入正确的 index 值,导致通过错误的元素获取了错误的收益,错误收益被发送到 adapter 合约,造成收益增多,导致了悲剧。

慢雾安全团队在此提醒,DeFi 是一个复杂的系统,在进行 DeFi 操作的时候,要记得检查好业务逻辑中的每一个流程,防止意外的发生,在必要的时候可以联系专业的安全团队进行专业的安全审计,防止事故的发生。

参考链接

官方事故分析报告:
https://forum.alchemix.fi/public/d/137-incident-report-06162021

收益计算错误交易
https://etherscan.io/tx/0x3cc071f9f40294bb250fc7b9aa6b2d7e6ca5707ce4d6d222157d7a0feef618b3

来源链接:mp.weixin.qq.com

区块链技术慢雾:在defi贷款协议alchemix中的aleth合同漏洞事件的技术细节 由www.b2bchain.cn 提供
文章整理自网络,只为个人学习与分享使用
链接地址https://www.b2bchain.cn/20439.html

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 区块链技术慢雾:在defi贷款协议alchemix中的aleth合同漏洞事件的技术细节
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们