SC03:2025 - ロジックエラー (Logic Errors)

説明:

ロジックエラーは、ビジネスロジック脆弱性とも呼ばれ、スマートコントラクトの捉えにくい欠陥です。これはコントラクトのコードが意図した動作と一致しない場合に発生します。これらのエラーは、報酬分配における計算の誤り、不適切なトークン鋳造メカニズム、貸借ロジックにおける計算の誤りなど、さまざまな形で現れる可能性があります。そのような脆弱性は見つけにくく、コントラクトのロジック内に隠れて発見されるのを待っています。

ロジックエラーの事例:

  1. 報酬分配の誤り: ステークホルダー間での報酬分配の計算ミスにより、不公平な割り当てにつながります。

  2. 不適切なトークン鋳造: 鋳造ロジックがチェックされていないか誤っており、トークンの無制限の生成や意図しない生成を可能にします。

  3. 貸付プールの不均衡: 入出金の追跡が不正確で、プール準備金の不整合を引き起こします。

事例 (脆弱なコントラクト):

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

contract Solidity_LogicErrors {
    mapping(address => uint256) public userBalances;
    uint256 public totalLendingPool;

    function deposit() public payable {
        userBalances[msg.sender] += msg.value;
        totalLendingPool += msg.value;
    }

    function withdraw(uint256 amount) public {
        require(userBalances[msg.sender] >= amount, "Insufficient balance");

        // Faulty calculation: Incorrectly reducing the user's balance without updating the total lending pool
        userBalances[msg.sender] -= amount;

        // This should update the total lending pool, but it's omitted here.

        payable(msg.sender).transfer(amount);
    }

    function mintReward(address to, uint256 rewardAmount) public {
        // Faulty minting logic: Reward amount not validated
        userBalances[to] += rewardAmount;
    }
}

影響:

  • ロジックエラーはスマートコントラクトが予期しない動作をしたり、完全に使用できなくなる可能性さえあります。これらのエラーは以下をもたらす可能性があります。

    • 資金の損失: 不正確な報酬分配やプールの不均衡によりコントラクト資金が枯渇します。

    • 過剰なトークン鋳造: トークン供給を膨らませて、信頼と価値を損ないます。

    • 運用上の不備: コントラクトが意図した機能を実行できなくなります。

  • これらの結果、ユーザーやステークホルダーに多大な金銭的損失と運用上の損失をもたらす可能性があります。

対策:

  • 考えられるすべてのビジネスロジックシナリオを網羅する包括的なテストケースを記述して、常にコードを検証します。

  • 徹底的なコードレビューと監査を実施し、潜在的なロジックエラーを特定して修正します。

  • 各機能やモジュールの意図した動作を文書化し、実際の実装と比較して整合性を確認します。

  • 以下のようなガードレールを実装します。

    • 計算エラーを防ぐための安全な数学ライブラリ。

    • トークン鋳造に対する適切なチェックとバランス。

    • 監査可能な報酬分配アルゴリズム。

事例 (修正バージョン):

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

contract Solidity_LogicErrors {
    mapping(address => uint256) public userBalances;
    uint256 public totalLendingPool;

    function deposit() public payable {
        userBalances[msg.sender] += msg.value;
        totalLendingPool += msg.value;
    }

    function withdraw(uint256 amount) public {
        require(userBalances[msg.sender] >= amount, "Insufficient balance");

        // Correctly reducing the user's balance and updating the total lending pool
        userBalances[msg.sender] -= amount;
        totalLendingPool -= amount;

        payable(msg.sender).transfer(amount);
    }

    function mintReward(address to, uint256 rewardAmount) public {
        require(rewardAmount > 0, "Reward amount must be positive");

        // Safeguarded minting logic
        userBalances[to] += rewardAmount;
    }
}

ロジックエラーの被害を受けたスマートコントラクトの事例:

Last updated