2022年4月30日、攻撃者はNerve Bridgeインシデントと同様の脆弱性を悪用し、Saddle Financeを攻撃しました。合計4,900 Etherが攻撃対象となりました。幸いなことに、そのうち1,360 Etherは弊社によって救出されました。このインシデントの詳細については、公式の事後分析を参照してください。


同じ脆弱性が悪用されましたが、攻撃手法は以前のものとは異なります。新しい攻撃手法は、予想されるほど単純ではないため、より多くの労力をかけて詳細な調査を行う価値があると考えています。本レポートでは、まず脆弱性を簡潔に説明し、次にNerve Bridgeインシデントの元の攻撃手法をレビューします。その後、新しい攻撃手法を解明するために、Saddle Financeインシデントに焦点を当て、攻撃プロセスを詳細に分析します。
0x1. デプロイされたコントラクトについて
関連するコントラクトアドレスは以下の通りです。
- 被害者 MetaSwap コントラクト: 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
- 脆弱な MetaSwapUtils コントラクト: 0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17
検証済みのMetaSwapコントラクトに関連付けられているMetaSwapUtilsコントラクトの表示コードは、Settingsで指定されているコントラクトアドレスのデプロイされたMetaSwapUtilsコントラクトと等しくないことに注意してください。

したがって、これらの2つのMetaSwapUtilsコントラクトに混同しないでください:)
0x2. 脆弱性分析
脆弱なコントラクトはMetaPoolに属しており、これは以前のブログで詳細に議論されています。 要するに、MetaPoolはもともとCurveによって設計され、単一のコインを別の(ベース)プール内のすべてのコインとプール化することを可能にし、その流動性を希釈しないようにしました。それは基本的に、いくつかの他のステーブルコインで構成されるベースプールのLPトークンとステーブルコインで構成されるプールです。 MetaPoolの設計には懸念があります。つまり、MetaPoolは基本的にステーブルコインの価格を維持するステーブルコインプールですが、ベースのステーブルコインプールのLPトークンはステーブルコインではありません。
実際、ベースのステーブルコインプールのLPトークンの価格は、ベースプールのgetVirtualPrice関数を呼び出すことで取得でき、その価格はベースプールによって請求される手数料の蓄積とともに着実に上昇します。
これを処理するために、MetaPoolは価格計算の前にLPトークンの準備金をスケーリングアップします。

したがって、ユーザーがLPトークンをステーブルコインと交換する場合、LPトークンの量は価格計算の前にスケーリングアップされます。 あるいは、ユーザーがステーブルコインをLPトークンと交換する場合、計算されたLPトークンの量は転送と記帳の前にスケーリングダウンされます。

上記のswapUnderlying関数のコードスニペットは、MetaPool内のステーブルコインとベースプール内のステーブルコインとの間で交換するために使用されます。2つの赤い四角で示されているように、この関数は交換されるLPトークンの量をスケーリングアップし、交換されるLPトークンの量をスケーリングダウンします。
しかし、swap関数の実装はswapUnderlying関数の実装とは一致しません。具体的には、脆弱性の根本原因は、swap関数(すなわち_calculateSwap関数)に実装された欠陥のある計算にあり、LPトークンの量を適切にスケーリングダウンおよびスケーリングアップしていません。以下に示すように、左側はMetaPoolの脆弱なコード、右側は修正されたバージョンです。

Nerve Bridgeインシデントの攻撃者は、swap関数とswapUnderlying関数の間の不整合を悪用しました。
(Nerve BridgeはSaddle Financeのフォークプロジェクトです。)
その後、Saddle Financeは直ちに脆弱性を修正し、新しいバージョンのMetaSwapUtilsライブラリ(すなわちV2)を再デプロイしました。
残念ながら、何らかの未知の理由により、Ethereum上のsUSD V2 MetaPoolは古い脆弱なMetaSwapUtilsライブラリでデプロイされたままになりました。 その結果、4月30日にこの脆弱性が攻撃者によって再び悪用されました。興味深いことに、Nerve Bridgeインシデントで使用された攻撃手法とは異なり、脆弱なMetaPoolを攻撃するために異なる方法が採用されました。
0x3. Nerve Bridgeインシデントの元の攻撃手法
元の攻撃手法をレビューするために、以下の図(以前のブログを参照)を再利用します。

脆弱なswap関数は交換されるLPトークン(Nerve 3-LP)の量をスケーリングダウンしないため、ステップ3での交換量(36,959)は通常より大きくなります。
その後、攻撃者はswapUnderlying関数(脆弱性なし)を呼び出して、36,959 Nerve 3-LPを51,494 fUSDTと交換し、1,143 fUSDTの利益を得ます。
合理的に、利益は次のように説明できます。攻撃者はステップ3でより多くのNerve 3-LPを獲得し、次にswap関数とswapUnderlying関数の間の不整合を利用して、「通常の」価格でそれらを販売します。
0x4. Saddle Financeインシデントの新しい攻撃手法
最近のSaddle Financeインシデントの攻撃者は、swapUnderlying関数を関与させずに、同じ脆弱なswap関数を攻撃するために異なる方法を使用しました。
ここでは、プロセスを具体的に説明するために、1つの攻撃トランザクションを例として取り上げます。

直感的には、ステップ3とステップ4のいずれかの含意は相殺されるため、利益は存在しないはずです。
具体的には、ステップ3では、LPトークン(saddleUSD)を交換する際にスケーリングダウンが行われないため、攻撃者はより多くのsaddleUSDを交換できます。
しかし、ステップ4では、脆弱なswap関数は価格計算の前に流入するsaddleUSDの量をスケーリングアップしないため、攻撃者は必然的により少ないsUSDを交換することになります。
しかし、上記の図に示すように、攻撃者はステップ3とステップ4の交換ペアを通じて2,059,771 sUSDの利益を得ました。 利益の理由を理解するために、価格設定メカニズムを深く掘り下げ、攻撃プロセスを理解するために詳細な調査を行う必要があります。
0x4.1 価格設定メカニズム
Saddle FinanceのMetaPoolはCurveの価格設定式を継承しています。

(nが2の場合の)関数のグラフを以下の図の青い曲線で示します。 (式の設計はCurve StableSwap Whitepaperで見つけることができます。)

ここで疑問が生じます。MetaPoolはこの式を使用して各スワップの価格をどのように計算するのでしょうか?
nが2で、ユーザーがdx0トークン0を使用してdx1トークン1を交換すると仮定します。
各スワップにおいて、Aは定数として扱われ、
価格曲線に影響を与える唯一の変数であるDは、実際には
Dはプールによって請求される手数料の蓄積とともに増加します。具体的には、計算プロセスは次の3つのステップに要約できます。
- ステップI:現在のプールの準備金(x0およびx1)を式に入れて現在の
Dを計算し、現在の価格曲線を決定します。 - ステップII:x0をdx0だけ増加させ、現在の
Dとx0を式に入れて新しいx1を計算します。 - ステップIII:次に、dx1は新しいx1と古いx1の差です。
トークン0がベースプールのLPトークンである場合、ステップIIは次のようになります。

ここで、baseVirtualPrice/1e18は攻撃中に約1.0033でした。 あるいは、トークンがベースプールのLPトークンである場合、ステップIIIは次のようになります。

Dが価格曲線にどのように影響するかを理解するために、例を使用して説明します。
ユーザーが最初にdx0トークン0をdx1トークン1と交換し、次にdx1トークン1をdx0'トークン0と交換するとします。

上記の図に示すように、ステップ②が最初の交換に手数料を請求するため、Dは増加して価格曲線を上にシフトします(黒い曲線から青い曲線へ)。
さらに、図はdx0'がdx0'よりも小さい理由を明確に説明しています。
0x4.2 攻撃分析
利益の理由を分析するために、脆弱なおよび修正されたMetaSwapUtilsライブラリをローカルにデプロイし、その時点の被害者プールの状態を使用して攻撃をシミュレートしました。
さらに、このシミュレーション中に、攻撃プロセスを理解するのに役立ついくつかの値、つまりAが10,000、x_sUSDが8,130,463、x_saddleUSDが9,688,608、そしてDがその時点で17,818,392であることを記録しました。

上記の図は、利益のあった一連の交換プロセスを示しています。
- 交換-I:14,800,272 sUSDを9,657,586 saddleUSDと交換
- 交換-II:9,657,586 saddleUSDを16,860,043 sUSDと交換
具体的には、交換-Iは次の2つのステップに分割できます。
- ①:14,800,272 sUSDを9,625,654 saddleUSDと交換。ここで、
Dは17,931,435に増加します(請求された手数料のため)。 - ②:脆弱なMetaPoolは交換されるsaddleUSDをスケーリングダウンしないため、プールは31,932 saddleUSDを失います。損失により
Dは15,736,195に減少します。これにより、価格曲線はさらに下にシフトします(黒い曲線から灰色の曲線へ)。
同様に、交換-IIも2つのステップに分割できます。
- ③:価格曲線が下にシフトしているため、同じ9,625,654 saddleUSDは、コストである14,800,272 sUSDよりもはるかに多い16,891,906 sUSDを交換できます。
- ④:脆弱なMetaPoolは価格計算の前に流入するsaddleUSDの量をスケーリングアップしないため、MetaPoolには31,863 saddleUSDが残ります。これにより、価格曲線は上にシフトします(灰色の曲線から青い曲線へ)。 それにもかかわらず、交換ペアは依然として2,059,771 sUSDの利益を上げています。
明らかに、上記の分析は、攻撃者が新しい攻撃手法を使用して利益を収穫できた理由を明確に説明しています。 さらに、交換-IIでMetaPoolに残ったsUSDのため、元の攻撃手法の方が新しい手法よりも効率的であるように思われます。もちろん、攻撃者はプールを枯渇させるために複数の攻撃を実行する可能性があり、これは実際に観察されています。
0x5. まとめ
調査によると、2つのインシデントにおける利益の根本原因は同じです。具体的には、最初の交換(LPトークンを交換するもの)は、脆弱なMetaPoolのDを減少させ、それが価格曲線をさらに下にシフトさせます。このシフトは、その後の価格設定に大きく影響し、その後の利益の主な理由となっています。
BlockSecについて
BlockSecは、2021年に世界的に著名なセキュリティ専門家チームによって設立された、先駆的なブロックチェーンセキュリティ企業です。同社は、新しいWeb3の世界のセキュリティと使いやすさを向上させ、その大規模な採用を促進することにコミットしています。この目的のために、BlockSecはスマートコントラクトおよびEVMチェーンのセキュリティ監査サービス、セキュリティ開発および脅威のプロアクティブなブロックのためのPhalconプラットフォーム、資金追跡および調査のためのMetaSleuthプラットフォーム、そしてWeb3ビルダーが仮想通貨の世界を効率的にサーフィンするためのMetaDock拡張機能を提供しています。
現在までに、同社はMetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなどの300社以上の著名なクライアントにサービスを提供し、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの有力な投資家から2回の資金調達ラウンドで数千万米ドルを受け取っています。
公式ウェブサイト: https://blocksec.com/
公式Twitterアカウント: https://twitter.com/BlockSecTeam



