Yearnが盗まれた$9Mの攻撃分析
前言
2025年12月1日、Yearnプロトコルは巧妙に設計された多段階の複雑なハッキング攻撃に遭遇し、最終的に約900万ドルの資産損失を被りました。攻撃は単一の脆弱性の悪用ではなく、攻撃者がフラッシュローンを利用して資金を調達し、プロトコルの複数の論理的欠陥を利用して資金プールの状態を段階的に操作し、最終的にほぼ無限にyETH関連のLPトークンを鋳造し、資金プールを枯渇させる悪性の事件を引き起こしました。
今回の攻撃はフラッシュローンを初期資金のレバレッジとして使用し、多段階の操作でプロトコルの防御を突破しました。核心的な攻撃プロセスは、資金調達、状態操作、無限鋳造、利益確定の4つの重要な段階に分けられます。各段階は密接に関連しており、プロトコル設計の論理的欠陥を正確に利用しています。
攻撃tx: https://etherscan.io/tx/0x53fe7ef190c34d810c50fb66f0fc65a1ceedc10309cf4b4013d64042a0331156
技術分析
まず、2つのフラッシュローンを使用して、BalancerとAaveからwstETH、rETH、WETH、および0xa35b_ETHx、rETH、wstETH、cbETHを借り出します。


フラッシュローンのコールバック関数内で、借りたETHを1100 ETHでTornado.Cashに預け入れます: 100 ETH混合、次にTornado.Cashのwithdraw関数を利用して、100 ETHを悪意のあるコントラクト0x3e8e7533dcf69c698Cf806C3DB22f7f10B9B0b97に引き出し、そのfallback関数をトリガーします。


fallback関数内では、下の図の最後のexchangeと次のremove_liquidityの数値が一致していることが確認でき、前のステップはすべてフラッシュローンで得た資産をexchangeなどの操作を通じて大量のyETH weighted stableswap poolのLPトークンに交換するためのものであると推測できます。これは後続の攻撃の準備となります。

これにより、核心的な攻撃プロセスが正式に開始されます。
1.まず、上記のexchangeで得たLPトークンをyETH weighted stableswap poolのremove_liquidity関数を通じてすべて破棄し、按分された8種類のプール内の基礎資産に変換します。
このremove_liquidity関数のロジックは、プールに合計10,000のLPトークンがあると仮定し、416.37のLPトークンを破棄した場合、あなたの割合は:416.37 / 10,000 = 4.16%となります。
次に、各資産について、プールに1,000のwstETH(仮想残高prev_vb)があると仮定します。あなたが引き出せる仮想残高は:dvb = 1,000 * 416.37 / 10,000 = 41.637 wstETH、次に為替レートrateで実際のトークン数に変換します。
2.次に、addliquidityを繰り返し呼び出して片側のプールに注入します。合計8つのamountsパラメータがそれぞれ異なる資産の数量に対応しています。前の数回のループでindex3[rETHトークン]、index6[wOETHトークン]、index7[mETHトークン]がすべて0を入力していることが観察され、つまり、流動性を追加するたびにこれら3つのトークンは追加されていません。

このようにして片側の資産を注入し、プール内のトークンの数量差を人工的に拡大します。
3.続いて、片側に大量のrETHトークンを注入し、その後の重要なステップでremoveliquidityを呼び出しますが、amount=0を入力します。

なぜ0個のトークンを引き出すことができるのでしょうか?それはremove_liquidityの内部実装によります。

removeliquidity関数は0金額に対してショートサーキット処理を行わず、依然として完全なvbprod計算ループを実行し、上記のように人工的に作成されたプール内のトークン数量の差に基づいてグローバルなpackedpoolvb状態を計算し更新します。
4.その後、updaterates関数を呼び出してindex6[wOETH]のプール比率を更新し、最後にremoveliquidityを呼び出してプール内のトークンを引き出します。この時点で、そのプール内のW0ETHの数量はほとんど残っていません。

5.同様の方法でプール内のindex6[w0ETH]とindex7[mETH]のシェアを絞り取ります。ここで、最初の2回のindex6の更新後すぐにremove_liquidityでトークンを引き出し、最後のindex7[mETH]はまだ更新のみ行い、引き出していません。

これにより、上記のように大量の片側プールを追加し、すべてのプールのトークンを引き出すことで、プール内のW0ETHとmETHの比率はほぼ0になりました。
この時点で新しい悪意のあるコントラクト0xADbE952eBB9b3e247261d2E3b96835f00f721f8Eを作成し、すべてのトークンをそのコントラクトに転送します。注意すべきは、前のステップで片側にrETHを追加して得たLPトークンは基礎トークンに交換されず、新しい悪意のあるコントラクトに転送されたことです。

前の攻撃操作でupdateratesがindex7[mETH]を更新したが、引き出しは行われていないトークンはここでremoveliquidityを呼び出して引き出します。この時点でプール内のindex6[w0ETH]のシェアは非常に小さく、index7[mETH]のシェアはさらに小さくなっています。

この時点でプール内のトークンの比率は深刻に不均衡になり、攻撃者は再度add_liquidityを呼び出して流動性を追加し、[1, 1, 1, 1, 1, 1, 1, 9]の比率で大量のLPトークンを取得します。

ここまでで攻撃者は大量のLPトークンを取得し、その後はexchange、redeemなどの方法で利益を確定し、フラッシュローンの費用を返済します。

攻撃復盤
今回の攻撃は複雑な多段階の組み合わせ攻撃であり、攻撃者はpool.vyコントラクト内の3つの核心的な脆弱性を利用しました:精度の喪失 (Precision Loss)、利益の剥奪 (Yield Stripping)、およびゼロ供給の初期化 (Zero Supply Initialization)。
段階一:極端な不均衡の製造
* 操作 : 攻撃者はadd_liquidityを繰り返し呼び出しますが、index 3 (rETH)、index 6 (wOETH)、index 7 (mETH)を意図的に避けます。
* 目的 : プール内の資産比率の不均衡を人工的に作り出します。
* 重要なステップ : その後、片側に大量のrETHを注入します。
* 結果 : rETHと他の資産(特にwOETHとmETH)の数量差を極端に広げ、精度の喪失を引き起こす数学的条件を作り出します。
段階二:誤差のトリガーとロック
* 操作 : removeliquidity(amount=0)を呼び出します。
* 原理 :
- remove_liquidityは0金額に対してショートサーキット処理を行いません。
- 送金しなくても、コントラクトはvb_prodの完全な計算ループを実行します。
- 極端な重みの不均衡の下で、powdown関数は顕著な切り捨て誤差を生じます。
- コントラクトはこの小さすぎるvbprodをグローバル状態packedpool_vbに書き込みます。
* 本質 : これは「ゼロコスト」の状態攻撃であり、攻撃者は何の代償も払わずにプールの帳簿価値を改ざんしました。
段階三:利益の剥奪とシェアの搾取
* 操作 :
- update_rates([6]) (wOETHの為替レートを更新)。
- remove_liquidity (資産を引き出す)。
- update_rates([7]) (mETHの為替レートを更新)。
* 原理 :
- updateratesはupdatesupplyをトリガーします。vbprodが以前に悪意を持って低下させられたため、システムはプールの価値が減少したと誤認し、Stakingコントラクトが保有するLPトークンを破棄して帳尻を合わせます。
- 攻撃者はremove_liquidityを利用して、為替レートの更新前後でアービトラージを行い、徐々にプール内のwOETHとmETHのシェアを搾取します。
* 結果 : Stakingコントラクトのシェアが大量に破棄され、攻撃者の手元のLPシェアが受動的に増加し、プールの総供給が0に近づきます。
段階四:ゼロ供給の無限鋳造
* 前提状態 : 上記の操作を経て、プールは空になり、総供給が0に近づき、wOETHとmETHの残高が非常に低くなっています。
* 操作 : addliquidity、パラメータはamounts=[1, 1, 1, 1, 1, 1, 1, 9]です。
* 原理 :
- prevsupply ≈ 0のとき、calc_supplyの反復式は極小数値(1 wei、9 wei)を処理する際に無効になります。
- コントラクトは天文学的なLPトークンの鋳造量を誤って計算します。
- 結果: 攻撃者は235,443…個のyETH LPトークンを無から得ました。
まとめ
Yearnの今回の攻撃事件は、DeFiプロトコルがエッジケースの論理検証、数値計算精度の制御、および多重脆弱性の組み合わせリスク防止において多くの不足を露呈しました。攻撃者はフラッシュローンを道具として、脆弱性の組み合わせを利用することを核心とし、資金の混乱を隠れ蓑とする攻撃モデルを展開し、現在のDeFi攻撃の専門化、複雑化の傾向を浮き彫りにしました。今回の攻撃の核心的な教訓は、1つはプロトコルが「ゼロ金額」や「極端な不均衡」などのエッジケースに対する論理検証を強化し、ショートサーキット処理を行わないことによる状態改ざんリスクを回避する必要があること、2つ目は数値計算において極端な比率下での精度損失の問題を重視し、powdownなどの重要な関数の計算ロジックを最適化する必要があることです。以前、Balancerプロトコルも精度損失により安全事件が発生したことがあり、これは前車之鑑です。3つ目は、多次元のリスク監視システムを構築し、高頻度の片側流動性注入や異常な為替レートの更新などの疑わしい操作に対して警告を行う必要があります。全体のDeFi業界にとって、今回の事件は再び、プロトコルの安全性は単一の脆弱性の修正だけでなく、全プロセスの視点から多重脆弱性の組み合わせ利用の攻撃を防ぐ必要があることを証明しました。また、攻撃者の資金の流れを追跡し、遮断する能力を強化し、業界全体の安全防護能力を向上させる必要があります。











