Notional Financeが整数オーバーフローの脆弱性により173万ドルのハッキング被害

iconMetaEra
共有
AI summary icon概要
2026年9月4日、Notional FinanceはEscrow契約における整数オーバーフローを悪用され、173万ドルの被害を受けました。この脆弱性は、ExchangeRate._convertToETH関数に存在し、適切なコラテラルなしにfCash保有資産が生成されることを可能にしていました。この出来事は、DeFi戦略におけるリスク対リワード比率の重要性を浮き彫りにしています。CryptoでTAを使用するトレーダーは、このような脆弱性が市場の動向を急速に変える可能性があるため、警戒を怠らないでください。

著者:九九

編集:77

背景

2026年9月4日、有名なデセントラライズド貸付プラットフォームNotional Financeが攻撃を受け、約173万ドルの損失を被りました。以下は、慢霧セキュリティチームによる本次攻撃イベントの詳細な分析です:

前提知識

Notional Finance V1では、fCashは満期日付きの現金債権と理解できます。cash receiverは満期日に受取を行い、cash payerは満期日に支払いを行います。プロトコルは这两种ポジションをPortfolioに記録し、フリーコラテラルチェックを通じてアカウントのポジション構築の健全性を判断します。

ERC1155Trade の safeTransferFrom は、資産の帳簿処理機能を担っています。入力された資産タイプが cash receiver である場合、コントラクトは Portfolios.mintfCashPair を呼び出し、payer には負債として記録し、receiver には同等の債権として記録します。この呼び出しは ERC1155 の転送のように見えますが、実際には fCash のペアによる鋳造が行われます。

新ポジションがPortfolioに書き込まれた後、フリーコラテラルの計算とチェックが必要です。RiskFramework契約は、まずpayerのfCash負債を符号付きint256に集計し、その後各通貨の残高をETHに換算して合計します。負数は支払いが必要な現金を、正数はアカウントが保有する現金または債権を表します。この計算結果により、取引が許可されるかどうかが決定されます。

ポジションが満期になると、PortfolioはEscrowのportfolioSettleCash関数を呼び出して、満期となったfCashを現金残高に変換します。その後、アカウントはEscrowから対応するDAIまたはUSDC資産を引き出し関数を用いて引き出します。

根本原因

今回の攻撃の核心的な脆弱性は、Escrow実装契約で使用されているExchangeRate._convertToETHにあり、その中のコードが符号付き整数の絶対値をそのままuint128に変換しています。

攻撃者は、同じペイラーによる2つの負債ポジションを構築し、それぞれの金額は1とuint128.maxであった。この2つの負債を合計すると、ちょうど2^128となる。ペイラーの支払いはリスク計算において負数として記録されるため、EscrowのconvertBalancesToETHに渡される重要なパラメータは-2^128となる。

しかし、本契約で使用されているSolidityのバージョンは0.6.xであり、その絶対値2^128はuint128に強制変換された後、オーバーフローして0になります。したがって、この負債はETH評価結果に含まれません。

最後に、mintfCashPair関数では、ペイヤーのフリーコラテラルがゼロ以上であることを要求するだけで、結果が0にオーバーフローした後でもこのチェックを通過できるため、資産が負債を十分にカバーしていないアカウントでもポジションを構築できる。

攻撃ステップの分析

1. 前置取引(0xe1589a19…d60a)において、攻撃者はまず複数の補助契約を作成し、ERC1155Trade 契約の setApprovalForAll 関数を呼び出して補助契約に承認を付与しました。また、CashMarket の2つの満期日を事前に照会し、後続の操作で必要な3つのAssetIdパラメータの値を計算しました。

2. 次に、攻撃者は ERC1155Trade コントラクトの safeTransferFrom 関数を呼び出し、キャッシュグループ ID が 2、満期日タイムスタンプが 1788480000(2026 年 9 月 4 日 8 時)である fCash ペアを 1 単位mintします。この処理では、内部関数 _upsertAsset が呼び出され、from アドレス(攻撃コントラクト)および to アドレス(受信コントラクト 1)の負債と予想収益がそれぞれ更新されます。

ペアの鋳造が完了後、Portfolios は攻撃契約のフリーコラテラルを即座にチェックしますが、最初の鋳造量が小さすぎるため、現在の為替レートと精度で ETH に換算するとゼロに丸められ、最初のチェックは通過します。

3. 攻撃者はその後、ERC1155Trade コントラクトの safeTransferFrom 関数を再び呼び出し、cashGroupId が 2 だが、満期タイムスタンプが 1796256000(2026 年 12 月 3 日 8 時)である fCash ペアを uint128.max の額面で鋳造した。

ここで一つの詳細があります。攻撃者は、満期日が異なる2つの異なるアドレスに債券資産をmintしました。これは、fromアドレスの負債を更新する際、債券資産が同じ場合、直接加算されるため、加算処理でオーバーフローが発生しrevertしてしまうからです(契約はsafeMathライブラリを使用しています)。

4. 第二次鋳造の対象である from アドレス(攻撃契約)と to アドレス(受信契約2)の負債と予想収益を更新した後、mintfCashPair 関数は freeCollateral 関数を呼び出して、from アドレスのネット抵当ポジションを計算し、それが 0 以上であることを確認します。

まず、RiskFrameworkコントラクト内のgetRequirement関数で、fromアドレスの2回の鋳造による負債の合計を加算します。

最終的な結果は -2^128 であり、次に Escrow コントラクトの convertBalancesToETH 関数が呼び出され、この値を ETH で評価します。convertBalancesToETH 関数は、計算処理のために ExchangeRate ライブラリの _convertToETH 関数を呼び出します。

_convertToETH 関数を追跡すると、まず balance の絶対値を取得し、その後 uint128 を呼び出して 256 ビットを 128 ビットに変換します。上記の from の負債合計は -2^128 であり、その絶対値である 2^128 を uint128() で強制変換すると上限を超えてオーバーフローし、0 になります。これにより、プロトコルは from アドレスの自由な抵当資産ポジションが 0 であり健全であると誤認識し、mintfCashPair 関数の最終チェックを通過してしまいます。

5. 次に、コントラクト2が受け取ったポジションを、さらに2つの補助コントラクトに分割しました。この2つのsafeTransferFromは依然としてmintfCashPair関数に到達します。しかし、この時点でのpayerは、2回目の鋳造時の受信コントラクト2であり、前ステップで得た巨大な期待収益ポジションを保有しています。リスク計算はこれを正の債権と見なすため、担保チェックを通過し、2つの補助コントラクトは、満期時に現金に交換可能なreceiver fCashを獲得しました。

6. 攻撃者はその後、前回の取引の両方の保有ポジションに対応する補助契約の債権を清算し、対応する資産の現金残高を増加させた後、Escrow契約のwithdraw関数を呼び出して資産を出金して利益を確定しました。

要約

この攻撃の鍵は、攻撃者が2つの個別のポジションを利用してpayerの負債合計を2^128にし、その後Escrowがこの負債をETHに換算する際に、型変換のオーバーフロー脆弱性を利用して結果を0に切り詰め、リスクチェックを回避した点にあります。

慢霧セキュリティチームは、型変換前に範囲チェックを実施し、type(uint128).max を超える結果は直ちに拒否することを推奨します。また、符号付き金額、精度スケーリング、資産額面に関連するすべての境界値に対して、極値テストを実施し、特に uint128.max、uint128.max + 1、および負数の絶対値の入力をカバーする必要があります。型変換処理には、Openzeppelin の SafeCast ライブラリを参照または使用することを推奨します。

免責事項: 本ページの情報はサードパーティからのものであり、必ずしもKuCoinの見解や意見を反映しているわけではありません。この内容は一般的な情報提供のみを目的として提供されており、いかなる種類の表明や保証もなく、金融または投資助言として解釈されるものでもありません。KuCoinは誤記や脱落、またはこの情報の使用に起因するいかなる結果に対しても責任を負いません。 デジタル資産への投資にはリスクが伴います。商品のリスクとリスク許容度をご自身の財務状況に基づいて慎重に評価してください。詳しくは利用規約およびリスク開示を参照してください。