2023年4月16日、Compound V2のフォークであるHundred Financeが攻撃を受け、約740万ドルの損失が発生しました。この攻撃は、主に以下の2つの問題によって引き起こされました。
- 精度損失問題(不正な丸め処理の問題)
- 空の市場により、ハッカーがexchangeRateを操作できるようになりました。
DeFiLlamaによると、最も多くフォークされているレンディングプロトコルであるCompound V2は、100以上のフォークを誇ります。OpenZeppelinによって監査され、実戦で証明されたそのコントラクトは安全と見なされています。しかし、Hundred Financeの攻撃は、特に流動性の低い状況での精度損失がDeFiプロトコルのセキュリティに致命的な影響を与える可能性があり、MidasやRadiantなどの著名なフォークで同様のエクスプロイトが続発するきっかけとなりました。
より深い理解のために、完全な分析を参照することをお勧めします。以下に、このインシデントの簡潔な紹介を提供し、2023年のトップ10セキュリティインシデントの1つとして強調します。
背景
Hundred Financeの概要
Hundred FinanceはCompound v2のフォークであり、Chainlinkオラクルを利用して複数のメインネットで動作しています。伝統的な金融の貸付慣行とは異なり、CompoundやAaveのようなDeFiレンディングプロトコルでは、過剰担保による借入は許可されていません。 簡単に言うと、トークンAを100ドル分預け入れた場合、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と基軸資産(例:daiとhDai、ethとhEth)間のexchangeRateは0.020から始まり、複利市場金利に相当する率で増加します。
清算
不良債権を防ぐため、レンディングプロトコルは、ユーザーが他のユーザーの負債を清算できるようにしています。次の例で説明します。
- アリスは100ドル相当のBTCを預け入れ、70ドル相当のETHを借入します。
- ETHの価格が上昇したり、BTCの価格が下落したりすると、アリスの資産が清算閾値に達する可能性があります。
- ボブは一定量のETHを使用してアリスのBTCを清算し、アリスの負債を健全なレベルに戻すことで、プロトコルの資金の安全を確保します(プロトコルは清算を開始したユーザーに報酬を支払います)。
清算はこの攻撃の焦点ではありませんが、攻撃に関与していました。 ここでは、ユーザーが任意のトークンで他のユーザーの負債を清算でき、それによって対応するhTokenが減少することを知っておけば十分です。
脆弱性
精度損失問題
ハッカーは、redeem()を介して担保を引き出す際に、控除されるhTokenの量の計算結果が1.99999992(2に非常に近いが2未満)となるようにしました。truncate()で整数に変換する際に、切り捨てを使用すると、最終結果は1になります。

exchangeRate
前述のように、exchangeRateの計算にはgetCash()が含まれており、これはhTokenコントラクトが保有する基軸資産の残高を指します。基軸トークンをコントラクトに直接転送することで(mintを使用せず、単純に転送)、ハッカーはexchangeRateを操作できます。
ただし、このexchangeRateの問題だけではプロトコルのセキュリティは侵害されないことに注意することが重要です。ハッカーは単独では利益を得られません。 この攻撃の文脈では、主にハッカーの利益を増幅するために悪用され、プールを急速に枯渇させることができました。そうでなければ、攻撃は単一の決定的な一撃ではなく、多数の微細な刺し傷となり、大きな影響を与えるには多数の反復が必要になります。
簡潔に言うと、精度損失はこの攻撃の鍵となる問題です。
攻撃プロセス
攻撃トランザクションを以下に示し、Phalcon Explorerを使用してこの複雑なトランザクションを分析します。
トランザクション:0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451
-
Flashloanを介してAave V3から500 WBTCを借入します。
-
以前に取得したhWBTCをすべて
Redeemし、hWBTCのtotalSupplyを0にリセットします。
この前の目的は、フラッシュローンを使用して準備資金を確保し、hWBTCを新しい市場としてリセットすることです。
-
2番目の攻撃コントラクト(以下、攻撃コントラクト2と呼ぶ)を
Createし、すべてのWBTC(500.30063816 WBTC)を攻撃コントラクト2に転送します。
-
4 WBTCを使用してhWBTCを
Mint()し、200 hWBTCを生成します。 -
199.99999998 hWBTCを
Redeem()し、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を借入します。
-
50030063815 WBTCを
Redeem()します。計算後、1.9999992 hBTCが控除されるはずですが、精度損失のため、1 hBTCしか控除されず、大幅な精度損失(約50%)が発生します。
この時点で、ハッカーは500 WBTC + 1021 Etherを保有しており、1021 Etherの利益を上げました。 -
攻撃者は残りのhWBTCを
liquidate()し、そのtotalSupplyを0にリセットし、他の市場での攻撃を継続する準備をします。 hWBTC内のほとんどすべてのWBTCが引き出されたことを考えると、ハッカーはわずか0.000002 Etherでこれを管理しました。
-
他の市場の攻撃を続行し、プロトコル全体を枯渇させます。
-
AaveへのFlashloanを返済します。
セキュリティ勧告
レンディングプロトコルのための軽減策
この問題は、特にCompoundやAaveのフォークで顕著です。プロアクティブなアプローチには、新しい市場を立ち上げる際に、totalSupplyが決して0にならないように、アカウンティングトークンをいくらかミントすることが含まれます。
精度損失問題のための軽減策
精度損失による一連の問題をより効果的に回避するために、**最小値を設定することは実際には効果的な方法です。**この戦略は、非常に小さな値を扱う際に精度損失によって引き起こされる重大な影響を回避するのに役立ちます。
このシリーズの他の記事を読む:
- リードイン:2023年のトップ10「素晴らしい」セキュリティインシデント
- 第1位:Flashbotsリレーの脆弱性を悪用したMEVボットの収奪
- 第2位:Euler Financeインシデント:2023年最大のハッキング
- 第3位:KyberSwapインシデント:極めて巧妙な計算による丸め誤差の巧みな悪用
- 第4位:Curveインシデント:コンパイラエラーにより無害なソースコードから不正なバイトコードが生成される
- 第5位:Platypus Finance:3度の攻撃を幸運で乗り越える
- 第7位:ParaSpaceインシデント:業界で最も重大な攻撃を阻止するための時間との戦い
- 第8位:SushiSwapインシデント:下手な救出試みが一連の模倣攻撃を招く
- 第9位:MEVボット 0xd61492:巧妙なエクスプロイトで捕食者から被食者へ
- 第10位:ThirdWebインシデント:信頼されたモジュール間の互換性のないことで脆弱性が露呈



