SC03:2025 - Logic Errors

Description:

Logic errors, also known as business logic vulnerabilities, are subtle flaws in smart contracts. They occur when the contract’s code does not match its intended behavior. These errors can manifest in various forms, such as faulty math in reward distribution, improper token minting mechanisms, or incorrect calculations in lending and borrowing logic. Such vulnerabilities are elusive, hiding within the contract’s logic and waiting to be discovered.

Examples of Logic Errors:

  1. Faulty Reward Distribution: Miscalculations in dividing rewards among stakeholders, leading to unfair allocations.
  2. Improper Token Minting: Unchecked or erroneous minting logic that allows infinite or unintended token generation.
  3. Lending Pool Imbalances: Incorrect tracking of deposits and withdrawals, causing inconsistencies in pool reserves.

Example (Vulnerable contract):

// 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;
    }
}

Impact:

Remediation:

Example (Fixed version):

// 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;
    }
}

Examples of Smart Contracts That Fell Victim to Business Logic Attacks:

  1. Level Finance Hack : A Comprehensive Hack Analysis
  2. BNO Hack : A Comprehensive Hack Analysis