T 123,406.134999 – USDC 844,282.284002229528476039 – HOPE 220,617.821736563540747967 – stHOPE 这些代币被作为收益通过 Uniswap 兑换为 WBTC 和 WETH,扣除各种费用后,最终黑客获利为约 263 枚 WETH(除去贿赂 payload 的 263.9 枚 WETH)。 为什么黑客可以从其他池子借走大量资金: 借款或取走存款时,借贷合约会检验用户的抵押资产状况,确保借出不超过抵押。 由于之前贴现率已被黑客操纵且贴现率会以 normalizedIncome 乘数计入抵押价值计算,其手中的一单位 hEthWBTC 抵押价值高达 75.6WBTC。 每一次从其他池借款,黑客都轻松通过了抵押资产校验。 此时, 攻击者总共在 HopeLend 投入了 2000+1.8*60 枚 WBTC 用于操纵 liquidityIndex,只留存了 1 单位的 hEtthWBTC。 利用关键漏洞点(整数除法错误)套现 为了取出之前的投入 wBTC,攻击者部署了另一个攻击合约:0x5a63e……844e74,并调用其中的 withdrawAllBtc() 方法: 漏洞过程如下: 首先存入 151.20000002 枚 wBTC,根据当前的 liquidityIndex(1 最小单位 hEthWBTC=75.6wBTC),攻击者获得 2 个最小单位的 hEthWBTC。 取出(withdraw)113.4 个 wBTC,反算出其对应的 hEthWBTC 份额,对 hEthWBTC 进行 burn 操作。 113.4 个 wBTC 需要销毁 1.9999999998 最小单位的的 hEthWBTC,但是由于 div 函数精度问题,仅一个最小单位的 hEthWBTC 被销毁,因此变成可被利用的漏洞,黑客仍可保留 1 个最小单位的 hEthWBTC。 关键漏洞 hEthWBTC 的 burn 方法调用了高精度除法 rayDiv。 此处: a=11340000000(打算取出的 WBTC) b=7560000001000000000000000009655610336(贴现率) 虽然 (a*1e27+b/2)/b = 1.9999999998,solidity 自带的 div 方法截断返回 1, 相当于 11340000000 / 7560000001 除法后小数位被截断了。 0x5a63( 攻击合约 – 套现 ) 继续存入 75.60000001WBTC 恰好又获得 1 个最小单位 hEthWBTC,从而继续持有 2 个最小单位 hEthWBTC。 如此循环取出 113.40000000wBTC,存入 75.60000001wBTC 的操作,每次攻击者可以凭空获取 37.8 枚 wBTC。 循环 58 次后,攻击者取出了所有前期投入的 wBTC ,并顺利归还 Aave 的闪电贷。 结论 由于 hEthWBTC 借贷池未被初始化,攻击者得以轻易操纵 liquidityIndex,将其增至极大,提现率作为除数极大放大后,由于整数除法的截断误差,使得取出之前的投入更容易在一个区块内实现。 在运转良好的借贷池中,由于池中已有流动性,不容易因为少量的贷款利息增加而极大增加贴现率。 来源:金色财经lg...