過去1週間(2026/04/06 - 2026/04/12)に、BlockSecは4件の攻撃インシデントを検出し分析しました。総推定損失額は約92万8600ドルです。以下の表にこれらのインシデントの概要を示し、各ケースの詳細な分析は後続のセクションで提供します。
| 日付 | インシデント | タイプ | 推定損失額 |
|---|---|---|---|
| 2026/04/05* | Denariaインシデント | 丸め非対称性&安全でないキャスト | 約16万5600ドル |
| 2026/04/07 | HBトークンインシデント | ビジネスロジックの欠陥&価格操作 | 約19万3000ドル |
| 2026/04/07 | Squid Multicallインシデント | 任意のコール | 約51万7000ドル |
| 2026/04/11 | XBITインシデント | アクセス制御の問題 | 約5万3000ドル |
*Denariaインシデントは先週のレポートではカバーされていませんでしたが、完全を期すためにここに含めました。
Web3のための最高のセキュリティ監査人
ローンチ前の設計、コード、ビジネスロジックを検証
今週から、各レポートの冒頭で1つのインシデントをハイライトします。選択は必ずしも損失額に基づくものではありません — 新しいプロトコルの設計、巧妙な攻撃手法、またはコミュニティへのより広範な教訓のために選ばれることがあります。
今週のハイライト
Denariaインシデント
永久DEXのDenariaは、複雑なコードロジックに裏打ちされた斬新な会計メカニズムを導入しました。しかし、監査後のリファクタリングで丸め非対称性が導入され、微妙なエッジケースである負の値が発生する可能性があり、最終的には安全でないキャストにヒットして天文学的な価値の抽出を可能にしました。
2026年4月5日、DenariaのLinea上の永久DEXが、約16万5600ドルの損失で悪用されました。根本原因は、getLpLiquidityBalance()における2つの連鎖的な欠陥でした。LP残高会計への監査後リファクタリングにより丸め非対称性が導入され、わずかに負の中間値が発生する可能性があり、さらに安全でないint256からuint256へのキャストが、この負の値をリバートする代わりにサイレントにほぼ最大値の符号なし整数にラップしました。攻撃者は、片側LP預け入れとロングトレードを通じてこれを悪用し、その後、人工的に膨張したPnLをVaultから引き出しました。
背景
DenariaはLinea上の永久DEXで、動的な仮想AMMを中心に構築されています。取引と決済を2つのコンポーネントに分離しています。PerpPair市場はユーザーポジションとLP会計を管理し、Vaultは担保を保持し実現されたPnLを決済します。
PerpPairにおけるLPの所有権は、明示的なトークン残高では表されません。代わりに、プロトコルは、資産側と安定側という2つの簿記コンポーネントで構成される内部会計行列から、各LPの状態を再構築します。資産側は、価格変動に対するプールのエクスポージャーのLPのシェアを追跡し、安定側は、プールの安定通貨建て価値のシェアを追跡します。これら2つのコンポーネントは連携して、LPの価値がどのように追跡され決済されるかを決定します。
重要ですが、これらのコンポーネントは静的なスナップショットとして格納されていません。取引が発生するたびに、PerpPairはグローバル流動性状態を更新し、各LPの再構築された残高は、累積グローバル値とLPのエントリポイントスナップショットとの差から導出されます。この会計メカニズムは、元のシェアベースのアキュムレーターを直接残高追跡に置き換えた、監査後のリファクタリングで導入されました。しかし、リファクタリングされた減算パスは、特定の取引シーケンスの下で再構築されたLPコンポーネントがわずかに負になる原因となる丸め非対称性を導入しました。
脆弱性分析
脆弱なPerpPairコントラクト(0xb683...36ae17)には、2つの連鎖的な欠陥が含まれています。
- リファクタリングされた会計における丸め非対称性。 直接残高追跡を導入した監査後のリファクタリングにより、減算再構築パスに丸め非対称性が作成されました。特定の取引シーケンスの下では、丸め後のグローバル累積値がLPのエントリポイントスナップショットよりもわずかに小さくなる可能性があり、減算によってゼロではなく小さな負の結果が生じました。理論的には、この値はゼロまたはゼロに近いべきでした。この非対称性は、減算会計の一般的な性質ではなく、このリファクタリングされた実装に特有の欠陥でした。

- 安全でない符号付きから符号なしへのキャスト。
getLpLiquidityBalance()では、再構築されたLP残高コンポーネントが、検証なしにint256からuint256にキャストされました。Solidityでは、負のint256をuint256にキャストしてもリバートせず、値は2^256 moduloでラップされ、-1のような小さな負の数はほぼ最大値の符号なし整数(2^256 - 1)に変わります。この再構築された残高が決済のためにcalcPnL()にフィードされたため、負の入力は巨大なLPポジションとして解釈され、攻撃者は人工的に膨張した利益を実現してVaultから資金を引き出すことができました。


どちらか一方の欠陥だけでは悪用されることはありませんでした。丸め非対称性はわずかに負の値を生成するだけで、通常のint256算術では無視できる誤差として単純に表現されるだけでした。しかし、その負の値が保護されていないキャストに達すると、ほぼ最大値の符号なし整数にラップされました。その後の境界チェックにより、ラップされた値はプールの総資産側流動性にキャップされ、オーバーフローは市場の資産側全体に対する請求に効果的に変換されました。
攻撃分析
以下の分析は、攻撃トランザクション0xcb0744...0c606447に基づいています。
-
ステップ1:攻撃者はAaveのフラッシュローンを通じて
60,000USDCを借入しました。 -
ステップ2:ヘルパーアドレスが
30,000USDCを担保として預け入れ、19,980の安定トークンによる安定通貨のみのLPポジションを追加しました。安定側のみに預け入れることで、ヘルパーは資産側のLPコンポーネントがゼロ近くから始まることを保証し、負の領域に移行しやすくしました。 -
ステップ3:2番目のヘルパーアドレスが
15,000USDCを預け入れ、100,000のノミナルロングポジションを開設し、liquidityMの更新を引き起こして主要な丸めエラーを導入しました。プールの流動性に対するノミナルサイズの大きさは、取引ごとの丸め影響を増幅し、最初のヘルパーの再構築された資産側残高をゼロ未満に押し下げました。 -
ステップ4:その後、最初のヘルパーは
realizePnL()を呼び出しました。LP残高の再構築中、負のlpAssetBalanceはほぼ最大値のuint256にラップされました。この大きな値は市場の資産側全体の流動性にキャップされ、非常に膨張した利益を生み出しました。実質的に、プロトコルはLPが市場の資産側全体を所有していると信じました。 -
ステップ5:攻撃者は膨張したPnLをVaultから引き出しました。

残りのVault流動性が枯渇するまで、同じパターンが繰り返されました。フラッシュローンを返済した後、攻撃者は約16万5600ドルの利益を実現しました。
結論
このエクスプロイトは、最終的に符号付きから符号なしへの変換における境界検証の欠如によって引き起こされました。直接的な修正は簡単です。ベアキャストをSafeCast.toUint256()に置き換えることです。これは、ラップするのではなく負の入力でリバートします。
より広範には、このインシデントは、外部レビューをバイパスする監査後のリファクタリングのリスクを示しています。公式のポストモーテムによると、丸め非対称性は、チームが元のリファクタリングでアキュムレーターを直接残高追跡に置き換えた後の最終的な外部監査で導入されました。リファクタリングはオーバーフローの懸念を解決しましたが、内部テストで捕捉されなかった新しいエッジケースを作成しました。プロトコルがコア会計ロジックをリファクタリングする場合、新しいコードパスはセキュリティクリティカルとして扱われ、特に再構築された値がPnL決済または引き出しロジックに直接フィードされる場合は再監査されるべきです。
今週のその他のインシデント
HBトークンインシデント
2026年4月7日、BNB Chain上の、購入/販売フックが埋め込まれたカスタムERC-20トークンであるHBが、約19万3000ドルで悪用されました。根本原因は報酬決済ロジックの欠陥でした。トリガーされると、swapBack()が呼び出され、PancakeSwapペアから直接HBリザーブが削除され、次にsync()が呼び出されてプールが再価格設定されました。攻撃者がペアのHBの大部分を買い占めた後、その後のswapBack()実行により残りの流動性がさらに減少し、スポット価格が急騰しました。その後、攻撃者はUSDTの不均衡に大きな金額で、HBのわずかな量を売却し、サイクルを繰り返してペアが枯渇するまで続けました。
背景
HBは、BNB Chain上のカスタムERC-20トークンで、_transfer()に購入および販売フックが埋め込まれています。ユーザーがAMMペアから購入すると、_handleBuy()がコストベース情報を記録します。ユーザーが販売すると、_handleSell()はペアの状態に応じて、異なる税金および決済パスに分岐します。
このトークンには、swapBack()をトリガーできる報酬決済メカニズムも含まれています。通常のルーターを介したスワップを実行するのではなく、swapBack()はHBをPancakeSwapペアからPROOFアドレスに直接転送し、次にペアにsync()を強制して再同期させます。これにより、コントラクトは通常のAMM取引フロー外でペアのHBリザーブを縮小し、プールの価格を即座に引き上げることができます。
脆弱性分析
HBトークンコントラクト(0x62ce...87a4b0)の根本的な欠陥は、swapBack()が、リザーブやルーターを介したスワップからではなく、AMMペアから直接トークンを調達していたことでした。swapBack()は報酬決済パスから到達可能であったため、非取引コードパスがペアリザーブを直接変更し、スポット価格を変化させることができました。

ペアのHBリザーブが低い場合、swapBack()の呼び出しは残りのHBをさらに減らし、価格の歪みを増幅させ、極端に高い価格でわずかな量のHBを販売することを可能にします。
攻撃分析
以下の分析は、攻撃トランザクション0x19671f...d71594edに基づいています。
-
ステップ1:攻撃者はVenusから大量の資金を借入しました。
-
ステップ2:攻撃者は約
1,496HBをトークンコントラクトに転送し、コントラクトのHB残高を増加させて、後続のswapBack()がペアからより多くの量を引き出せるようにしました。 -
ステップ3:わずかな量の
HBをPancakeSwapペアに転送することにより、攻撃者は_swapAndLiquify()をトリガーし、トークンコントラクトが保持していた約4,163HBを10USDTとスワップし、攻撃者の請求可能なHB報酬を増加させました。

- ステップ4:次に、攻撃者は
72,117,360USDTを費やして73,608,753HBを購入し、ペアにはほとんどHB流動性が残らなくなりました。

- ステップ5:次に、攻撃者は報酬不足パスをトリガーしました。報酬を支払うために、トークンは
swapBack()を呼び出し、PancakeSwapペアから追加のHBを引き出し、sync()を強制してHB価格を急騰させました。

- ステップ6:攻撃者は直接
USDTをペアに転送してUSDTリザーブを補充し、歪んだ価格でわずか0.000582HBを37,582,322USDTで売却しました。
ステップ6を繰り返してHBトークンを歪んだ価格で売却することにより、攻撃者はプールからほぼすべてのUSDTを抽出しました。
結論
HBトークンインシデントは、報酬ロジックがAMMリザーブを直接変更することを許可する危険性を示しています。リザーブに影響を与える関数は、報酬決済パスから到達可能であってはならず、プロトコルはセキュリティクリティカルな制御フローで、内部トークン残高とAMMリザーブ会計を混同することを避けるべきです。内部でプールを操作した後のスポットAMM価格設定に依存する設計は、本質的に価格操作に対して脆弱です。
Squid Multicallインシデント
2026年4月7日、Squidユーザーは、承認に関連するインシデントで複数のチェーンにわたって約51万7000ドルを失いました。ユーザーは、意図したSquid Routerの代わりに誤ってSquidMulticallコントラクトを承認しました。これにより、攻撃者は、承認されたコントラクトに対して任意の外部コールを実行できる、承認不要のSquidMulticall.run()関数を呼び出すことができました。したがって、攻撃者は、コントラクトに承認されたあらゆる許可を利用して、それを承認したユーザーに対してトークンのtransferFrom()コールを実行することができました。
背景
Squidの通常のフローでは、ユーザーはSquid Routerを承認すべきであり、SquidMulticallは実行ヘルパーとしてのみ機能します。ヘルパーコントラクトは、ルーティングロジックの一部としてバッチコールを実行するように設計されていますが、ユーザーが直接トークン転送を承認する支出者であってはなりません。
ERC-20の許可チェックは支出者アドレスに対してのみ実行されるため、ユーザーの承認と無制限の任意のコール機能を組み合わせたコントラクトは、危険な承認シンクを作成します。承認されると、そのコントラクトは、誰かがそのコールを制御できる場合、汎用的なトークン引き出しベクトルになる可能性があります。
脆弱性分析
このインシデントは、スマートコントラクトの脆弱性によって引き起こされたものではありません。損失は、2つの条件が同時に発生したことによって生じました。Squid Routerの代わりにSquidMulticallをターゲットとした誤った承認、およびrun()の承認不要な設計が、任意の呼び出し元からの任意のターゲットとcalldataを受け入れたことです。
SquidMulticallは、入力が信頼されたルーティングロジックによって構築されるRouterのフローの後続ステップとして、バッチコールを実行することを意図しています。意図されたとおりに使用された場合、承認不要な設計はリスクを伴いません。しかし、不適切な承認はそれを完全に変えます。MEVボットはライブの許可を検出しました。run()を細工されたcalldataで呼び出し、transferFrom(victim, attacker, amount)を呼び出し、被害者のさらなるアクションなしに各チェーンで承認されたトークンを枯渇させました。

攻撃分析
このインシデントは、BNB Chain、Arbitrum、Optimism、Avalanche、Baseにわたるユーザーに影響を与えました。以下の分析は、攻撃トランザクション0x81d0c4...9b1301e9に基づいています。
-
ステップ1:被害者(0xacc0...f40e98)は、意図したSquid Routerの代わりに誤って
SquidMulticallを承認しました。 -
ステップ2:MEVボットはこの許可を検出し、細工されたcalldataで
SquidMulticall.run()を呼び出しました。 -
ステップ3:任意のコールを通じて、
SquidMulticallはtransferFrom(victim, attacker, amount)を呼び出し、被害者のウォレットから承認された資産を転送しました。

結論
このインシデントは、ユーザー向けの承認フローと共存する、承認不要の任意のコールコントラクトのリスクを示しています。直接的な原因は誤った承認であり、SquidMulticallが制限のない呼び出し元、任意のターゲット、および任意のcalldataを受け入れたため、誤って向けられたあらゆる承認は、簡単に悪用可能になりました。実行ヘルパーコントラクトを使用するプロトコルは、呼び出し元制限を追加するか、そのような関数が許可するコールターゲットを制限することを検討すべきであり、そうすれば、不適切な承認が簡単に武器化されることを防ぐことができます。
XBITインシデント
2026年4月11日、BNB Chain上のXBITトークンが約5万3000ドルで悪用されました。根本原因は、XBITVaultにおけるフェイルオープンアクセス制御の欠陥でした。transfer()関数の認可チェックは条件付きでした — xbitContractがゼロでない場合にのみmsg.sender == xbitContractを強制し、それ以外の場合はサイレントにパスしました。bindXBIT()がコントラクトを初期化するために呼び出されたことがなかったため、この欠陥は恒久的に露呈し、任意の呼び出し元が、XBIT/USDT PancakeSwapペアを含む、あらゆるアドレスからXBIT残高を移動できるようになりました。攻撃者はこれを利用してペアからXBITを枯渇させ、その後、XBITのわずかな量をプールに繰り返し売却して、不均衡に大きな量のUSDTを獲得しました。
背景
XBITVaultは受動的な財務省コントラクトではありません。これは、XBITトークンシステムの残高と許可のバックエンドであり、transfer()、approve()、mintForXBIT()のようなトークンライクな関数を公開しています。意図された設計では、オーナーは最初にbindXBIT()を呼び出して、xbitContract、pancakePair、pairContract、xbitDecimalsを設定することによってVaultを初期化する必要があります。初期化後、機密性の高い状態変更関数は、バインドされたXBITコントラクトによってのみ呼び出し可能になると想定されていました。言い換えれば、Vaultのセキュリティモデルは、公開使用前の初期化の成功に依存しています。
脆弱性分析
重要な欠陥は、脆弱なXBITVaultコントラクト(0xc879...42391a)におけるアクセス制御が条件付きであることです。transfer()関数は、xbitContract != address(0)の場合にのみmsg.sender == xbitContractをチェックします。これは、xbitContractが設定されていない場合、関数はリバートせず、代わりに誰でも呼び出し可能になります。残高は_balancesに格納されているため、ソースアドレスに十分な残高がある限り、外部呼び出し元は任意のアドレスから任意のアドレスにXBITを移動できます。

意図された初期化パスはbindXBIT()でしたが、呼び出されなかったため、Vaultは初期化されていないフェイルオープン状態のままでした。結果として、実質的に無制限の任意の残高転送プリミティブとなりました。

攻撃分析
以下の分析は、攻撃トランザクション0xbc877f...4df1b694に基づいています。
-
ステップ1:非制限的な
transfer()関数を通じて、攻撃者は対応するUSDTを提供せずに、XBIT/USDTペアから1,526,216.569XBITを移動しました。 -
ステップ2:攻撃者は
sync()を呼び出し、ペアのXBITリザーブをわずか1〜2単位に縮小しました。 -
ステップ3:ペアに
XBIT流動性がほぼゼロになった後、攻撃者は繰り返しXBITを売却し、約53,112USDTをペアから枯渇させました。

結論
このインシデントは、初期化に依存するアクセス制御チェックがフェイルオープンしたことによって引き起こされました。xbitContractが設定されていない場合、transfer()は制限されておらず、bindXBIT()が呼び出されなかったため、Vaultは恒久的に公開の任意の残高転送プリミティブを公開していました。特権関数は、初期化が完了するまでリバートすべきであり、デプロイメント時のバインディングステップは、運用上の仮定ではなく、オンチェーンで強制される前提条件であるべきです。



