SC02:2026 - ビジネスロジックの脆弱性 (Business Logic Vulnerabilities)

説明

ビジネスロジックの脆弱性は、個々の低レベルチェック (型安全性、再入防止、アクセス制御など) が正しいにもかかわらず、スマートコントラクトの 意図した 経済的または機能的な動作が損なわれる可能性のあるあらゆる状況を指します。これらは、システムのルール、インセンティブ、状態遷移、不変条件がオンチェーンでどのようにモデル化されているかにおける 設計上の欠陥 です。低レベルバグ (オーバーフロー、再入可能性) とは異なり、ビジネスロジックの欠陥はルール自体が安全でない場合に発生します。コードは「指示どおりに動作する」ものの、それは悪用可能な結果を許すことになります。

これは、DeFi (融資、AMM、Vault、利回り戦略)、NFT (発行ロジック、ロイヤリティ、マーケットプレイス機構)、DAO (投票、委譲、提案実行)、ブリッジ (burn/mint の非対称性、流動性ルール)、ゲーミング (報酬分配、公平性)、マルチホップの状態遷移が新たな脆弱性を生み出すクロスチェーン/L2 システムなど、すべてのスマートコントラクトの領域にわたって適用します。

注目する領域は以下のとおりです。

  • モジュール間における 不変条件違反 (例: vault ↔ strategy ↔ gauge, collateral ↔ debt, supply ↔ backing)

  • 報酬および手数料のロジック (double-counting, under/over-accrual, wrong beneficiary)

  • バイパス可能または一貫性のない適用された 適格性および制限のチェック (借入上限、発行制限、換金閾値)

  • 操作的なアクションシーケンスが不可能または一貫性のない状態に到達できる パス依存ステートマシン

  • モジュール間およびチェーン間の前提条件 (例: ブリッジの流動性、L2 ファイナリティ、メッセージの順序付け)

攻撃者は以下のように悪用します。

  • 一貫性のない会計処理間での裁定取引 (vault 対 strategy、内部残高と外部残高)

  • 操作順序のエッジケース (不変条件を破る預け入れ/引き落とし/請求シーケンス)

  • 適格性のバイパス (例: 持ち分なしでの報酬の請求、健全なポジションの債務弁済)

  • 経済的に不合理な状態を生み出す パラメータ操作 (金利曲線、手数料、担保係数)

事例 (脆弱な融資ロジック)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract VulnerableLending {
    mapping(address => uint256) public collateral;
    mapping(address => uint256) public debt;
    uint256 public collateralFactorBps = 7500; // 75%

    function depositCollateral() external payable {
        collateral[msg.sender] += msg.value;
    }

    // Vulnerable: calculates borrow capacity using the *new* amount, not total
    function borrow(uint256 amount) external {
        uint256 allowed = (amount * collateralFactorBps) / 10_000;
        require(allowed >= amount, "not enough collateral"); // meaningless check

        debt[msg.sender] += amount;
        // send tokens from pool (omitted)
    }
}

Issues:

  • allowed is computed from the requested borrow amount, not the user’s collateral balance.

  • The check allowed >= amount always holds for collateralFactorBps >= 10_000, and is otherwise simply a tautology when misused like this, failing to enforce any economic invariant.

事例 (修正: 不変式ベースの借用ロジック)

Security Improvements:

  • Borrow limits derive from total collateral, not just requested amounts.

  • Economic invariant: debt[user] <= maxBorrow(user) is enforced on every borrow.

  • Price oracle is explicitly integrated (and can be hardened per SC03).

2025 ケーススタディ

ベストプラクティスと緩和策

  • Model protocol economics explicitly (e.g., with adversarial simulations / agent-based models) rather than relying on intuition.

  • Express core invariants in code and tests:

    • “Total value withdrawn cannot exceed total deposits + realized yield”

    • “Rewards distribution is proportional to time-weighted stake”

    • “Liquidations never result in protocol loss under honest oracle data”

  • Use formal verification and property-based fuzzing for key accounting paths (vaults, strategies, reward distribution).

  • Version and gate new strategies / spells:

    • Roll out behind caps.

    • Monitor metrics and on-chain invariants before raising limits.

  • Ensure governance and operations teams understand invariants, not just auditors.

Last updated