2023年4月16日,作为Compound V2的一个分支Hundred Finance遭遇攻击,损失约740万美元。攻击涉及两个主要问题:
- 精度损失问题(错误的四舍五入问题);
- 空市场,这使得黑客能够操纵兑换率。
根据DeFiLlama的数据,Compound V2是分叉最多的借贷协议,拥有超过100个分叉。其合约经过OpenZeppelin的审计,并在实战中得到验证,被认为是安全的。然而,Hundred Finance的攻击凸显了精度损失(尤其是在低流动性环境下)可能严重影响DeFi协议的安全性,并在Midas和Radiant等知名分叉协议中引发了一系列类似漏洞利用。
为了更深入地了解,我们鼓励您阅读完整的分析。下面,我们将对此次事件进行简要介绍,并将其列为2023年十大安全事件之一。
背景
Hundred Finance概述
Hundred Finance是Compound v2的一个分支,运行在多个主网上,并使用Chainlink预言机。与传统金融的借贷实践不同,Compound和Aave等DeFi借贷协议不允许过度抵押借款。 简单来说,如果您存入价值100美元的Token A,您最多只能借出价值不到100美元的资产。根据大多数协议的风险控制系数,这个比例通常在50%到80%之间。
对于借贷协议而言,常见的攻击手段包括价格操纵和重入攻击。有趣的是,Hundred Finance曾在2022年3月经历过一次重入攻击,但此次事件创造了一种新的攻击向量。
hToken
从Compound和Aave分叉出来的借贷协议会为每个基础代币(抵押品)创建一个相应的记账代币。对于Hundred Finance:
- USDC对应hUSDC
- WBTC对应hWBTC
基础代币与hToken之间的兑换率称为exchangeRate。
- 存款时,用户应调用hToken的
mint()函数。 - 提款时,用户应调用hToken的
redeem()函数。
exchangeRate
以下是计算exchangeRate的公式:

其中:
getCash():此hToken合约持有的基础代币余额。这是一个关键的可操纵参数,请牢记。totalBorrows():市场上当前借出的基础代币数量,也是计算对市场供应商利息的基础数量。totalReserves():每个hToken合约中的一个记账项,代表一部分历史利息,作为现金储备,可以通过协议治理提取或转移。totalSupply():此hToken市场当前流通的代币数量。
注意:hToken与基础资产之间的exchangeRate(例如,dai与hDai或eth与hEth)初始值为0.020,并以市场复利利率的增长率增长。
清算
为防止坏账,借贷协议允许任何用户清算其他用户的债务。我们用以下例子来说明:
- Alice存入价值100美元的BTC,并借入价值70美元的ETH。
- 如果ETH价格上涨或BTC价格下跌,Alice的资产可能会达到清算阈值。
- Bob可以用一定数量的ETH来清算Alice的BTC,将Alice的债务恢复到健康水平,以确保协议资金的安全(协议会奖励发起清算的用户的)。
清算并非此次攻击的重点,但却牵涉其中。 这里我们只需要知道,任何用户都可以用一种代币清算另一个用户的债务,这将减少相应的hToken。
漏洞
精度损失问题
黑客利用在通过redeem()提取抵押品时,计算要扣除的hToken数量出现了1.99999992(非常接近2但小于2)。在truncate()中转换为整数时,向下取整导致最终结果为1。

exchangeRate
如前所述,exchangeRate的计算涉及getCash(),即hToken合约持有的基础代币余额。通过直接将基础代币转入合约(不通过mint,仅转账),黑客可以操纵exchangeRate。
然而,需要注意的是,仅凭此exchangeRate问题本身并不能危及协议安全;黑客无法单独从中获利。 在此次攻击中,它主要被用来放大黑客的收益,使其能够迅速耗尽资金池。否则,攻击将从一次决定性的打击变成一系列微小的消耗,需要多次迭代才能产生显著影响。
简而言之,精度损失是此次攻击的关键问题。
攻击过程
以下是攻击交易,我们将使用Phalcon Explorer来分析这笔复杂的交易。
交易:0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451
-
通过Flashloan从Aave V3借入500 WBTC。
-
Redeem之前获得的所有hWBTC,将hWBTC的totalSupply重置为0。
之前的目标是利用闪电贷准备储备金,并将hWBTC重置为一个新市场。
-
Create第二个攻击合约(以下称为攻击合约2),并将所有WBTC(500.30063816 WBTC)转入攻击合约2。
-
使用4 WBTC
Mint()hWBTC,产生200 hWBTC。 -
Redeem()199.99999998 hWBTC,剩余hWBTC总量为0.00000002(2 wei hWBTC)。 -
将所有WBTC(500.30063816 WBTC)转入hWBTC。请注意,直接转账不会增加hWBTC;这可以视为向资金池捐赠WBTC。此步骤的主要目的是操纵前面提到的
exchangeRate。此时,hWBTC的totalSupply仍为2 wei hWBTC,但现在有500.30064194 WBTC,使得exchangeRate比原来的高出数百倍。

-
从hETH市场借入1021 Ether。
-
Redeem()50030063815 WBTC,经过计算,应扣除1.9999992 hBTC,但由于精度损失,仅扣除1 hBTC,造成了巨大的精度损失(近50%)。
此时,黑客拥有500 WBTC + 1021 Ether,成功获利1021 Ether。 -
攻击者
liquidate()剩余的hWBTC,将其totalSupply重置为0,以便继续攻击其他市场。鉴于hWBTC中的几乎所有WBTC都已被提取,黑客仅用0.000002 Ether就完成了此操作。
-
继续攻击其他市场,耗尽整个协议。
-
偿还Aave的闪电贷。
安全建议
借贷协议的缓解措施
此问题在Compound和Aave的分叉协议中尤为普遍。积极主动的方法包括,在启动新市场时,铸造一些记账代币以确保totalSupply永远不会为0。
精度损失问题的缓解措施
为了更好地规避因精度损失导致的一系列问题,设置一个最小值是一个有效的实际方法。这种策略有助于避免在处理极小数值时因精度损失造成的重大影响。
阅读本系列其他文章:
- 导语:2023年十大“精彩”安全事件
- #1:利用Flashbots Relay中的漏洞 Harvesting MEV Bots
- #2:Euler Finance事件:2023年最大规模的黑客攻击
- #3:KyberSwap事件:通过极其微妙的计算进行四舍五入错误的主导性利用
- #4:Curve事件:编译器错误从无害源代码产生错误字节码
- #5:Platypus Finance:幸运地逃脱三次攻击
- #7:ParaSpace事件:一场与时间赛跑,阻止行业迄今为止最关键的攻击
- #8:SushiSwap事件:一次笨拙的救援尝试导致了一系列模仿攻击
- #9:MEV Bot 0xd61492:从掠食者到猎物,一次巧妙的漏洞利用
- #10:ThirdWeb事件:受信任模块之间的不兼容性暴露了漏洞



