Technical Background of Balancer V2 Composable Stable Pools Balancer V2 Composable Stable Pools のテクニカル背景 : : Pool Structure and How It Works Composable Stable Pools は、Curve の StableSwap モデルにインスピレーションを得た数学に基づいて構築されています。 What is a Composable Stable Pool? これらのプールは、USDCやDAI、またはStETHやETHなどのほぼ同じ値の資産を最小限のスライプで取引するように設計されています。 **What makes them “composable”? \ The pool’s LP token (BPT) is a standard ERC-20 token that can be reused across the ecosystem, for example, in other pools or as collateral. This allows liquidity to be seamlessly composed throughout the system. **How it works \ A Composable Stable Pool can hold multiple tokens, and its invariant DDD is calculated using the following polynomial equation: バランスの ポール(Curveからインスピレーションを得た)は、スワップを保持することで計算します。 (D) 可能な限り常時. スワップが起こるとき、トークンのバランスをこの変数を保持する新しい状態に移動します. 上記の方程式は You solve to get the あなたが解決しているトークンのうち、(D)は固定されている。 stable invariant quadratic new balance (x) 用語 (x):あなたが決済しているトークンの新しい(ポストスワップ)バランス。 (S):他のトークンの残高の合計(xを除く) (P):他のトークンの収益(xを除く) (D): pool invariant (targeted to remain constant across the swap) (スワップ全体で一貫することを目指す) (A): amplification parameter (flattens the curve → lower slippage for equal-valued assets) (n):プール内のトークンの数。 Intuition: we compress “all the other tokens” into two aggregates, (S) and (P). Enforcing “(D) stays constant” yields a . quadratic in (x) なんで四角形? 未知のトークンの新しいバランスを隔離し、残りを(S)および(P)に折ると、変数状態は(x)の第二度の多角形に減少します。 解決する という根を選ぶのは、 and (実行可能なバランスの範囲内) もう一つの根は、通常、ネガティブまたは無意味である。 Which root? positive economically valid シンプルな例 Setup (2 tokens, large A → very low slippage) 内部(スケールアップ)スタートバランス: token0 = 1,000,000; token1 = 1,000,000 トークンの数: n = 2 拡大:A = 1000 大型A、D ≈ 2,000,000 Action トークン0(EXACT_IN)の1万単位を追加します。 Quadratic to solve x^2 + (S - D/(A*n^n) - D)*x - D^(n+1)/(A*n^(2n)*P) = 0 どこ: で、 そして、 token1のポスト・スワップ・バランスを表す。 S = 1,010,000 P = 1,010,000 x Solution x ≈ 990,999.546 Amount out amountOut = 1,000,000 - 990,999.546 ≈ 9,000.454 Interpretation You put in 10,000 of token0 and receive ~9,000.45 of token1 → low slippage with large A. トークン0の10,000を投入し、トークン1の ~9,000.45を獲得します。 すべての数学では、18デシマルの内部単位を使用し、セキュリティのためにラウンドダウンを実装します。 使われている場所(高いレベル) EXACT_IN:あなたは入力トークンを増やし、対称トークンの新しいバランスを解決します(x);その旧バランスの違いは、金額です。 EXACT_OUT: you target a specific received amount; solve for the necessary (x) (and thus the input required). This path is more numerically sensitive (root-finding + rounding). このパスはより数値的に敏感です(root-finding + rounding)。 実践ノート すべてのバランスは、内部で18デシマル(スケーラード)で処理され、計算は通常、プールセーフになります。 より大きな(A)は曲線をより常数のようなものにします(安定したカップルのための小さな滑走);より小さい(A)は、常数製品の行動に近いです。 TL;DR: この方程式は、固定不変数(D)の下で、スワップ後に新しいトークンバランスを(x)与えるワークホースの平方です. The coefficients encode “the rest of the pool” via (S) and (P), while (A) and (n) set the shape/flatness of the stable curve. この方程式は、 それは、固定無変数(D)の下で、あなたがたに与える。 係数は(S)および(P)を通じて「残りのプール」をコードし、(A)および(n)は安定曲線の形状/平面性を設定します。 TL;DR: workhorse quadratic new token balance (x) プールはA トークンバランスの間で、捕獲された1 . balance relationship invariant D 交換すると、1つのバランスが上昇し、もう1つは下がり、プールはバランスを見つける。 そこで価格が現れる。 new balance that keeps D as constant as possible プールは、スケーリング因子を使用してトークンを18デシマルに正常化します。Upscale 操作は、バランスを内部の精度に調整し、ラウンドダウンを使用します。 Swap Types EXACT_IN (GIVEN_IN): 固定入力金額、出力計算。 EXACT_OUT (GIVEN_OUT): 固定出力金額、入力計算。 Vault と BatchSwapBalancer Vault はすべての操作を管理します。 BatchSwap は、1 つの取引で複数のスワップを組み合わせ、フラッシュローンのような「延期決済」を使用します。 1.利用分析 1.1 攻撃 2025年11月3日午前7時40分頃、特定のバランサーv2の安定プールは、バランサーとそのフォークで合計1億2000万ドルの損失をもたらした複雑な攻撃で標的となった。 The attack leveraged several circumstances: ターゲットプールの大半は、ComposableStablePool契約の例でした. 既知の為替レートまたは近い平等で一貫して交換する予定の資産のために設計された特別なプール。 Balancer Vault 契約の batchSwap 機能により、余分なデルタを決済する必要がある前に一時的なスワップが発生することを可能にします。 攻撃は低流動性のシナリオで利益を得た。攻撃者は大規模なスワップを準備しなければならなかったので、ポールのバランスを、あるいは他のトークンの低流動性に持ち込むことができた。 上記のすべては単に必要であるが、結論を出すことのできない状況であり、これが起こるために必要な唯一の状況が問題の根本原因であり、upscale 関数における円形行動である。 攻撃ベクターは、MetaStablePoolが攻撃を乗り越えた2021年7月16日に初めて導入されました。 同様の変更は、2021年9月1日、Commit 4e9e70aの線形プールに対して、そして、2021年9月20日、StablePhantomPoolのための commit f450760に対して、後にComposableStablePoolと改称された。 _scalingFactors 下記の問題説明では、なぜこのオーバーレードの導入が攻撃の中心だったのか説明します。 1.2 問題 Vault 契約の batchSwap 関数は、この攻撃の入力点です。 攻撃者は、ComposableStablePool のインスタンスをターゲットに、それへの呼び出しを作成しました。 ComposableStablePool の相互作用をもたらす Vault 契約の関連論理は、次のフローによって定義されます。 batchSwaps → 内部呼び出し _swapWithPools → 内部呼び出し 各 swap に対してプールを呼び出し _swapWithPool → _processGeneralPoolSwapRequest → 最終的に ComposableStablePool で onSwap 呼び出します。 ComposableStablePool に着陸すると、実行は onSwap ハック内で継続され、2つのことが起こります。 _scalingFactors 関数に呼び出します。 上記のサンプルトランザクションで定義したように _swapGivenOut に転送します。攻撃者は _swapGivenIn パターンを取ることを決定した場合がありますが、攻撃トランザクションで提供された入力は選択肢を明確に示します。 この2つの機能を見てみましょう。 スケールファクター function _scalingFactors() internal view virtual override returns(uint256[] memory) { uint256 totalTokens = _getTotalTokens(); uint256[] memory scalingFactors = new uint256[](totalTokens); for (uint256 i = 0; i < totalTokens; ++i) { scalingFactors[i] = _getScalingFactor(i).mulDown(_getTokenRate(i)); } return scalingFactors; } この機能は2つのことを行います: それは _getScalingFactor 関数が提案したように、任意の金額を固定された数十桁にスケールし、何を返しますか。 トークンの為替レートの要因は、スケーリング要因でそれを倍増し、1e18で分けます。 アップスケール function _upscale(uint256 amount, uint256 scalingFactor) pure returns (uint256) { /* Upscale rounding wouldn't necessarily always go in the same direction: in a swap for example the balance of token in should be rounded up, and that of token out rounded down. This is the only place where we round in the same direction for all amounts, as the impact of this rounding is expected to be minimal. */ return FixedPoint.mulDown(amount, scalingFactor); } これは単にそのスケーリング因子で量を倍増し、最後に1e18で分けるだけです。 問題は二つの事実にある: これらの関数は、スワップの方向に関係なく常にラウンドダウン(mulDown)を行います。 数値がスケーリングの数値より小さい場合は、正確性の損失は無視されません。攻撃者取引では、典型的な数値とスケーリング因子の値は、「17」スケーリングFactor: "1058132408689971699" 計算したら 「We Get , but since Solidity truncates decimals, this becomes 結果はA IN THE 機能です。 amount * scalingFactor / 1e18 17.98 17 0% net change _upscale すなわち、量を考慮して、 (平成18年度) 結果は、 Aを代表する 率を正しく反映している。 17,000000000000000000 17.988250950000000000 5.8% increase 同様に, for a token with (ほとんどのstablecoinsが持っているように) ダニエル ほぼ同じものに匹敵するもの。 . 6 decimals 17,000000 17.988250 5.8% positive change Truncation is maximized by making できるだけ大きいので、製品は1e18で割ると最大の精度を失います。 amount*scalingFactor mod 1e18 たとえば、下の表では、量=17と量=50の両方が、約0.90の絶対回転損失を生み出します。 例 Table 1. Examples of floor rounding error when scaling by a factor of 1.058132408689971699 amount upscale error %error %increase lost 17 17 0.98 5.76% 100% 50 52 0.90 1.80% 17% ... ... ... ... ... 17 17 0.98 5.76% 100パーセント 50 52 0.90 1.80% 17% ・・・ ・・・ ・・・ ・・・ ・・・ THE この機能は後でこれらの円形値を使用して、スワップの後、攻撃者がプールに負う金額を計算します. This value is artificially deflated, making the swap cheaper. これらは複雑であり、また、低流動性の状態が意欲的に得られるプールでこれが達成できる理由を正当化するものである。これは、ある程度の konvergence を確保する不変性のチェックによるものである。 _swapGivenOut _swapGivenOut 最終的に、イテレーションの数が高い場合、バッチSwapの後のデルタは膨らみ、プール内の資金の大部分を攻撃者に与える。 さらに、 _upscale in-line docstrings について、適切な観察があります。 /* Upscale rounding wouldn't necessarily always go in the same direction: in a swap for example the balance of token in should be rounded up, and that of token out rounded down. This is the only place where we round in the same direction for all amounts, as the impact of this rounding is expected to be minimal. */ A prior version of this comment had an additional note: /* …as the impact of this rounding is expected to be minimal (and there's no rounding error unless `_scalingFactor()` is overriden). */ これは重要なことなので、The 導入中 後に改名し、 正確に実施しているのは、 上記のオーバーレイドについて StablePhantomPool September 20, 2021 ComposableStablePool _scalingFactor 以前のバージョンでは、 , the 機能は、トークンデシマルの差だけを考慮したが、より新しい実装では、それはまた、トークンデシマルの差を含む。 根本的な変化を象徴する。 StablePool _scalingFactor exchange rate で指摘されたように、 機能のコメントで、コードは使用から進化した。 (例えば、 (二) この変化は、機能的に必要であるにもかかわらず、可能性を導入します。 そして、彼らと共に、新しい . _upscale unitary scaling factors 1e12 non-unitary exchange rates rounding errors attack vector ラウンドエラーを可能にすることは根源的な原因であったが、それを悪用するには、追加のプロトコルメカニックと特定の攻撃ステップを活用する必要があった。 Balancer's batchSwap は、バッチの終わりにのみネットで決まっている一時的な内部バランスを可能にします. これにより、攻撃者は、バッチ内の BPT を効果的に「貸し出し」して、BPT を保有する取引を終了する必要がなく、プールを操作します。 BPT(バランサー・ポール・トークン)は、バランサー・ポールの割合割合を表すERC-20です。 ターゲット化されたComposableStablePoolsを含むいくつかのプールデザインでは、BPTもプール資産として現れ、取引可能/交換可能です。 最初の段階では、BPTをトークン1とBPTをトークン2に繰り返し交換することによって、ポールトークンバランスを(例えば、WETH / osETH)非常に低いレベル(約100k)に押し上げました。 バランスが小さい場合、固定点のラウンドが支配的になります。目標は、フロア数学で捨てられた割合部分を最大化すること、すなわち、量を最大化するということです。Factor mod 1e18 は、製品が1e18 で分けるときに可能な限り多くの精度を失うようにします。 The exploit runs in repeating triplets of swaps: スワップのトリプルを繰り返します。 Prime:プールを次の操作でトランクが起こる状態に移動します。下のスクリーンショットでは、WETH を osETH に交換します。 Exploit: rounding loss を実現するスワップを実行します. スクリーンショットでは、osETH に対して 17 WETH のスワップを実行します. Reset: バランスを復元して、トリプルを再生できます。 スクリーンショットでは、osETH を WETH に交換します。 下記のトラックで示すように、重要なスワップはしばしばボールバランスを18と比べ17の金額を使用します。 セキュリティの最良の実践の推進:業界への教訓 この事件は、スマート契約セキュリティ監査の有効性について議論を呼び起こし、いくつかの評論家は、これらの監査が価値を提供しているかどうかを疑問視しているが、この感覚は挫折の瞬間に理解できるかもしれないが、セキュリティ監査がなぜ業界のベストプラクティスとなったのか、そしてセキュリティ監査の実践が過去10年間でリスクを軽減し、ユーザーを保護することに大きな影響を与えたのかを認識できない。 セキュリティ企業は毎年集団的に何百もの潜在的な取を防ぎます。OpenZeppelinだけでは、すべての監査で生産に到達する前に700以上の重大な脆弱性と高レベルの脆弱性が特定されています。これらの予防された災害はタイトルではありませんが、保護された価値の数十億を表しており、無数のユーザーが損失から救われています。高品質のセキュリティ監査はまた、開発チームが開発サイクルを通じてセキュリティの姿勢を向上させ、ブロックチェーンアプリケーションにさらなるエラーが導入される確率を急速に減らすのに役立ちます。 実際の教訓は、監査が非効率であることではなく、業界の監査慣行は、重要な価値を確保する複雑なプロトコルがどれほど迅速に進化するかをまだ把握していないことである。監査はしばしば孤立したレビューではなく継続的な取り組みとして範囲化されているため、コードベースが進化するにつれてコンテキストが失われる可能性があります。 2.1 業界標準として継続的セキュリティの確立 Balancer v2 は、2016 年にスマート コントラクト オーディションの実践を先駆けて以来、最も成功したセキュリティの結果が、プロトコルコードベース全体とそのすべての変更をカバーする継続的なセキュリティパートナーシップから来ていることを示しています。 セキュリティ研究者がプロトコルに連続的に取り組むことで、プロトコルのアーキテクチャ、エンジニアリングプロセス、および特定の設計決定がなぜ下されたのかを深く知ることができます。 Balancer v2 コードベースは、4 社の独立した監査会社によってレビューされたが、各社はプロトコルの異なる範囲に焦点を当てた。複数の監査員を関与させることは、欠けている脆弱性の可能性を減らすのに役立ちますが、少なくとも 1 つの長期的なセキュリティパートナーを維持することは、コードベースがどのように進化し、新しい変更が既存の論理とどのように相互作用するかをより深く、継続的に理解します。 2.2 より良いセキュリティ枠組みの構築 OpenZeppelinの契約は、セキュアなスマートコントラクトを構築するための事実上の基準となり、現在、生態系全体で転送される総価値が30兆ドルを超えています。 例えば、OpenZeppelinは、Blockchain Security Standards Council、Enterprise Ethereum Alliance、International Standards Organization(ISO)などの業界標準設定機関に貢献し、当社のチームとコミュニティが先駆けてきたセキュリティのベストプラクティスを業界全体に利用できるようにします。 We also engage with regulators and policymakers globally to ensure blockchain security best practices are promoted in relevant regulatory regimes. In particular, OpenZeppelin has engaged with the U.S. Department of Treasury, the U.S. Securities and Exchange Commission, the UK Financial Conduct Authority, and the French ACPR and AMF regarding the benefits of conducting comprehensive security audits on a regular basis. In addition, we have explored the potential to create a dedicated self-regulatory organization similar to auditors in other fields that we believe could help formalize security auditing standards and methodologies for blockchain technology, set quality and ethics requirements for auditors, and manage accreditation to certify qualified auditors, which could improve security outcomes and increase consumer confidence. 2.3 ブロックチェーンセキュリティエコシステムの強化 すべてのセキュリティ事件は、業界全体で改善を促進する貴重な洞察を提供します。Balancer v2の利用は、プロトコルがより価値があり、洗練されていくにつれて、プロトコルチームが継続的なセキュリティに投資することも、企業がそれをサポートするフレームワークを構築するために監査することも重要になります。