Gateアプリをダウンロードするにはスキャンしてください
qrCode
その他のダウンロードオプション
今日はこれ以上表示しない

価格操作の黒魔術: Balancer V2 の不変計算の脆弱性の解剖学

編纂:平易なブロックチェーン

!

2025年11月3日、Balancer V2のコンポーザブルステーブルプール(Composable Stable Pools)および複数のチェーン上のいくつかのフォークプロジェクトが協調攻撃を受け、総損失は1.25億ドルを超えました。BlockSecは最初に警報を発し、その後初期分析を発表しました。

これは高度に複雑な攻撃です。私たちの調査によると、根本的な原因は不変量(invariant)計算における精度の損失によって引き起こされた価格操作であり、それによってBPT(Balancerプールトークン)の価格計算が歪められました。この不変量操作により、攻撃者は特定の安定プールからの一回のバッチスワップを通じて利益を得ることが可能になりました。一部の研究者が洞察に満ちた分析を提供していますが、特定の解釈には誤解を招くものがあり、根本的な原因や攻撃プロセスはまだ完全には明らかにされていません。本ブログはこの事件について包括的かつ正確な技術分析を行うことを目的としています。

重要なポイント (TL;DR)

根本原因: 丸めの不整合と精度の損失

+ アップスケーリング操作では一方向の丸め (切り捨て) を使用し、ダウンスケーリング操作では 2 方向の丸め (切り上げと切り捨て) を使用します。
+ この不一致性は精度の損失を引き起こし、巧妙に設計された交換経路を利用する際に「丸めは常にプロトコルに有利であるべき」という標準的な原則に違反します。

攻撃の実行

+ 攻撃者は、精度の損失の影響を最大化するために、反復回数や入力値を含むパラメータを注意深く設計しました。
+ 攻撃者は、検出を回避するために二段階の方法を使用します:まず、単一の取引でコア攻撃を実行し、すぐには利益を得ず、次に別の取引で資産を引き出すことによって利益を実現します。

運用上の影響と増幅

+ いくつかの制限により、プロトコルを一時停止することができません。この停止できない状況は、攻撃の影響を悪化させ、大量の後続の模倣攻撃を引き起こしました。

以下の部分では、まずBalancer V2に関する重要な背景情報を提供し、その後、発見された問題や関連する攻撃について詳しく分析します。

0x1 背景

1. Balancer V2 のコンビネーション型ステーブルプール

今回の攻撃で影響を受けたコンポーネントは、Balancer V2 プロトコルのコンビネーション型ステーブルプールです。これらのプールは、1:1 のペッグ(または既知の為替レートで取引される)資産を維持することを目的として設計されており、最小限の価格影響で大規模な交換を可能にし、同類または関連資産間の資本効率を大幅に向上させます。各プールには、自身の Balancer プールトークン (BPT) があり、流動性提供者のプール内の持分と、それに対応する基礎資産を表しています。

このプールは、Stable Math(Curveに基づくStableSwapモデル)を採用しており、不変量Dはプールの仮想総価値を表しています。

BPT価格は次のように近似できます:

画像上記の式からわかるように、Dが帳簿上で小さくすることができれば(実際の資金損失がなくても)、BPTの価格はより安く見えることになります。

2. batchSwap()とonSwap()

Balancer V2 は、batchSwap() 関数を提供しており、この関数は Vault 内でのマルチホップスワップをサポートしています。この関数に渡されるパラメータに基づいて、2 種類のスワップタイプがあります。

  • GIVEN_IN(“与えられた入力”):呼び出し元が正確な入力Tokenの数量を指定し、プールがそれに応じた出力数量を計算します。
  • GIVEN_OUT(“与えられた出力”):呼び出し元が期待する出力数量を指定し、プールが必要な入力数量を計算します。

通常、batchSwap() は、複数の onSwap() 関数を通じて実行されるトークン間の交換で構成されています。以下は、SwapRequest が GIVEN_OUT 交換タイプとして割り当てられたときの実行パスを概説しています(ComposableStablePool は BaseGeneralPool を継承していることに注意してください):

! 【画像】()

以下は、GIVEN_OUT 交換タイプにおける amount_in の計算を示しており、これは不変量 D に関連しています。

inGivenOut token x for y - 解く多項式方程式 // ax = 計算するための金額 // bx = トークン残高 x = bx + ax (finalBalanceIn)
D = 不変式 A = 増幅係数 // n = トークンの数 S = 最終残高の合計ですが、x
// P = 最終残高の積ですが x

               D D^(n+1)  

x ^ 2 + ( S - ---------- - D) * x - ------------- = 0
(A * n^n) A * n^2n * P

3. スケーリングと丸め

異なるToken残高間の計算を標準化するために、Balancerは以下の2つの操作を実行します:

  • アップスケーリング(Upscaling):計算を実行する前に、残高と金額を統一された内部精度に拡大します。

! 【画像】()

  • ダウンサイジング(Downscaling):結果を元の精度に戻し、方向性のある丸めを適用します(例えば、入力金額は通常、プールが不足して課金されないように上に丸められ、出力金額は頻繁に下に丸められます)。

! 【画像】()

明らかに、拡大と縮小は理論的には対になった操作であり、それぞれ乗算と除算です。しかし、これらの操作の実装には不一致があります。具体的には、縮小操作には divUp と divDown の2つの変種または方向があります。対照的に、拡大操作には mulDown という1つの方向しかありません。

この不一致の原因はまだ明らかではありません。_upscale() 関数のコメントによると、開発者は片方向の丸めの影響がごくわずかであると考えています。

// 拡大(Upscale)する際の丸めは必ずしも同じ方向になるわけではありません:たとえば、ある交換において、

// トークンの残高は切り上げるべきで、出力トークンの残高は切り捨てるべきです。これは、すべての金額を同じ方向に丸める唯一の場所です、

// この丸めの影響は最小限になると予想されています

// (そして_scalingFactor()が上書きされない限り、丸め誤差はありません)。

0x2 脆弱性分析

根本問題は、BaseGeneralPool._swapGivenOut() 関数内でのアップスケーリング操作を実行する際に実施される切り捨て操作に起因します。特に、_swapGivenOut() は _upscale() 関数を通じて swapRequest.amount を誤って切り下げます。この切り捨てられた値は、その後 amountOut として使用され、_onSwapGivenOut() を通じて amountIn を計算するために使用されます。このような動作は「丸めはプロトコルに有利な方法で適用されるべきである」という標準的な慣行に矛盾しています。

! 【画像】()

したがって、与えられたプール(wstETH/rETH/cbETH)に対して、計算された amountIn は実際に必要な入力を過小評価しています。これにより、ユーザーは少ない数量の一つの基礎資産(例えば wstETH)を別の資産(例えば cbETH)と交換でき、効果的な流動性の減少により不変量 D が減少します。したがって、対応する BPT(wstETH/rETH/cbETH)の価格は人為的に押し下げられ(deflated)、なぜなら $\text{BPT price} = \frac{D}{\text{totalSupply}}$ だからです。

0x3 攻撃分析

攻撃者は実行しました

二段階攻撃は、検出リスクを最小限に抑えるためのものである可能性があります:

  • 第一段階では、コアは単一の取引で実行され、即座に利益を得ることはありません。
  • 第二段階では、攻撃者は別の取引で資産を引き出すことによって利益を実現します。

第一段階はさらに二つの段階に分けることができます:パラメータ計算とバッチ交換。以下に、Arbitrum上の攻撃取引(TX)の例を使用して(これらの段階を説明します。

パラメータ計算段階

この段階では、攻撃者はオフチェーン計算とオンチェーンシミュレーションを組み合わせ、ハイブリッド安定プールの現在の状態(スケーリングファクター、拡大係数、BPTレート、交換手数料、その他のパラメータを含む)に基づいて、次の段階(バッチ交換)での各ジャンプのパラメータを正確に調整します。興味深いことに、攻撃者はこれらの計算を支援するために補助契約を展開しました。これは「フロントランニング」のリスクを減らすためかもしれません。

まず、攻撃者はターゲットプールの基本情報を収集します。これには各Tokenのスケーリングファクター、拡大パラメーター、BPTレート、および交換手数料の割合が含まれます。それから、彼らは精度損失を引き起こすために操作されたターゲットTokenの数である重要な値trickAmtを計算します。

ターゲットトークンのスケーリングファクター(scaling factor)を sF として、次のように計算します:

画像次のステージ(バルクスワップ)ステップ2で使用されるパラメータを特定するために、攻撃者は以下のcalldataを使用して補助コントラクトの0x524c9e20関数に対して後続のシミュレーション呼び出しを行います:

uint256[] バランス; プールトークンの残高(BPTを除く) uint256[] scalingFactors; // 各プールのトークンのスケーリングファクター uint tokenIn; // このジャンプがシミュレートする入力トークンのインデックス uint tokenOut; // このジャンプでシミュレーションされる出力トークンのインデックス uint256 amountOut; 出力トークンの予想数 uint256 amp; // プールの拡大パラメータ uint256料金; プールインターチェンジフィーの割合

返されたデータは:

uint256[] バランス; スワッピング後のプールトークンの残高(BPTを除く)

具体的には、初期残高と反復ループの回数はチェーン外で計算され、攻撃者の契約にパラメータとして渡されます(報告はそれぞれ 100,000,000,000 と 25)。各反復は三回の交換を実行します:

  1. スワップ1:スワップ方向を0→1と仮定して、ターゲットトークンの数をtrickAmt + 1にプッシュします。
  2. 交換 2:引き続き trickAmt を使ってターゲットトークンを交換すると、_upscale() 呼び出しでの切り捨てがトリガーされます。 320,000。

ご注意ください。StableMathの計算においてニュートン-ラフソン法が使用されているため、このステップは時折失敗する可能性があります。この状況を緩和するために、攻撃者は2回の再試行を実装し、各回のバックアップ値として元の値の9/10を使用しています。

攻撃者の補助コントラクトは Balancer V2 の StableMath ライブラリから派生しており、これは「BAL」スタイルのカスタムエラーメッセージが含まれていることから証明できます。

$d$ バッチ交換フェーズ

そして、batchSwap###( 操作は三つのステップに分解できます:

  1. ステップ 1:攻撃者は BPT )wstETH/rETH/cbETH( を基礎資産に交換し、1つのトークン(cbETH)の残高を切り上げの境界に正確に調整します(amount = 9)。これにより、次のステップでの精度損失の条件が整います。
  2. ステップ 2:その後、攻撃者は慎重に設計された数量(= 8)を使用して、別の基盤資産(wstETH)と cbETH の間で交換します。トークンの数量をスケールダウンする際に切り捨てるため、計算された Δx がわずかに小さく(8.918 から 8 へ)、Δy が過小評価される結果となり、不変量(D、Curve の StableSwap モデルから)が小さくなります。$\text{BPT price} = \frac{D}{\text{totalSupply}}$ のため、BPT 価格が人為的に押し下げられます。

! 【画像】)( 3. ステップ 3:攻撃者は、基盤となる資産を逆に BPT に換え、バランスを回復し、同時に押し下げられた BPT の価格から利益を得ます。

0x4:攻撃対損失

私たちは下表にこれらの攻撃とそれに対応する損失をまとめており、総損失は1.25億ドルを超えています。

! 【画像】)(

0x5 まとめ

この事件は、Balancer V2 プロトコルおよびそのフォークプロジェクトに対する一連の攻撃取引に関連しており、重大な財務損失を引き起こしました。最初の攻撃の後、複数のチェーン上で大量の追随および模倣取引が観察されました。この事件は、DeFi プロトコルの設計とセキュリティに関するいくつかの重要な教訓を浮き彫りにしています。

  • 丸め動作と精度損失:拡大(upscaling)操作で使用される一方向の丸め(切り捨て)と縮小(downscaling)操作で使用される双方向の丸め(切り上げと切り捨て)は異なります。同様の脆弱性を防ぐために、プロトコルはより高精度の算術を採用し、堅牢な検証チェックを実施する必要があります。「丸めは常にプロトコルに有利であるべき」という標準原則を遵守しなければなりません。
  • 脆弱性利用の進化:攻撃者は、検出を回避することを目的とした複雑な二段階の脆弱性利用を実行しました。第一段階では、攻撃者は単一の取引内でコアな利用を実行し、即時に利益を得ることはありませんでした。第二段階では、攻撃者は別の取引で資産を引き出すことで利益を上げました。これは再び、安全研究者と攻撃者との間の継続的な「軍備競争」を浮き彫りにしています。
  • 運営意識と脅威対応:この事件は、初期化および運営状態に関するタイムリーな警告の重要性、ならびに持続的または模倣攻撃による潜在的な損失を軽減するための積極的な脅威検出と予防メカニズムの重要性を強調しています。

運営とビジネスの継続性を維持しながら、業界の参加者は BlockSec Phalcon を最後の防御線として利用して、彼らの資産を保護することができます。BlockSec の専門家チームは、あなたのプロジェクトのために包括的なセキュリティ評価を行う準備が整っています。

本文リンク:

源:

BPT11.15%
原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • コメント
  • リポスト
  • 共有
コメント
0/400
コメントなし
  • ピン