超 1900 枚 ETH 被盗,Radiant Capital 如何被黑客「摸底」盗取 450 万美元
2024 年 1 月 3 日,Radiant Capital 项目遭受攻击者闪电贷攻击,攻击者通过 3 笔交易盗取了超 1900 枚 ETH,价值超 450 万美元,目前被盗资金还保存在攻击者地址。
撰文:Beosin
2024 年 1 月 3 日,据 Beosin 旗下 EagleEye 安全风险监控、预警与阻断平台监测显示,Radiant Capital 项目遭受攻击者闪电贷攻击。攻击者通过 3 笔交易,盗取了超 1900 枚 ETH,价值超 450 万美元,目前被盗资金还保存在攻击者地址,Beosin 安全团队第一时间对本次事件进行了分析。
漏洞分析
该事件发生的根本是由于 Radiant Capital 项目在计算代币数量的过程中,使用了精度扩展,并且采用了四舍五入的方式进行计算,导致攻击者可以通过控制精度大小,并结合四舍五入扩大利润点来进行攻击。
观察上述代码,rayDiv 函数传入两个 uint256 数据 a 和 b,整个过程可以简写为 (a*RAY+b/2)/b,其中 RAY 是精度扩展数据,为 10^27,那么该结果相当于 a*RAY/b+0.5,实现四舍五入的功能,而该计算方式误差主要来源于 b,如果 b 相对于 a 来说极小,那么误差将可忽略不计,但如果 b 于 a 拥有相同数量级,那么误差可能达到 a 本身。
举个例子:如果 a*RAY=10000,b=3,那么计算出来结果为 3333,比实际值小了 1/10000;而如果 a*RAY=10000,b=3000,计算出来的结果为 3,比实际值小了 1/10。
此次事件便是攻击者操控 b 的值,让 b 值与 a 值拥有相同数量级,使得计算等价于 3/2.0001=1,计算值比实际值减小 1/3。
攻击流程
让我们来看看黑客的攻击流程:
1.攻击者首先通过 AAVE 闪电贷借贷了 300 万枚 USDC,用于攻击启动资金。
2.攻击者将 200 万枚 USDC 质押到 Radiant 合约,并获得了 200 万枚 rUSDCn 凭证代币。
3.攻击者通过 Radiant 合约进行闪电贷,借贷 200 万 USDC,并在回调函数中将 200 万 USDC 归还,同时将第二步质押的 USDC 提取出来,最后闪电贷函数会调用 transferfrom 函数连本带利的将攻击者的 USDC 转入合约。此时会收取 9/10000 的手续费,而收取的手续费便成为了池子的流动性。
4.攻击者通过多次重复步骤 3 的操作,将 liquidityIndex 控制得很大,liquidityIndex=271800000000999999999999998631966035920。
5.接下来,攻击者新建了一个合约,并向其中打入 54.36 万 USDC,因为 5436(USDC 数值 ) 正好是步骤 4 中 2718(liquidityIndex 数值 ) 的两倍,可方便进行四舍五入控制。
6.攻击者将 54.36 万 USDC 全部抵押进 Radiant 合约,并获得相同数量的 rUSDCn。
7.攻击者提取 40.77 万 USDC,本应该销毁 40.77 万 rUSDCn,但如上所述,burn 函数进行了精度扩展与四舍五入计算。
407700000000000000000000000000000000000/271800000000999999999999998631966035920=1.49999999,而四舍五入结果为 1,导致结果偏小了 1/3。
如下图,本该销毁 40.77 万,但还剩 27.18 万,说明只销毁了 27.18 万,攻击者便提取了 40.77 万 USDC。
8.攻击者利用第七步的漏洞,重复质押提取操作,并且提取始终比质押数量多 1/3,最终将池子里的 USDC 全部兑换出来。
资金追踪
截止发稿,被盗的 1902 枚 ETH 一直存在黑客地址未移动,Beosin Trace 将对资金进行持续监控。
随着 2024 年的开启,我们已目睹了两起大金额的被盗案件的发生。(昨日安全事件回顾:开年第一案,被盗 8000 万美元的 Orbit Chain 事件是怎么一回事?)这一系列的事件再次提醒了我们,在 Web3 生态系统中,安全防范仍然是至关重要!
本站提醒:投资有风险,入市须谨慎,本内容不作为投资理财建议。