過去1週間(2026年3月30日~2026年4月5日)に、BlockSecは9件の攻撃インシデントを検出し分析しました。総推定損失額は約2億8700万ドルでした。以下の表にこれらのインシデントをまとめ、各ケースの詳細な分析は後続のサブセクションで提供します。
| 日付 | インシデント | タイプ | 推定損失額 |
|---|---|---|---|
| 2026/03/30 | 未知のプロトコルインシデント | 不備のあるビジネスロジック | ~$10K |
| 2026/03/30 | WDGGトークンインシデント | アクセス制御 | ~$40K |
| 2026/03/31 | i6トークンインシデント | 不備のあるビジネスロジック | ~$273.8K |
| 2026/04/01 | Driftプロトコルインシデント | フィッシング攻撃 | ~$285.3M |
| 2026/04/01 | LMLステーキングプロトコルインシデント | 不備のあるビジネスロジック | ~$950K |
| 2026/04/01 | Tactileインシデント | 価格操作 | ~$12K |
| 2026/04/02 | SASトークンインシデント | 不備のあるビジネスロジック | ~$12K |
| 2026/04/03 | Unknown-EIP-7702インシデント | アクセス制御 | ~$17.2K |
| 2026/04/03 | Silo Financeインシデント | 設定ミス | ~$359K |
1. 未知のプロトコルインシデント
概要
2026年3月30日、BNB Chain上の未知のプロトコルが、不備のあるビジネスロジックにより約10,000ドルの損失を被りました。このプロトコルは、ユーザーの預金の一部をプラットフォームトークン「PSTART」の購入と流動性の追加に充てていました。これは、ユーザーが実質的に市場価格の変動に影響されるLPポジションを保有していたことを意味します。しかし、引き出し時に、プロトコルはLPの実際の償還可能価値に基づいて決済しませんでした。代わりに、過去の預金と定義済みのルールに基づいて固定額のステーブルコインを約束し続けました。その結果、強制的な投資を通じて資本をコミットした後、攻撃者は事前に合意された固定値で資金を引き出すことができ、LPポジションが負担すべき損失を実質的にプロトコルに転嫁し、最終的にゼロコストでの利益を達成しました。
背景
このプロトコルは以下のように機能します。ユーザーが「BUSD」を預金すると、プロトコルは預金額の一部を使って「PSTART」を購入し、流動性を追加します。生成された「LP」シェアは「Vault」によって保管されますが、プロトコルは内部台帳に、固定の日次利回りを示すユーザーへの注文を記録します。
その後、ユーザーは固定利回りを受け取ることができ、終了時に「Vault」は、基礎となる「LP」ポジションの実際の正味資産価値に基づいて厳密に償還するのではなく、定義済みのルールに従って元本と利回りを決済します。
脆弱性分析
この脆弱性は、非合理的なプロトコル(0x587984...73a43c)の設計に起因しています。決済ロジックが、基礎となる資産の実際の価値から切り離されています。
ユーザーが「BUSD」を預金した後、プロトコルはその一部を使用して「PSTART」を購入し、流動性を追加します。これは、ユーザーの実際の基礎となるポジションが、市場価格の変動に影響される「LP」エクスポージャーであることを意味します。しかし、ユーザーが終了する際、プロトコルは、その時点での「LP」の実際の償還可能価値に基づいて決済しません。代わりに、過去の預金額と定義済みの決済ルールに従って、固定額のステーブルコインを約束し続けます。
攻撃者は、フラッシュローンを使用して大量の資本を獲得し、その後繰り返し「deposit()」を実行することで、この欠陥を悪用しました。これにより、攻撃者はプロトコルに継続的に「PSTART」を購入させ、プールの資産構成を変更させ、それによって「PSTART」の価格を人為的に押し上げ、裁定機会を作り出しました。
攻撃者はその後、「withdraw()」を実行し、事前に約束された固定値で資金を償還しました。これにより、本来LPポジションが負担すべき損失を実質的にプロトコル自体に転嫁し、最終的にゼロコストでの利益を達成しました。
攻撃分析
以下の分析は、トランザクション0xf3b8...55e7に基づいています。
-
ステップ1:攻撃者はフラッシュローンを通じて約2,000,000e18の「BUSD」を獲得し、それをプールで19,013,120e18の「PSTART」と交換しました。
-
ステップ2:攻撃者は繰り返しコントラクトの「deposit()」関数を呼び出して資金をステークしました。各預金に対して、プロトコルは、流動性を追加するために使用される最終的なトークン対「BUSD」の比率がプールの現在の比率に近くなるように、どのくらいの「BUSD」を使用すべきかを計算しました。繰り返し預金することで、攻撃者は継続的に「BUSD」をプールに注入しましたが、「PSTART」の量はほぼ変わりませんでした。その結果、「PSTART」の価値は上昇し続けました。この段階で、攻撃者の預金を通じて取得された「LP」は、実際には損失を被って取得されていました。
-
ステップ3:攻撃者はその後、ステップ1で購入した「PSTART」をプールに売却しました。ステップ2でプールの「BUSD」準備金が増加したため、この交換により約2,010,655e18の「BUSD」が戻り、単一の攻撃サイクルで約10,655の「BUSD」の利益が生じました。
-
ステップ4:最後に、攻撃者はステップ2で開かれたすべてのステーキングポジションに対して「withdraw()」を実行しました。この時点では、これらのポジションに対応する資産の市場価値は、初期預金価値をはるかに下回っていました。通常の経済ロジックでは、全額償還は不可能であるはずです。しかし、プロトコルは、過去の預金額に基づいて償還可能な「BUSD」額を計算したため、攻撃者は以前の強制投資コストを損失を負担することなく全額回収することができました。

結論
このインシデントの根本原因は、プロトコルが市場価格の変動に影響されるLPポジションにユーザー資金を投資したにもかかわらず、過去の預金額と定義済みのルールに基づいて固定額の「BUSD」での決済を約束したことです。これにより、プロトコルの負債と基礎となる資産の実際の価値との間に乖離が生じました。
攻撃者は、この欠陥を悪用して繰り返し「deposit()」を使用し、プールの資産構造を変更して「PSTART」の価格を押し上げ、その後外部ポジションを通じて裁定を完了し、最後に「withdraw()」を使用して以前は損失が出ていたポジションを簿価で償還しました。このようにして、ポジション自体が負担すべき損失はプロトコルに転嫁され、最終的にリスクフリーな利益が可能になりました。
2. WDGGトークンインシデント
概要
2026年3月30日、BNB Chain上の「WDGG」トークンが約40,000ドルの損失を被りました。根本原因は、「burnFrom()」関数におけるアクセス制御の欠落でした。具体的には、「burnFrom()」関数は、任意のユーザーが任意のウォレットから「WDGG」トークンを燃焼させることを許可していました。攻撃者は、PancakeSwapプールから「WDGG」トークンを燃焼させ、その後「sync()」関数を呼び出してプールの「WDGG」準備金を削減し、続いて逆スワップを実行して利益を抽出することで、これを悪用しました。
背景
このインシデントは、単一のトークン「WDGG」に関連しています。これは、各取引ごとに手数料を課す配当分配トークンです。
脆弱性分析
「WDGG」トークンコントラクト(0x512de7...6b90c5)は、呼び出し元認証なしに「burnFrom()」を公開していました。その結果、任意のウォレットが、PancakeSwapプール自体を含む、任意の保有者から「WDGG」トークンを燃焼させることができました。PancakeSwapの公開呼び出し可能な「sync()」(記録された準備金を実際の残高に再調整する)と組み合わせることで、この欠陥により、正当な取引なしにプールの「WDGG」準備金を任意に削減し、定数積不変量を壊すことができ、プールを価格不均衡による裁定取引にさらしました。

「setWdgAddress()」における二次的な欠陥により、任意の呼び出し元が手数料免除アドレスを指定でき、この攻撃面から抽出できる利益をさらに最大化できました。

攻撃分析
以下の分析は、トランザクション0x2da5...0bd1に基づいています。
- ステップ1:攻撃者はまず、「setWdgAddress()」を呼び出して、自身のアドレスを手数料免除として設定し、その後の取引でトークンの取引手数料を回避できるようにしました。

-
ステップ2:攻撃者はその後、少量の「BNB」をPancakeSwapプールを通じて「WDGG」トークンと交換しました。
-
ステップ3: 「WDGG」を取得した後、攻撃者は「burnFrom()」を呼び出して、PancakeSwapペアアドレスから直接「WDGG」トークンを燃焼させました。
-
ステップ4:攻撃者はその後、「sync()」を呼び出し、ペアにその準備金を操作されたトークン残高に一致させるように強制しました。その結果、プール内の「WDGG」準備金はわずか1 weiに削減されました。

- ステップ5:プールの準備金が著しく歪んだため、攻撃者は逆スワップを実行し、価格の不均衡から利益を抽出しました。

結論
このインシデントは、最終的に「WDGG」トークンコントラクトの「burnFrom()」関数におけるアクセス制御の欠落によって引き起こされました。その結果、攻撃者はPancakeSwapプールから直接トークンを燃焼させ、「sync()」を通じてプールの準備金を操作し、結果として生じた価格の不均衡を利益のために悪用することができました。
3. i6トークンインシデント
概要
2026年3月31日、BNB Chain上の「i6」トークンが約273,800ドルの損失を被りました。原因は、「invest()」がプールのスポット価格を移動させる一方で、「withdraw()」が遅延したTWAPを通じて残高を決済し、両者を同じトランザクションで組み合わせることができたことです。攻撃者は、「invest()」でスポット価格をインフレさせ、「withdraw()」で古いTWAPで過剰な「i6」を償還し、インフレしたプールに「i6」を戻して売却することで利益を得ました。
背景
このプロトコルは次のように機能します。ユーザーが「invest()」を呼び出すと、「USDT」が預金され、PancakeSwapで「i6」を購入するために一部が使用されます。取得された「i6」は、残りの「USDT」と共に「USDT/i6」プールに流動性として追加され、生成されたLPトークンは燃焼されます。「USDT」建てのユーザーおよび紹介者の残高がプロトコルによって記録されます。
「withdraw()」が呼び出されると、プロトコルはユーザーの累積価値を「USDT」建てで計算し、プロトコルによって維持されるTWAP価格(「twapPrice」)を使用して「i6」に変換します。
脆弱性分析
プロトコルコントラクト(0x1cb36b...2a18a)の根本原因は、「invest()」が「i6」の購入と流動性の追加の副作用として「USDT/i6」プールのスポット価格を変化させる一方で、「withdraw()」が時間ウィンドウが経過した後にのみ更新される、プロトコルによって維持されるTWAP(「twapPrice」)を使用して、「USDT」建ての累積残高を決済することです。これらの2つの関数が同じトランザクションで実行されることを防ぐものは何もありません。
「invest()」の呼び出しが、後続の「withdraw()」がまだ更新されていないTWAPを読み取るのと同じトランザクション内でスポット価格をインフレさせる可能性があるため、両者は実質的に同じプールの状態に対して2つの異なる価格を認識します。「withdraw()」を通じて償還された「USDT」建ての残高は、古い、はるかに低い価格で「i6」で支払われます。これは、各「i6」がプール自体でさらに多くの「USDT」で実現可能であるにもかかわらずです。このギャップにより、プロトコル内の累積「USDT」残高は、内部決済とライブプールとの間の利用可能なスプレッドに変換されます。
攻撃分析
以下の分析は、トランザクション0xc1b9...2f16に基づいています。
-
ステップ1:攻撃者はまず、フラッシュローンを通じて270,000 WBNBを獲得し、それをVenusに担保として供給し、大量のUSDTを借入しました。攻撃者はまた、攻撃コントラクトAを0xda49に、ヘルパーコントラクトBを0x096aにデプロイしました。
-
ステップ2:攻撃コントラクトは最初の「invest()」を実行しました。このプロセス中に、プロトコルはまず531,489e18の「USDT」を使用して234,188e18の「i6」を購入し、次に354,326e18の「USDT」と72,607e18の「i6」をプールに追加しました。その結果、プールのスポット価格は、約1.05159 USDT/i6から約4.89287 USDT/i6に急速に上昇しましたが、プロトコルに記録された「TWAP」は依然として1.05159のままでした。

-
ステップ3:攻撃者はその後、124,014,184e18の「USDT」をヘルパーコントラクトBに転送しました。ヘルパーコントラクトBは、「referrer = A」で「invest()」を呼び出しました。このステップにより、プロトコルは再び大規模な「USDT -> i6」購入と「addLiquidity()」を実行することを余儀なくされ、プールの準備金はスポット価格が約15,528 USDT/i6に相当する新しい状態に押し上げられました。ただし、新しい時間ウィンドウが経過しなかったため、プロトコルは「TWAP」をそれに応じて更新しませんでした。
-
ステップ4:2回目の「invest()」が完了した後、紹介者として機能する攻撃コントラクトAは、すぐに「USDT」建ての紹介報酬の対象となりました。攻撃者はその後、「withdraw()」を呼び出しました。プロトコルは古い「TWAP」を使用して支払われる「i6」の量を計算し、そのトークンを独自の残高から転送しました。その結果、合計5,896,508e18の「i6」が支払われました。
-
ステップ5:攻撃者は「i6」を受け取った後、すぐに「swapExactTokensForTokensSupportingFeeOnTransferTokens」を呼び出して、5,896,508e18の「i6」すべてをプールに売却し、代わりに125,177,224e18の「USDT」を獲得しました。これらの「i6」トークンは、古い「TWAP」約1.05159 USDT/i6を使用して決済され、攻撃者によって約15,528 USDT/i6に押し上げられたプールのスポット価格に対して売却されたため、攻撃者は2つの価格間の巨大なスプレッドを直接実現することができました。
-
ステップ6:フラッシュローンを返済した後、攻撃者は273,802e18の「USDT」を保持しました。これが攻撃からの実際の利益でした。
結論
根本原因は、スポット価格に影響を与える関数(「invest()」)とTWAPで決済される関数(「withdraw()」)が単一のトランザクション内で組み合わせ可能であったことで、両者が同じプールの状態に対して異なる価格を認識できるようにしたことです。
このクラスの欠陥を防ぐには、AMMインタラクションと遅延価格設定を組み合わせるプロトコルは、補完関数が基盤となるプールのスポット価格を移動させるのと同じトランザクションで残高をTWAPで決済することを避け、代わりに古いまたは派生した価格ではなく、プールのライブ実現可能価値を基準にするべきです。
4. Driftプロトコルインシデント
概要
2026年4月1日(UTC)、Solana上のDriftプロトコルが約2億8530万ドルの被害に遭いました。根本原因はスマートコントラクトのバグではなく、マルチシグ承認プロセスの崩壊、2-of-5のセキュリティ評議会にタイムロックがなく、Solanaの永続的なnonceメカニズムが組み合わさったことでした。これにより、事前に収集されたマルチシグ承認は、攻撃者がそれらを実行するまで無期限に有効なままでした。数週間の段階的準備の後、攻撃者は5人の署名者のうち2人に、永続的なnonceアカウントにバインドされた悪意のあるガバナンストランザクションに事前に署名させ、その後それらを提出して管理者権限を奪取し、偽の担保資産(「CVT」)を導入し、そのオラクルの価格をインフレさせ、引き出し制限を緩和し、Drift Vault(JCNCMF...XJfrw)を通じて実際の資産を枯渇させました。
背景
DriftプロトコルはSolana上のDeFiプロトコルであり、マージン取引、貸付、スポット市場、デリバティブをサポートしています。管理者変更、市場作成、オラクル設定、リスクパラメータ更新、引き出し限度調整などの高権限操作は、単一の秘密鍵ではなく、Squadsマルチシグフレームワークによって管理されています。攻撃当時、Driftのセキュリティ評議会は、2-of-5の閾値設定で、タイムロックなしで運用されていました。これは、5人の署名者のうち2人が、管理アクションを即時効果で承認できることを意味します。このシステムのセキュリティは、署名キーの保護だけでなく、完全な承認パイプラインの整合性にも依存します。つまり、どのトランザクションが作成され、署名者が何を承認したと信じていたか、そして最終的に実行された命令がそのレビューコンテキストと一致していたかです。
別個に、Solanaの永続的なnonceアカウントは、短命のブロックハッシュを専用アカウントに格納された永続的なnonceに置き換えます。これにより、署名されたトランザクションは、nonceがアドバンスされるまで無期限に有効なままになります。このメカニズムは、オフライン署名や遅延送信などの正当なユースケースのために設計されていますが、トランザクションが署名された時点とオンチェーンで実行された時点を切り離すことで、重要な攻撃プリミティブをもたらします。署名者が永続的なnonceトランザクションを承認すると、nonce権限者が手動でnonceアカウントをアドバンスしない限り、承認は取り消せません。
脆弱性分析
根本原因はスマートコントラクトのバグではなく、Driftのガバナンス設定における3つの構造的な弱点です。これらが組み合わさることで、ソーシャルエンジニアリングの機会が2億8530万ドルの枯渇につながりました。第一に、永続的なnonceは、暗黙の署名期限切れの安全ネットを削除しました。通常のブロックハッシュベースのトランザクションでは、不正な署名者の承認は、迅速に実行されるか、狭いウィンドウ内で無害に期限切れになり、協調的な悪用範囲を制限します。永続的なnonceはこの制約を解消します。2人のセキュリティ評議会の署名者が、誤解を招く署名要求を通じて悪意のあるガバナンストランザクションに事前に署名させられた場合、それらの署名は無期限に悪用可能であり、攻撃者に実行タイミングの完全な制御を与えます。
第二に、管理アクションに対するタイムロックがないため、事前に署名されたトランザクションが送信されると、管理者移行は即座に有効になり、検出または介入のウィンドウがなくなりました。第三に、管理者ロールの範囲は、新しい担保市場の作成、オラクルソースの切り替え、および引き出し制限の緩和を単一の特権パスで実行できるほど広かったため、単一のガバナンス乗っ取りが、追加の承認バリアなしに任意の資産を実際の資金抽出に変換するだけで十分でした。
攻撃分析
攻撃は3つの明確なフェーズで展開されました:攻撃前ステージング(攻撃者が偽の担保資産を製造し、誤解を招く署名要求を通じてガバナンスアクセスを取得するために数週間運営)、ガバナンス乗っ取り(2つの事前に署名された永続的なnonceトランザクションが急速に送信されて管理者権限を奪取)、および資金抽出(攻撃者がプロトコルのパラメータを操作し、プロトコルの貸付経路を通じて実際の資産を枯渇させた)。以下の図は、これらの3つのフェーズにわたる実行フローを示しています。
-
フェーズ1(攻撃前ステージング):3月11日に始まり、攻撃者はTornado Cashから10 ETHを引き出し、CarbonVote Token(「CVT」)をデプロイし、7億5000万ユニットをミントし、Raydiumに流動性を供給し、ウォッシュトレードを使用して約1ドルの人工的な価格履歴を構築しました。並行して、3月23日までに4つの永続的なnonceアカウントが作成されました。2つはDriftセキュリティ評議会のメンバーにリンクされ、2つは攻撃者によって制御されていました。これは、5人の署名者のうち少なくとも2人が、永続的なnonceアカウントにリンクされたトランザクションにすでに署名していたことを示しています。3月27日、Driftはメンバー変更のため計画されたセキュリティ評議会の移行を実行し、以前に収集された署名を無効にしました。しかし、3月30日までに攻撃者は新しい構成の下で必要な閾値を再取得しました。これは、オンチェーンガバナンス変更の積極的な監視とリアルタイム適応を示しています。
-
フェーズ2(ガバナンス乗っ取り):4月1日、UTC約16:05、Driftが保険基金から正当なテスト引き出しを実行した約1分後、攻撃者は4つのスロット離れた2つの事前に署名された永続的なnonceトランザクションを送信しました。最初のトランザクション(2HvMSg...2C4H)は、悪意のある管理者移行提案を作成し承認しました。2番目のトランザクション(4BKBmA...RsN1)は、それを承認および実行しました。「AdvanceNonceAccount」で始まり、保存されたnonceをアクティブ化し、「proposalApprove」と「vaultTransactionExecute」を通過し、最終的に「UpdateAdmin」を呼び出して管理者権限を攻撃者制御のアドレスに転送しました。
-
フェーズ3(資金抽出):完全な管理者権限で、攻撃者は「CVT」の担保市場を作成し、攻撃者制御のオラクルに切り替えてその帳簿価格をインフレさせ、主要な資産市場の引き出し制限を引き上げまたは削除しました。攻撃者はその後、過大評価された「CVT」を大量にプロトコルに預け、約12分間にわたって31回の迅速な引き出しを実行し、「USDC」、「JLP」、「SOL」、「cbBTC」、「USDT」、「wETH」、「dSOL」、「WBTC」、「JTO」、「FARTCOIN」を枯渇させ、合計損失額は約2億8530万ドルでした。これは、攻撃者の引き出しアカウント(HkGz4K...pZES)に基づいて計算されています。

結論
このインシデントの根本原因は、スマートコントラクトの脆弱性やキーの侵害ではなく、マルチシグ承認プロセスの崩壊、永続的なnonceベースの遅延実行、およびタイムロックのない管理パスの組み合わせでした。通常は数分で期限切れになるはずだった事前に収集された承認は無期限に悪用可能であり、送信されると、管理者乗っ取りとその後の資金抽出は介入ウィンドウを残しませんでした。
このクラスのリスクを軽減するには、単なる署名キーの保護だけでなく、完全な承認パイプラインを保護し、高権限操作にタイムロックを強制し、永続的なnonceのような遅延実行メカニズムを、より高い署名閾値、時間制限付きまたは取り消し可能な承認、および無期限に有効な署名済みトランザクションに対する制限を必要とする、独立した脅威サーフェスとして扱う必要があります。
5. LMLステーキングプロトコルインシデント
概要
2026年4月1日、BNB Chain上の「LML」ステーキングプロトコルが約95万ドルの被害に遭いました。根本原因は、報酬計算ロジックの一貫性の欠如でした。報酬変換は、3600秒の更新クールダウンにロックされた保存された「LML/USDT」価格を読み取っていましたが、支払われる「LML」はライブAMM価格で償還可能であり、両者の間に偏差チェックはありませんでした。攻撃者は、フラッシュローンを使用してプールスポット価格をインフレさせ、EIP-7702コード委任を使用して単一のトランザクションで11の事前にステークされたEOAの報酬を一括請求し、古い保存価格で過剰な量の「LML」を受け取り、それを著しく歪んだプールに売却して利益を上げました。
背景
「LML」はBNB Chain上のステーキングプロトコルであり、ユーザーは「APower」コントラクトを通じて「BNB」をステークして報酬として「LML」トークンを獲得します。報酬は「USDT」建てで計算され、配布前にプロトコルに保存された「LML/USDT」価格を使用して「LML」量に変換されます。「LML/USDT」価格は、「updatePrice()」によって更新されます。これはAMMスポット価格を読み取りますが、更新間の3600秒のクールダウンを強制します。報酬請求は、「msg.sender」に基づいて「APower」の「receive()」を通じてトリガーされるため、元のステーキングアドレスのみが自身の報酬を請求できます。
脆弱性分析
ステーキングコントラクト(0xbe9713...adce19)のコア欠陥は、報酬の蓄積と報酬の償還が、同じプールの2つの異なる価格にアンカーされていることです。両者の間に一貫性チェックがありません。報酬式reward += (10^18 * base_reward) / stored_priceは、「_prices[]」から「LML」ペイアウトを計算します。これはプロトコルに保存された「LML/USDT」価格ですが、「updatePrice()」によって3600秒のクールダウン後にのみ更新されます。しかし、支払われる「LML」はライブAMMスポット価格で即座に償還可能です。このクールダウンウィンドウ内でスポット価格を移動させる外部アクティビティは、凍結された蓄積価格とライブ売却価格との間にギャップを開けます。そのギャップが不合理になった場合に、そのギャップを拒否するものはコントラクトに何もありません。



2番目の構造的欠陥は、報酬ソースの補充方法にあります。「PROOF」コントラクトの「LML」残高が請求の支払いに不十分な場合、「swapBack()」は「super._transfer(swapPair, PROOF, deficit)」を呼び出し、それに続いて「sync()」を呼び出してそれを補充します。これにより、「LML」がLPペアの準備金から直接移動され、ペアの保存状態が再調整され、通常の交換を経由しません。このパスはペアの価格発見をバイパスするため、それをトリガーする各請求は、オフセットトークン流入なしにペアの「LML」準備金を削減し、保存された価格とライブ売却価格との間のギャップを機械的に広げます。


攻撃分析
以下の分析は、トランザクション0x805d...5b47、0x70f7...3572に基づいています。
-
ステップ1:攻撃者は、Moolahからのフラッシュローン、VenusおよびMoolah Pool(「WBNB」を担保として使用)からの借入、PancakeSwap V4、複数のV3プール、およびV2プールからのフラッシュローンを通じて、大量の「USDT」と「WBNB」を収集しました。この資本は、「LML/USDT」ペア価格を操作するために必要でした。
-
ステップ2:攻撃者は「LML」トークンコントラクトの「swapAndTrans()」を呼び出し、コントラクトに蓄積された「LML」手数料を「USDT」と交換しました。これにより、「LML」コントラクト自体の「LML」残高が枯渇しました。これは、その後の報酬配布がLPペアから「swapBack()」を通じて「LML」を引き出す必要があることを意味します。

- ステップ3:攻撃者はPancakeRouter「swapExactTokensForTokensSupportingFeeOnTransferTokens」を通じて「USDT」を「LML」と交換し、受信者をデッドアドレスに設定しました。購入された「LML」トークンは、攻撃者が受け取るのではなく燃焼されました。唯一の目的は、ペアから「LML」を枯渇させ、AMM上の「LML」価格をインフレさせることでした。攻撃者はトークン自体ではなく、価格の歪みだけが必要でした。

- ステップ4:攻撃者は以前に11のEOAアドレスを使用してステーキングプロトコルに預金していました。「APower」の「receive()」は「msg.sender」に基づいて「_claimReward(msg.sender)」をトリガーするため、報酬は預金アドレス自体によってのみ請求できます。11のEOAの報酬を単一のトランザクションで請求するために、攻撃者はEIP-7702を使用してこれらのEOAにコードを設定し、攻撃者のメインコントラクトによってコントラクトとして呼び出せるようにしました。各EOAは「transfer(rst, fte)」関数を実行し、少量の「BNB」をAPowerに送信して「receive()」、「_claimReward(EOA)」をトリガーしました。各請求内で:「updatePrice()」はスキップされました(3600秒のクールダウンが満たされなかったため、「stored_price」は過去の低い値のままでした)。「updateUser()」は古い低い価格を使用して報酬を計算しました。「sendMining()」は「PROOF」からAPowerに「LML」を転送し、次に「swapBack()」をトリガーして、LPペアから「LML」を引き出し、「sync()」を呼び出すことでPROOFを補充しました。これにより、ペアの準備金がさらに削減されました。最後に「claimReward()」がEOAに「LML」を配布し、各EOAはその受け取った「LML」を攻撃コントラクトに転送しました。


-
ステップ5:攻撃者は、蓄積された「LML」を、現在著しく枯渇したプールを通じて、非常にインフレした価格で「USDT」にスワップしました。
-
ステップ6:すべてのフラッシュローン、借入、および手数料を返済しました。残りの利益を転送しました。
結論
根本原因は、ステーキングコントラクトにおける報酬の蓄積と償還の不一致です。支払い額は、3600秒のクールダウンにロックされた保存された「LML/USDT」価格から計算されますが、ライブAMM価格を追跡する「LML」で決済され、両者をリンクする偏差チェックはありません。「swapBack()」補充パスは、各請求でLPペアから直接「LML」を枯渇させることでこの欠陥を増幅し、処理される請求が多いほど、凍結された保存価格とライブ売却価格との間のギャップが機械的に広げられます。
AMM派生価格から報酬を計算するステーキングプロトコルは、請求時に保存価格と現在のスポット価格との間の偏差チェックを強制し、ギャップが安全な閾値を超えた場合にリバートすべきです。また、通常の交換パス外でLP準備金を変更する補充メカニズムを避け、古い価格設定による損害を制限する価格発見をバイパスするメカニズムを避けるべきです。
6. Tactileインシデント
概要
2026年4月1日、Polygon上のティアード預金プロトコルであるTactileが約12,000ドルの損失を被りました。根本原因は、預金と引き出しの決済ロジックの一貫性の欠如でした。入金と出金の両方が「CES」の現在のスポット価格に対して計算され、内部シェアは元のミント時の資産価値の記録を持っていませんでした。攻撃者は、預金前にスポット価格をインフレさせて過剰なシェアを取得し、その後、引き出し前に価格を低下させてシェアあたりの「CES」をより多く償還し、ヘルパーコントラクト全体でサイクルを繰り返して利益を抽出することで、これを悪用しました。
背景
TactileはPolygon上のティアード預金プロトコルです。ユーザーは、選択したティアに応じて、支払いコントラクトに「CES」を預金します。必要な預金額は、「CES」の現在のスポット価格とティア構成から計算され、ユーザーはポジションを表す内部会計シェアでクレジットされます。引き出し時、記録されたシェアは、元の預金額ではなく、出口時のスポット価格を使用して「CES」に変換されるため、ユーザー残高は実際には固定資産額ではなく、価格依存の会計単位として追跡されます。
脆弱性分析
支払いコントラクト(0x9153e1...09b654)のコア欠陥は、預金と引き出しが、それらをリンクする不変のアンカーなしに、2つの異なる時点で同じスポット価格オラクルに対して決済されることです。預金時、コントラクトはgetActualPrice()を読み取り、現在の価格に基づいて預金された「CES」を内部シェアに変換します。引き出し時、同じシェアは、償還時のスポット価格を使用して「CES」に変換されます。
シェア自体は、ミントされた価格または資産額の記録を持たないため、これら2つの時点間のスポット価格の移動は、CESの支払額とCESの支払額との間の不一致に直接変換され、プロトコルの会計は、基礎となる資産価値ではなく、価格パスに完全にさらされます。

攻撃分析
以下の分析は、トランザクション0xc321...da74に基づいています。
- ステップ1:攻撃者はまず、Uniswap V3フラッシュプールから55,365e18の「CES」を借入し、資金を5つのヘルパーコントラクトに配布しました。各ヘルパーはまず6,426e18の「CES」を受け取り、次に
deposit(12)を呼び出しました。このプロセス中、各ヘルパーはまずgetPriceForLevel(12)をクエリし、次に現在の価格に基づいてこの預金に必要な「CES」額を準備しました。


- ステップ2:5つのヘルパーすべてが最初の
depositラウンドを完了した後、攻撃者は「DEX」に300,000 CESをダンプし、「bank」が使用する価格を1.067585から0.688542に引き下げました。その後、5つのヘルパーは順番にwithdrawを実行し、以前に高価格で作成されたシェアを現在の低価格で「CES」に償還しました。各ヘルパーは9,427e18の「CES」を受け取りました。

-
ステップ3:最初の
withdrawラウンドを完了した後、攻撃者は取得した相手方資産を「CES」にスワップし、価格を再び上昇させました。その後、攻撃者はステップ2~3を繰り返しました。 -
ステップ4:最終的に、複数の攻撃サイクルを経た後、フラッシュローンとフラッシュ手数料166.097975017841805126 CESを返済した後、攻撃者は567,736e18のCESを利益として残しました。
結論
このインシデントの根本原因は、Tactileが預金と引き出しの両方を操作可能なスポット価格に対して決済し、預金時の資産額または価格に会計シェアをアンカーしなかったことです。これにより、内部会計は、エントリーと出口の間の価格変動に完全にさらされました。
ボラティリティのある資産に対してシェアのようなポジションを発行するプロトコルは、各シェアをミント時の具体的な資産額または価格にアンカーすべきです。これにより、償還は、ライブオラクルに対して再価格設定するのではなく、元の経済的価値を再現します。決済関数が現在の価格を参照する必要がある場合は、時間加重またはその他の操作耐性のあるソースを使用し、決済呼び出しと同じトランザクションで実行される取引によって移動できる同じスポット価格を読み取ることを避けるべきです。
7. SASトークンインシデント
概要
2026年4月2日、BNB Chain上の「SAS」トークンが約12,000ドルの被害に遭いました。根本原因は、トークンのカスタム転送ロジックの欠陥でした。LPプールへの「SAS」の送信は、グローバルなsellBurnカウンターをインクリメントするだけで、その後の通常の転送でプールから直接「SAS」を燃焼させ、「sync()」を呼び出して準備金を書き換えることができました。すべてAMMの交換ロジックを経由せずに実行されました。攻撃者は、売りによってsellBurnを蓄積し、無関係な通常の転送をトリガーしてプールから「SAS」を燃焼させ、その準備金を1 weiに押し下げ、その後残りの「SAS」を逆スワップして利益を得ることで、これを悪用しました。
背景
「SAS」はBNB Chain上のデフレショナリートークンであり、PancakeSwap V2プールの上に構築されたカスタム転送ロジックを備えています。そのtransfer()関数は2つのパスを区別します。1つは宛先がLPプールである場合にトリガーされる売却パスで、転送された金額でグローバルなsellBurnアキュムレータをインクリメントします。もう1つは通常の転送パスで、sellBurnがゼロでない場合に、LPプールから直接「SAS」を燃焼させ、その後「sync()」を呼び出して準備金を新しいオンチェーン残高に一致させます。この2つのパスは、累積的な売却圧に応じてプールの「SAS」準備金を削減するデフレメカニズムとして連携するように設計されています。
脆弱性分析
「SAS」トークンコントラクト(0xbfa266...3d91c6)のコア欠陥は、デフレメカニズムがtransfer()にどのように配線されているかです。 「SAS」がLPプールに送信されると、コントラクトは転送された金額でグローバルなsellBurnアキュムレータをインクリメントします。その後、後続の通常の転送で、sellBurnがゼロでない場合、コントラクトは_burnFromPair()を呼び出してLPプールから直接「SAS」を燃焼させ、それに続いて「sync()」を呼び出して、プールの準備金をオンチェーン残高に一致するように書き換えます。
問題は、この燃焼と同期パスが、AMMの交換ロジックを経由せずにプールの準備金を書き換えることです。 sellBurnがプールへの転送によって増加すると、無関係な通常の転送で燃焼と同期がトリガーされ、プールのSAS準備金がゼロに近づき、その後通常の交換で収穫できる大きな価格の歪みが生じます。



攻撃分析
以下の分析は、トランザクション0x878e...adc5に基づいています。
-
ステップ1:攻撃者はフラッシュローンで「WBNB」を借入しました。
-
ステップ2:攻撃者は「WBNB」を「SAS」と交換しました。

-
ステップ3:攻撃者はコントラクトをデプロイし、
constructor()で攻撃ロジックを実行しました。これは、トークンコントラクトがtransfer()の送信元にホワイトリスト登録されたアドレスまたはEOAを必要としたため、プロトコルのis_contract()チェックをバイパスするために使用されました。


- ステップ4:攻撃者はプールに「SAS」を転送し、売却パスをトリガーして
sellBurnを蓄積しました。

- ステップ5:攻撃者は2番目のコントラクトをデプロイし、再びその
constructor()内で、通常の転送を開始しました。ステップ4からsellBurnがすでにゼロでなかったため、この転送は関数_burnFromPair()をトリガーしました。これはLPプールから直接「SAS」を燃焼させ、その後関数sync()を呼び出して、「SAS」準備金を1 weiに削減しました。

- ステップ6:攻撃者は逆スワップを実行し、残りの「SAS」を利益のために売却しました。
結論
このインシデントの根本原因は、「SAS」トークンのカスタム転送ロジックの欠陥でした。通常の転送がLPプールから直接「SAS」を燃焼させ、その準備金を削減された残高に同期させることができたため、累積的な売却活動をプールの「SAS」準備金の任意の削減に変換し、そこから通常の交換を通じて収穫できる大きな価格の歪みにつなげることができました。
トークンは、外部のAMMプールにアクセスして、通常の交換パス外でその準備金を変更すべきではありません。デフレ設計が本当にプールからの燃焼を必要とする場合、燃焼とそれに伴うsync()は、信頼されたキーパーやレート制限付きスケジュールなど、厳密に制御された内部トリガーにバインドされる必要があります。任意のユーザー転送に依存するのではなく。
8. Unknown-EIP-7702インシデント
概要
2026年4月3日、BNB Chain上のEIP-7702による委任コードを有効にしていたユーザーアカウントが、約17,200ドルの被害に遭いました。委任されたコードは、適切なアクセス制御のないpancakeV3SwapCallback()関数を公開していました。攻撃者は、このコールバックを細工されたコールデータで直接呼び出し、被害者アカウントにトークンを攻撃者制御のアドレスに転送させました。
背景
被害者EOAは、EIP-7702タイプ-4トランザクションを使用して委任コードを設定し、アカウントがスワップ関連ロジックを実行できるようにしました。しかし、委任された実装には、本来は正規のPancakeSwap V3プールコールバック中にのみ呼び出されるはずだった公開pancakeV3SwapCallback()関数が含まれていました。
脆弱性分析
根本原因は、委任されたコントラクト(0x02C809...aEDbAE)のpancakeV3SwapCallback()関数におけるアクセス制御の欠如です。
正しいUniswapV3/PancakeV3コールバック設計では、コールバックはmsg.senderが期待される正規プール(ファクトリー+トークンペア+手数料から導出されるか、信頼できるプールリストに対して検証される)であることを確認する必要があります。この場合、その検証が欠落していたため、外部の呼び出し元がコールバックを直接呼び出すことができました。
コールバックはそれをホストするアカウントからトークン転送を実行するため、欠落しているmsg.senderチェックは、正のamount0Delta/amount1Deltaを持つ任意の外部呼び出しがコールバック内の支払いパスに入り、実際の交換が発生せずにトークンを被害者アカウントから移動させることを意味します。
攻撃分析
以下の分析は、トランザクション0x5b2c...4261に基づいています。
- ステップ1:攻撃者は、細工されたパラメータで
pancakeV3SwapCallback()を直接呼び出し、コールバック転送ロジックをトリガーして、被害者のトークンを攻撃者制御のアドレスに移動させました。


結論
このインシデントは、EIP-7702アカウントに厳密なコールバック認証なしでスワップコールバックロジックをデプロイしたことによって引き起こされました。pancakeV3SwapCallback()にはアクセス制御がなかったため、コールバックは任意の外部呼び出し元によって呼び出され、正当なスワップが発生せずに被害者アカウントからトークンを移動させるために使用されました。
V3スタイルのコールバックを実装するコントラクトまたは委任されたEIP-7702コードの場合、開発者は、コールバックが転送ロジックに入る前に、msg.senderが正規のPancakeV3プール(信頼できるファクトリー、トークンペア、および手数料ティアから導出される)であることを検証する必要があります。
9. Silo Financeインシデント
概要
2026年4月3日、Arbitrum上のSilo FinanceのsoUSDCボールトが約359,000ドルの被害に遭いました。根本原因は3つの欠陥の収束でした。不変のwstUSRオラクルは、市場価格が約0.12に崩壊した後でもトークンを約1.133で価格設定していましたが、soUSDCの供給キャップメカニズムは、ボールト自体の預金のみを制限し、外部預金は制限しませんでした。また、totalAssets()会計の欠陥は、対応するsoUSDCシェアをミントせずに、外部でクレジットされたbUSDCシェアをカウントしました。攻撃者は、receiver=soUSDCでゼロキャップのwstUSR市場に直接USDCを預金することでボールトのシェア価格をインフレさせ、過大評価されたwstUSR担保に対して同じUSDCを借り入れ、インフレした評価額で以前取得したsoUSDCシェアを償還しました。不足分は、引き出しキュー内の他の健全な市場から引き出されました。
背景
Silo Financeは、Arbitrum上のリスク分離型貸付プロトコルです。各Silo市場は、2方向の貸付ペア(例:wstUSR/USDC)です。借り手は担保(wstUSR)を預け入れ、貸付資産(USDC)を借入し、貸し手はUSDCを預け入れ、利息を獲得します。貸し手が特定の市場にUSDCを預金すると、その市場の預金シェアトークンを受け取ります。借り手が担保を預金すると、コラテラルシェアトークン(例:bwstUSR-149)を受け取ります。
soUSDCは、複数のSilo市場の上に位置し、USDC貸付を統合するSiloVaultです。ユーザーはsoUSDCにUSDCを預金し、soUSDCシェアを受け取ります。その後、ボールトは、アロケーターによって設定された供給キャップに基づいて、承認されたSilo市場に預金されたUSDCをルーティングし、ボールト自体は、預金した各市場のbUSDCシェアを保有します。ユーザーがsoUSDCシェアを償還すると、ボールトはtotalAssets()を使用してシェアがUSDCでどれくらいの価値があるかを計算します。これは、引き出しキュー内のすべての市場を反復処理し、各市場でのボールトのbUSDCシェア残高を合計します。その後、ボールトは、償還者に支払うために、基盤となる市場からUSDCを引き出します。
wstUSR(Wrapped Staked USR)は、Resolvによって発行されたUSRステーブルコインのステーキングデリバティブです。Resolvが侵害された後、USRはペッグを失い、stUSRもペッグを失い、wstUSRの二次市場価格は約0.12に崩壊しました。しかし、ChainlinkのwstUSRフィードは、wstUSR/stUSR交換レート(約1.133)のみを追跡しており、プロトコルは暗黙的に1 stUSR = 1 USDを仮定していたため、オラクルはwstUSRを約1.133で価格設定し続けました。これは市場現実に対して約10倍のギャップです。
脆弱性分析
wstUSR/USDC市場のオラクルアドレスは、SiloConfigで不変としてハードコードされており、交換できません。オラクルコントラクト(0x836a1a...04425e)自体は、ChainlinkV3Oracleです。その基盤となるChainlinkフィード(説明:「wstUSR/stUSR交換レート」)は、wstUSRからstUSRへのラップ比率(約1.133)のみを追跡しており、二次市場価格は追跡していません。プロトコルは暗黙的に1 stUSR = 1 USDを仮定しているため、wstUSRを約1.133で価格設定しています。USRがペッグを失った後、stUSRもペッグを失い、wstUSRはオープン市場で約0.12に崩壊しましたが、オラクルは依然として約1.133を報告し続けており、約10倍の過大評価でした。


プロトコルはこのリスクを部分的に認識していました。wstUSR市場のsoUSDCの供給キャップは0に設定されていました。これは、ボールトが自発的にそこにUSDCをルーティングしないことを意味します。しかし、このキャップはボールト自身の内部的なdeposit()呼び出しのみを制限します。wstUSR_Market.deposit()は任意のreceiverパラメータを受け入れるため、誰でもUSDCを直接wstUSR市場に預け入れ、結果のbUSDCシェアをsoUSDCのアドレスにクレジットできます。これにより、供給キャップを完全に回避できます。
これにより、コアとなる悪用パスが作成されます。bUSDCシェアがこのような外部預金を通じてsoUSDCの残高に着地すると、totalAssets()はそれらをカウントします。これは、すべての市場を反復処理し、ボールトの実際のシェア残高を読み取ります。ポジションが自発的に入力されたかどうかのチェックはありません。一方、ボールト自体のミントロジックが呼び出されなかったため、これらの外部でクレジットされたポジションに対応する新しいsoUSDCシェアはミントされません。結果として、totalAssetsは増加しますが、totalSharesは同じままとなり、soUSDCシェア価格がインフレします。




攻撃分析
以下の分析は、トランザクション0xf77a...f3e1に基づいています。
攻撃者はまず、二次市場で(1トークンあたり約0.12で)wstUSRを購入しました。
-
ステップ1:Morphoから約4,236,352の
USDCをフラッシュローンしました。オラクルによる誤った価格設定だけでは不十分です。wstUSR市場にはUSDC流動性がゼロでした(キャップ=0、soUSDCはそこに預金しませんでした)。したがって、過大評価された担保に対して借り入れられるものはありませんでした。フラッシュローンは、後続の預金と寄付のステップに必要な資本を提供します。 -
ステップ2:
wstUSRをwstUSR市場に担保として預け入れ、bwstUSR-149を受け取りました。これはステップ5の借入の準備です。オラクルは13,797のwstUSRを約15,633(それぞれ1.133で)と評価しますが、攻撃者はわずか約1,656しか支払いませんでした。

- ステップ3:
soUSDCボールトに約4,222,007のUSDCを預け入れ、soUSDCシェア(全供給量の約91.5%)を受け取りました。ボールトは、このUSDCを既存の健全な市場(wstUSR市場ではなく、キャップ=0のため)にルーティングします。これらのsoUSDCシェアは、ステップ6で利益を抽出するための手段です。攻撃者がより多くのシェアを保有するほど、シェア価格がインフレしたときに利益を得られます。

- ステップ4:約14,344の
USDCを直接wstUSR市場にwstUSR_Market.deposit(receiver=soUSDC)経由で預け入れ、soUSDCにbUSDC-149をミントしました。結果のbUSDCシェアは、攻撃者ではなくsoUSDCのアドレスにクレジットされました。これはコア操作です。soUSDCのtotalAssets()は、これらのbUSDCシェアを顔価(約14,344USDC)で含んでいますが、ボールト自体の預金ロジックが呼び出されなかったため、新しいsoUSDCシェアはミントされません。totalAssetsは増加しますが、totalSharesは同じままとなり、soUSDCシェア価格がインフレします。同時に、これは以前は空だったwstUSR市場にUSDC流動性を作成し、次のステップで必要となります。

- ステップ5:ステップ2で預け入れた担保を使用して、
wstUSR市場から約14,344のUSDCを借入しました。オラクルは担保を約15,633と評価するため、最大LTVの92%では、攻撃者は約14,344を借りることができます。これにより、ステップ4で寄付されたUSDCが回収されます。借入と寄付は現金で中立です。しかし、wstUSR市場は完全に枯渇しました。すべてのUSDCは借入られ、ほとんど価値のないwstUSR担保に裏打ちされた、ほとんど価値のないローンが残されました。soUSDCは依然としてtotalAssets()でbUSDCシェアを顔価で保持しています。

- ステップ6:ステップ3で取得したすべての
soUSDCシェアを償還しました。シェア価格はステップ4の寄付によりインフレしているため、攻撃者は約4,235,143のUSDCを受け取りました。これは、ステップ3で預金した4,222,007よりも約13,136多くなります。ボールトはwstUSR市場からの引き出しを試みますが、流動性がない(ステップ5で借入済み)ため、引き出しキュー内の他の健全な市場から不足分を引き出します。ここで損失が発生します。他のsoUSDC預金者の市場からの実際のUSDCが、インフレした償還をカバーするために転送されます。



- ステップ7:フラッシュローンを返済しました。
32回のループ後、soUSDCはwstUSR市場でbUSDCポジションを保持しており、顔価は約359,000ドルですが、価値がその数分の一しかないwstUSR担保に裏打ちされています。利用率100%、実質的に回復不可能な不良債権が、残りのsoUSDC預金者に負担されています。
結論
このインシデントは、ステーキング交換レートを追跡するオラクル(ペッグを失った資産の市場価格ではなく)、totalAssets()で外部でクレジットされたポジションをシェアをミントせずにカウントするボールト会計システム、およびボールト自体の預金のみを制限し、外部預金は制限しない供給キャップメカニズムの組み合わせによって引き起こされました。SiloConfigにオラクルアドレスが永久に不変であったため、問題が明らかになった後の緊急修正を防ぎました。
貸付市場を統合するボールトプロトコルは、totalAssets()がボールト自身の預金操作を通じて入力されたポジションのみをカウントし、外部でクレジットされたシェア残高はカウントしないようにする必要があります。オラクルアドレスは永久に不変であるべきではありません。基礎となる資産がペッグを失った場合に価格フィード更新のための緊急ガバナンスメカニズムが存在すべきです。



