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関数とは一貫性がありません。具体的には、脆弱性の根本原因は、LPトークンの量を適切にスケールダウンおよびスケールアップしないswap関数(つまり_calculateSwap関数)に実装された誤った計算にあります。以下に示すように、左側は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を(ステップ4と5で)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,771sUSDの利益を得ました。 利益の理由を把握するために、価格設定メカニズムに深く入り込み、攻撃プロセスを理解するために詳細な調査を行う必要があります。
0x4.1 価格設定メカニズム
Saddle FinanceのMetaPoolはCurveの価格設定式を継承しています。

(nが2の場合の)関数のグラフは、以下の図の青い曲線で示されています。 (式の設計については、Curve StableSwap Whitepaperを参照してください。)

ここで問題が生じます。MetaPoolは、この式を使用して各スワップの価格をどのように計算するのでしょうか?
nが2と仮定し、ユーザーがdx0のtoken0を使用してdx1のtoken1を交換するとします。
dx1の計算プロセスをシミュレートできます。
各スワップにおいて、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のtoken0をdx1のtoken1と交換し、次にdx1のtoken1をdx0'のtoken0と交換したとします。

上記の図に示すように、ステップ②は最初の交換の手数料を請求するため、Dが増加して価格曲線を上にシフトします(黒い曲線から青い曲線へ)。
さらに、図はdx0'がdx0'より小さい理由を明確に説明しています。
0x4.2 攻撃分析
利益の理由を分析するために、脆弱なMetaSwapUtilsライブラリと修正された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で16,891,906 sUSDを交換できます。これは、コストの14,800,272 sUSDをはるかに超えています。
- ④:脆弱なMetaPoolは、価格計算の前に受け取ったsaddleUSDの量をスケールアップしないため、MetaPoolには31,863 sUSDが残っており、価格曲線は上にシフトします(灰色の曲線から青い曲線へ)。 それにもかかわらず、交換ペアは依然として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



