先週(2026/07/13 - 2026/07/19)、EthereumおよびSolanaにおいて合計約$1.35Mの損失をもたらした注目すべきセキュリティインシデント2件を紹介します。
| 日付 | インシデント | 種別 | 推定損失 |
|---|---|---|---|
| 2026/07/15 | BarnBridge | ガバナンスの不備 | ~$776K |
| 2026/07/16 | DeFiTuna | ヘルスチェックの欠陥 | ~$570K |
- DeFiTuna: ポジションのヘルスチェックが、ゼロでない債務を抱えていてもアセット価値がゼロであれば健全と判定してしまう欠陥があった。攻撃者はコントロールされたスワップルーティングと流動性の低い別のプールを使用してこの欠陥を突き、不良債権ポジションを作り出した。
- BarnBridge: 廃止されたガバナンスシステムが悪用され、重要なプロトコル設定が改ざんされ、ユーザーが承認した資金が流出した。
Best Security Auditor for Web3
Validate design, code, and business logic before launch
今週のハイライト:DeFiTuna
根本原因は、ポジションのヘルスチェックにおけるゼロ値分岐の欠陥にあった。アセット価値がゼロで約$570Kの未返済債務があるポジションが健全と判定されてしまった。攻撃者はこの欠陥を、流動性の低い別のプールにスワップをルーティングすることで引き起こしたが、ヘルスチェックこそが結果として生じた不良債権を検出すべき制御機構であった。
2026年7月16日、Solana上のレバレッジドスポットポジションをサポートする貸付プロトコルDeFiTunaが、約$570KのUSDCを悪用された [1]。根本原因は、ポジションのヘルスチェックにおけるゼロ値分岐の欠陥であり、アセット価値がゼロで債務がゼロでない場合でもポジションを健全と受け入れてしまった。攻撃者は担保ゼロでレバレッジドポジションを開設し、プロトコルのバルトからUSDCを借り入れ、攻撃者がコントロールする流動性の低いプールにスワップをルーティングしたため、ポジションが受け取るターゲットトークンの量がごく僅かとなった。精度の切り捨てによりポジション価値がゼロに丸められ、ヘルスチェックがそのポジションを健全と判定し、約$570Kの不良債権が生じた。
背景
DeFiTunaはSolana上の貸付プロトコルであり、マージントレーディングをサポートしている。ユーザーは1つのトークンを担保として預け入れ、プロトコルのバルトから借り入れを行い、借りた資金をターゲットトークンにスワップすることでスポットポジションを開設できる。その結果生じたポジションは、健全かどうかを判断するために債務と照合される。
DeFiTunaのスポットマーケットでは、2つのプールトークンをトークンAおよびトークンBと呼ぶ。攻撃されたマーケットでは、トークンAがTUNA、トークンBがUSDCであった。
USDCは担保トークン(collateral_token)であった。ユーザーはUSDCを証拠金として預け入れ、DeFiTunaのバルトから追加のUSDCを借り入れ、借りたUSDCはTUNAにスワップされる。TUNAはポジショントークン(position_token)であり、スワップ後にポジションが保有するアセットである。実質的な効果は、USDCの債務で賄われたTUNAのレバレッジドロングとなる。- バルトアカウントは貸し手の流動性を保有し、借入資金の供給源となる。
- AMMプールは
TUNA/USDCペアの市場流動性と価格コンテキストを提供する。
DeFiTunaはポジションのスワップをSolanaのスワップアグリゲーターであるJupiterを通じてルーティングする。スワップパスはJupiterのルートデータとルートアカウントとしてDeFiTunaのインストラクションに提供される。呼び出し元がこれらのアカウントを提供するため、呼び出し元はスワップが使用するプールをコントロールできる。スワップを実行する前に、DeFiTunaは通常の市場プール価格をオラクルと比較することでスワップ前の価格チェックを行う。
脆弱性の分析
バグのあるプログラムはDeFiTuna(tuna4u...nogD)である。
根本原因は、ポジションのヘルスチェックにおけるゼロ値分岐の欠陥であった。スワップ後、DeFiTunaは保有するTUNAをUSDC建てに換算してポジションを評価した。TUNA残高が切り捨てによりゼロになるほど少ない場合、totalフィールドは0となった。ヘルスチェックのロジックはdebt == 0を要求することなくtotal == 0を健全な状態として扱っていた。


攻撃の分析
2つの設計上の特性により、攻撃者は借りた資金のルーティング先をコントロールできた。第一に、DeFiTunaは呼び出し元が提供したJupiterのRouteV2データを受け入れる際、オラクル価格と借入額から許容可能な最小TUNA出力を独自に算出していなかった。第二に、スワップ前のオラクルチェックは通常のDeFiTuna市場プールのみを検証しており、Jupiterルートが実際に使用するプールは検証していなかった。

注意: プロジェクトチームが承認したインシデント後の分析 [1] では、攻撃者が作成したプールは正規のオラクル価格付近で初期化されたと説明されている。オンチェーンの証拠は、プールが極端な価格で初期化されたことを示しており、スワップ前チェックは攻撃者がコントロールするプールではなく、別の通常の市場プールを検証したため通過した。
以下の分析はトランザクション 4x33Dq...EXj1 に基づいている。複数の攻撃トランザクションが実行されたが、このトランザクションがコアテクニックを示している。
- ステップ1:攻撃者は新しいFusion
TUNA/USDCプールを作成した。このプールは本物のTUNAとUSDCのミントを使用していたが、通常のDeFiTuna市場プールとは別のものであった。プールはティック208636付近の極端な価格で初期化され、TUNA1枚あたり約11.49億USDCという価格が設定された。この価格では、ごく僅かな量のTUNAでもスワップで数十万USDCを吸収できた。


- ステップ2:攻撃者は新しいプールに2件の小さな売り指値注文を置いた。各注文は
0.000526 TUNAを預け入れ、合計0.001052 TUNAとなった。プール価格が極めて高かったため、この僅かなTUNAの供給でスワップ実行時に借入USDC全額を吸収できた。


- ステップ3:プールの準備が整った後、攻撃者はポジショントークンとして
TUNA、担保トークンとしてUSDCを指定したDeFiTunaスポットポジションを開設した。攻撃者は担保として0 USDCを提供し、DeFiTunaのUSDCバルトから570,000 USDCを借り入れた。

- ステップ4:スワップ前に、DeFiTunaは通常の市場プール価格とオラクル価格を比較した。通常プールのスポット価格はオラクルに近かったため、チェックは通過した。このチェックは通常のDeFiTuna市場プールのみを検証しており、Jupiterルートが使用するFusionプールは検証していなかった。

- ステップ5:スワップは攻撃者が提供したJupiterルートに従い、最小出力を実質ゼロに設定した攻撃者がコントロールするFusionプールに資金を誘導した。プロトコル手数料を差し引いた後、
569,601 USDCが攻撃プールにルーティングされ、DeFiTunaポジションが受け取ったTUNAはわずか494の生単位(0.000494 TUNA)であった。


- ステップ6:スワップ後、ポジションは約
570,000 USDCの債務を抱え、僅かな量のTUNAしか保有していなかった。DeFiTunaがそのTUNA残高をUSDC価値に換算すると、結果は切り捨てられて0となった。ヘルスチェックはtotal == 0を健全と判定したため、不良債権ポジションが受け入れられた。


- ステップ7:攻撃者は攻撃者がコントロールするFusionプールに蓄積された
USDCを引き出した。2回の引き出しはほぼ等額であり、ステップ2で作成した2つの指値注文ポジションに対応していた。
まとめ
根本原因は、ヘルスチェックのtotal == 0分岐が未返済の債務にかかわらずポジションを健全と受け入れたことにある。攻撃者がコントロールするルーティングと流動性がこの欠陥を引き起こす条件を作り出したが、ヘルスチェックこそが不良債権を防ぐべき最終的な制御機構であった。
最も直接的な修正方法は、total == 0かつdebt > 0であるポジションを拒否することである。未返済債務を抱えたゼロ価値のポジションは決して健全ではない。さらに、プロトコルは呼び出し元が提供するルートパラメータに依存せず、オラクル価格と借入額から許容可能な最小スワップ出力を独自に算出すべきである。オラクル/価格チェックを実際のスワッププールに紐付けるか、プロトコルが計算したフロアに対してスワップ出力を検証することで、未検証のプールへのルーティングによるスワップ前チェックの回避を防ぐことができる。
参考文献
今週のその他のインシデント
BarnBridge
2026年7月15日、Ethereum上のイールドアロケーションプロトコルBarnBridgeが、約$776KのUSDCを悪用された [1]。根本原因は、廃止されたガバナンスコントラクトが重要なプロトコル設定を変更する権限を保持し続けていたことにある。攻撃者はプロトコルコンポーネントのコントローラーを差し替える悪意のある提案を可決するのに十分な投票力を取得し、新しいコントローラーを使ってユーザーが承認したUSDCを転送した。
背景
BarnBridgeはDAOによって管理されるプロトコルであり、収益を生み出すためにユーザーの資金をさまざまな貸付市場に配分する。投票力はステーキングされたBONDの量とロックアップ期間によって決定される。提案の作成には、総投票力の少なくとも1%に相当する投票力が必要である。提案が可決されるには、最低クォーラム40%を満たし、参加した総投票数の少なくとも60%の賛成票を得る必要がある。提出後、提案は2日間のウォームアップ期間、3日間の投票期間、2日間のキュー期間を経て実行可能となる。
脆弱性の分析
根本原因は、プロトコルが廃止された後も、廃止されたガバナンスコントラクトが重要なプロトコル設定を変更する権限を保持し続けていたことにある。ガバナンスシステムは、ユーザーがUSDCの使用を事前承認していたCompoundProviderのController割り当てをコントロールしていた。BarnBridgeが廃止されていたため、ステーキングされた総BOND量とアクティブな参加者が大幅に減少しており、敵対的な提案の可決が容易に達成可能となっていた。
攻撃の分析
以下の分析はトランザクション 0xd191fe...895afb に基づいている。
攻撃者は約0.335 ETHを費やして約32,795 BONDを取得し、32,000 BONDを預け入れてロックし、総投票力の約43%を獲得した。
- ステップ1:攻撃者はプロキシコントラクトをデプロイし、悪意のある提案を提出した。2日間のウォームアップ期間後、攻撃者は自身の全投票力を賛成票として投じ、クォーラムと承認要件の両方を満たした。


- ステップ2:攻撃者は提案をキューに入れた。2日間のキュー期間が経過した後、攻撃者はそれを実行し、
CompoundProviderのControllerを攻撃者のプロキシコントラクトに設定した。

- ステップ3:攻撃者はプロキシコントラクトのロジックをアップグレードし、
_takeUnderlying()を呼び出した。これにより約50人のユーザーが持つUSDCの未使用承認額が使われ、彼らのUSDCがCompoundProviderに転送された。攻撃者はその後transferFees()を呼び出して資金を攻撃者のアドレスに転送し、約$776KのUSDCを不正取得した。

まとめ
DAOまたはプロトコルが廃止される場合、そのガバナンスコントラクトはセキュリティ上重要な設定、特に管理者・コントローラー・資金引き出し権限を変更する能力を放棄または恒久的に無効化すべきである。具体的な対策としては、ガバナンスコントラクトの下流コントラクトに対する管理者ロールの失効、バーンアドレスへの所有権移転、またはアップグレード機能を無効化してコントローラー参照を不変の安全な値に設定する最終提案の実行などが挙げられる。廃止されたプロトコルにガバナンス権限を残しておくと、低コストな攻撃面が生まれる。参加者が減少するにつれてクォーラムに必要な資本も比例して低下するためである。



