Skip to content
Last updated: December 19, 2024

SCSTG-TEST-0015: Testing Business Logic and Economic Security

Description

Business logic and economic security are crucial for ensuring that smart contracts function as intended and that the economic incentives align with the intended use cases. If vulnerabilities in the logic or economic models are present, attackers may exploit them for financial gain. This test focuses on reviewing economic models, incentive structures, and tokenomics to ensure that smart contracts are designed to prevent logic flaws, reentrancy attacks, and malicious economic manipulation.


Test 1: Ensure Economic Model Integrity and Prevent Logic Flaws

Vulnerable Code

pragma solidity ^0.8.0;

contract IncentiveModel {
    uint256 public rewardPool;

    function distributeRewards(address[] memory users) public {
        uint256 reward = rewardPool / users.length;  // Dividing the total reward pool among users
        for (uint256 i = 0; i < users.length; i++) {
            payable(users[i]).transfer(reward);
        }
    }
}

Why It’s Vulnerable

  • If the users array is empty, the division by zero will occur, leading to a runtime exception.
  • Additionally, if the reward pool is too small or the number of users is too large, it could cause unexpected behavior, leading to attackers exploiting the system by flooding the contract with too many addresses.

Fixed Code:

pragma solidity ^0.8.0;

contract SecureIncentiveModel {
    uint256 public rewardPool;

    modifier nonZeroUsers(address[] memory users) {
        require(users.length > 0, "No users provided");
        _;
    }

    function distributeRewards(address[] memory users) public nonZeroUsers(users) {
        uint256 reward = rewardPool / users.length;
        require(reward > 0, "Reward amount is too low");
        for (uint256 i = 0; i < users.length; i++) {
            payable(users[i]).transfer(reward);
        }
    }
}

How to Check

  • Code Review: Look for scenarios where division or mathematical operations could result in errors like division by zero or unintended behavior due to extreme input values.
  • Dynamic Testing: Test the function with edge cases such as empty user lists, very large user arrays, and reward pool sizes. Ensure that the system handles these cases gracefully and does not allow unexpected errors or exploits.