Trick or Treat

First Flight #27
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: low
Invalid

Potential Overflow in Calculations Leading to Transaction Reverts

While Solidity 0.8.x includes built-in overflow and underflow checks, the contract may still encounter issues with arithmetic operations involving large numbers. If treat.cost or multipliers are set to excessively high values, calculations can overflow, causing transactions to revert and disrupting the contract's functionality.

Vulnerability Details

In the trickOrTreat and resolveTrick functions, cost calculations involve multiplication and division:

uint256 requiredCost = (treat.cost * costMultiplierNumerator) / costMultiplierDenominator;

If treat.cost is set to a value close to type(uint256).max, multiplying it by costMultiplierNumerator can exceed the maximum value representable by a uint256, causing an overflow.

Example Scenario:

  • Setting treat.cost to 2**256 - 1 (maximum uint256 value).

  • Multiplying by costMultiplierNumerator (which could be 2 in the double price scenario) results in an overflow.

  • The transaction reverts due to the overflow check in Solidity 0.8.x.

Impact

  • Transaction Reverts: Users are unable to purchase treats if calculations overflow, leading to a denial of service for that functionality.

  • Disrupted User Experience: Frequent transaction failures can frustrate users and reduce engagement with the platform.

  • Potential Exploitation (In Earlier Versions): In Solidity versions before 0.8.x, overflows could be exploited to manipulate cost calculations, possibly allowing users to pay less than intended.

Proof of Concept

  1. Adding a Treat with Maximum Cost:

    addTreat("ExpensiveTreat", type(uint256).max, "metadataURI");
  2. Attempting to Purchase the Treat:

    • During the cost calculation, the multiplication overflows.

    • The transaction reverts due to the overflow check.

  3. Disruption of Service:

    • Users cannot purchase the treat.

    • The contract owner may be unable to correct the issue if the overflow prevents function execution.

Recommendations

  • Set Reasonable Limits:

    Impose maximum values for treat.cost and ensure multipliers are within safe ranges to prevent overflows.

    uint256 constant MAX_TREAT_COST = 1e24; // Example maximum cost
    function addTreat(string memory _name, uint256 _rate, string memory _metadataURI) public onlyOwner {
    require(_rate <= MAX_TREAT_COST, "Treat cost exceeds maximum allowed value");
    // Rest of the function
    }
  • Input Validation:

    Check all user inputs and state variables involved in calculations to ensure they won't cause overflows.

  • Use SafeMath Libraries (For Clarity):

    Although Solidity 0.8.x has built-in checks, using SafeMath can make the code clearer and intentions explicit.

    using SafeMath for uint256;
    uint256 requiredCost = treat.cost.mul(costMultiplierNumerator).div(costMultiplierDenominator);
  • Error Handling:

    Implement try-catch blocks around external calls and provide informative error messages to aid in debugging and user communication.


By addressing these vulnerabilities, the contract can ensure accurate pricing, prevent manipulation, and maintain reliable operation, thereby enhancing security and user trust.

Updates

Appeal created

bube Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.