5000万USDTが3.5万ドルのAAVEに:災害はどのように発生したのか?私たちは誰を責めるべきか?

本文约6410字,阅读全文需要约26分钟
取引パスの致命的な欠陥により、5000万ドルのDeFi操作がほぼゼロの保護下で実行され、資金が微小な流動性プールでほぼ全額蒸発した。

本文来自:@Ehsan1579

編訳|Odaily(@OdailyChina);翻訳者| Ethan(@ethanzhang_web 3)

イベントのタイトルだけを見ると、これはおそらくエクスプロイト攻撃だと誤解されるだろう。

イベントの核心はこれだ:誰かが5040万ドル相当のUSDTを、最終的にわずか3万5900ドル相当のAAVEにしか交換できなかった。

私がこの話を初めて聞いたとき、本当に驚いた。そこで、私はこの事件を徹底的に調査した:取引の追跡、ソルバーのパス、コントラクトの呼び出し、履歴リザーブ、決済データ、アダプタのフロー、Aaveインターフェースのコード、CoWフラッシュローンSDK、そして見積もりが「合理的」かどうかを判断するルーティングコード。

これはハッキングではない。​ Aaveのコアプロトコルに問題はなかった。CoWの決済に問題はなかった。Uniswapに問題はなかった。SushiSwapに問題はなかった。取引は有効で、署名は有効で、すべてのコントラクトはコード通りに正確に実行された。しかし、ほぼすべての経済的価値が破壊された。なぜなら、それが許可されたルートが途方もなく不合理だったからだ。

パブリックチェーンに問題はなかった。問題はルーティングにあった。

私の見解では、これを単なる「ユーザーの操作ミス」と軽く片づけることは、客観的で厳密な態度ではない。確かに、ユーザーは注文に署名した。しかし、約5000万ドルもの担保ローテーションに関わる操作が、見積もり、署名、ルート計画、最終的な実行まで、たった約331枚のAAVEしか持たない低流動性プールに向かうことを、ソフトウェアシステム全体が許可してしまった。これは本来、完全に起こりえないことだった。少なくとも、決済プロセスが開始される前に、システムによって強制的に拒否されるべきだった。

取引の核心情報の追跡

この異常取引のハッシュは:0x9fa9feab3c1989a33424728c23e6de07a40a26a98ff7ff5139f3492ce430801f。2026年3月12日、イーサリアムメインネットのブロック高24643151で確認され、取引インデックスは1、消費Gas量は3780570単位、取引は成功した。注文を所有するウォレットアドレスは0x98b9で始まり、実際に取引を実行したソルバー(取引送信者)のアドレスは0x3980で始まり、CoWの競争データではtsolverとマークされている。

まず理解すべきは、これは単純なウォレットレベルでのUSDTからAAVEへの交換ではないということだ。売却されたトークンはaEthUSDT、つまりAaveプラットフォーム上の利子付きUSDT預金証書だ。購入されたトークンはaEthAAVE、つまりAaveプラットフォーム上の利子付きAAVE預金証書だ。つまり、これは実際にはCoWプロトコルの決済システムとそのフラッシュローンアダプタフローを通じて行われたAave担保のローテーションだ。

取引前、このウォレットは約50,432,693.075254個のaEthUSDTと0個のaEthAAVEを保有していた。取引後、わずか4.980399個のaEthUSDTが残り、327.241335505966487788個のaEthAAVEを受け取った。実際、このウォレットはほぼ全ポジションを売却した。

メタデータは、ルートが実行前からすでに「有毒」であったことをより明確に示している。注文はaave-v3-interface-collateral-swapフローから来ている。CoWのAPIはこれを署名済みの売り注文として表示し、アプリケーションメタデータは121ベーシスポイントのインテリジェントスリッページを使用した成行式担保スワップとしてマークしている。署名された売却金額は50,432,688.41618個のaEthUSDTだ。署名された最低購入金額は324.949260918413591035個のaEthAAVEだ。実際の決済では327.241335505966487788個のaEthAAVEが支払われた。

これは極めて重要な詳細だ。この注文は、何千ものAAVEを獲得することを期待しておらず、途中で何らかの理由で破壊されたわけではない。構築された当初から、数百個のAAVEという結果を中心に設計されていた。

ルート崩壊の完全な連鎖

取引の追跡をたどれば、プロセス全体は残酷なまでに単純明快だ。

トップレベルの資金フローの核心は、CoWプロトコルの0x9008で始まるGPv2Settlement決済コントラクトに依存している。まず、0x60bfで始まるHooksTrampolineコントラクトがaEthUSDTの承認操作を完了し、CoWの金庫リレイヤーが個別の取引承認なしでユーザーの資産を引き出せるようにする。その後、0xc92eで始まるGPv2VaultRelayerコントラクトがユーザーのウォレットから50432688.41618枚のaEthUSDTを引き出し、決済フローに入れる。この段階までは、すべての操作が正常な論理に従っている。

決済コントラクトはその後、aEthUSDTの操作権限を0xd524で始まる未開示の補助コントラクトに付与し、関数セレクタ0x494b3137を通じて呼び出しを開始する。この補助コントラクトは実行権限を0x699cで始まる未開示のエグゼキューターコントラクトに転送し、ここで異常取引ルートの全貌が完全に露呈する。

最初の有効な呼び出しは0x87870で始まるAaveプールコントラクトを指し、withdraw関数(セレクタ0x69328dec)を通じてaEthUSDTをバーンし、基盤となるネイティブUSDTを償還する。その後、ルートは0x4e68で始まるUniswap V3の深いUSDT/WETH取引プールにジャンプし、すべての50432688.41618枚のUSDTを17957.810805702142342238枚のWETHに交換する。

この段階の取引は完全に正常だ:交換レートは約2808.4 USDTで1 WETHであり、当時の市場相場に合致しており、流動性不足の問題も計算誤差もなく、最初のジャンプの取引連鎖には何の異常もない。

問題は第二のジャンプにある。流動性リザーブを見れば、残りの話は避けられないものだ。

エグゼキューターが17957.810805702142342238枚のWETHを取得した後、全資金をアドレス0xd75ea151a61d06868e31f8988d28dfe5e9df57b4のSushiSwap V2 AAVE/WETH取引プールに転送する。

私は、異常取引が発生する直前(ブロック高24643150)のこの取引プールの履歴流動性リザーブデータを確認した。プール内には以下しか保持されていなかった:

331.631982538108027323 枚のAAVE、17.653276196397688066 枚のWETH

これはデータ入力エラーではなく、紛れもない事実だ。

この取引ルートは、約17958枚のWETHすべてを、わずか17.65枚のWETHをリザーブし、対応するAAVEの総在庫がたった331.63枚しかないミニ取引プールに注入した。投入されたWETHの規模は、プール内のWETHリザーブの約1017倍だった。

これは「スリッページがやや高い」や「流動性がやや薄い」といった通常の問題ではない。これは極端に不合理な成行注文の実行パスであり、規模が自らの数千倍にも及ぶ巨額の取引を、非常に小規模な定積AMMプールに強制的に引き受けさせることに相当する。

AMM取引プールは定められたアルゴリズムに従って操作を実行し、プール内のほぼすべてのAAVEリザーブを枯渇させた。

SushiSwapの取引ペアは、コアのSwap交換イベントをトリガーした:エグゼキューターが17957.810805702142342238枚のWETHを転送し、わずか331.305315608938235428枚のAAVEしか戻ってこなかった。取引完了後、このプールの残りの流動性は約:

0.326666929169791895 枚のAAVE、17975.464081898540030304 枚のWETH

つまり、プール内の約99.9%​のAAVE在庫が一つのジャンプで吸い尽くされた。

取引前のリザーブに基づくと、プールが暗示するAAVEの価格は約149.50ドルだった。ユーザーの実際の実行価格は約154,114.66​ USDTで1 AAVEだった。これは取引前のスポット価格の1000倍以上も乖離していた。

その後、これらのAAVEはセレクタ0x617ba037、つまりsupply(address,uint256,address,uint16)を使用してAaveプールに供給され戻された。結果として新しく鋳造されたaEthAAVEが決済コントラクトに戻された。決済コントラクトは最終的に327.241335505966487788個のaEthAAVEをユーザーに転送した。約4.06398010297174764個のaEthAAVEが、ユーザーが支払った金額に対する剰余として、決済コントラクト内に残された。

つまり、決済は突然良い実行結果を悪い結果に歪めたわけではない。それは単に、ルートがすでに生み出していた結果を最終確定しただけだ。

これが重要な点で、明確に言う価値がある:​ 壊滅的な結果は、ルートが実行される前からすでにその中に「予め設定」されていた。

ルートに埋め込まれた補助コントラクトの呼び出しデータでは、購入側の目標金額は約331.272185078031026739枚であり、ユーザーが署名で合意した最低購入金額は324.949260918413591035枚であり、実際の決済金額は327.241335505966487788枚だった。すべての核心的な数値は、決済前から、数百枚のAAVEという規模にロックされていた。

このルートは生まれつき壊れていた。

脆弱性はどこに?

答えは:システムの各層の検証メカニズムが、間違った次元をチェックしていたことだ。

すべての層は、取引が実行可能か、署名が有効か、金額がゼロでないかだけを検証し、取引ルートが経済的に合理性を持つかどうかを検証する核心層がほとんどなかった。これがメカニズムが崩壊した核心の根源だ。

Aaveインターフェースアダプタの見積もりパスのコード欠陥

最初の明らかなコード異常点は、AaveインターフェースのCoWアダプタ見積もりフローに現れた:見積もりをリクエストする際にアダプタ専用のアプリケーションデータを添付するために使用されるはずの関数が、直接強制的に無効化されていた。

出典:rates.helpers.ts:93adapters.helpers.ts:194

これは、AaveインターフェースがCoWに見積もりをリクエストする際に、実際に注文を発行する際に添付されるフラッシュローンとフックのメタデータを添付していなかったことを意味する。言い換えれば、見積もられたものは、実行されるものと完全には一致していなかった。コードコメントは、このヘルパー関数の目的はアダプタの見積もりをより正確にするためだとさえ述べているが、この関数は硬直的に無効化されていた。

CoWの見積もり競争ロジックの合理性判定が弱すぎる(核心の脆弱性)

二つ目、そして最も深刻な問題は、CoWプロトコルの見積もり競争ロジックにある:その公共サービスのコードでは、見積もりのGas費用が正で、出力金額がゼロでない限り、「合理的な見積もり」と判定される。

出典:quote.rs:31

8桁の注文を処理するルーティングシステムにとって、これは驚くほど薄弱な「合理性」の定義だ。

システムはオラクルを統合して価格の健全性を検証しておらず、「見積もりがスポット価格から500倍以上乖離している」という遮断メカニズムも、「ルートが流動性プールを完全に枯渇させる」というリスク判定も、「最後のジャンプの流動性が注文規模と深刻にミスマッチしている」という警告もない。ソルバーが実行可能でゼロでないルート案を返すだけで、システムに受け入れられる。これが今回の事件の核心的な脆弱性だ。

Uniswap V2スタイルの流動性モデリングロジックの欠陥

三つ目の問題は、Uniswap V2スタイルの流動性プールのモデリング方法にある:コードは標準的な定積アルゴリズムのみを採用し、ゼロリザーブ、数値アンダーフロー、リザーブオーバーフローなどの数学的に不可能な状況のみを拒否し、経済的な実現可能性の検証を行わない。

出典:pool_fetching.rs:118pool_fetching.rs:153

このコードは、流動性プールの規模が対応するルート取引を引き受けるのに十分かどうかを判断せず、交換操作が数学的に有効かどうかのみを判断する。したがって、たった331枚のAAVEしかリザーブしていないミニプールでも、17957枚のWETHの購入リクエストを引き受ける有効な場所と判定される。なぜなら、定積アルゴリズムがゼロでない結果を計算できるからだ。しかし、この結果が破滅的な資産損失をもたらすことは完全に無視される。

フラッシュローンSDKと注文検証メカニズムの二次