code-423n4 / loopfi-bug-bounty

5 stars 6 forks source link

Invalid Percentage Input in _claim Function Can Cause Underflow #26

Closed c4-bot-2 closed 3 months ago

c4-bot-2 commented 4 months ago

Lines of code

https://github.com/LoopFi/loop-prelaunch-contracts/blob/c8b13474aa4f319eec368fc4827bf51eddad080f/src/PrelaunchPoints.sol#L248

Vulnerability details

Vulnerability Details:

In the _claim function, the _percentage input represents the proportion of the user's stake to claim. The function lacks validation to ensure _percentage is within a logical range (0-100). If a value greater than 100 is provided, it results in userClaim being greater than userStake, which causes an underflow when updating the user's balance. This can lead to incorrect balance calculations and potential manipulation of the contract state.

Code Snippet:

function _claim(address _token, address _receiver, uint8 _percentage, Exchange _exchange, bytes calldata _data)
    internal
    returns (uint256 claimedAmount)
{
    if (_percentage == 0) {
        revert CannotClaimZero();
    }
    //remaining code
}

Impact:

The lack of validation for _percentage allows users to input values greater than 100, causing an underflow in balance calculations. This can lead to incorrect balances and potential manipulation of the contract state, which could be exploited by malicious users.

Proof of concept

Let's do theoretical Calculation Assume the following values:

   userClaim = userStake * _percentage / 100;

   Substitute the values:

   userClaim = 1000 * 200 / 100;
   userClaim = 1000 * 2;
   userClaim = 2000;
   balances[msg.sender][_token] = userStake - userClaim;

   Substitute the values:

   balances[msg.sender][_token] = 1000 - 2000;
   balances[msg.sender][_token] = -1000;  // Underflow occurs

Proposed Fix

function _claim(address _token, address _receiver, uint8 _percentage, Exchange _exchange, bytes calldata _data)
    internal
    returns (uint256 claimedAmount)
{
(-) if (_percentage == 0) {
(-)    revert CannotClaimZero();
    }

(+) require(_percentage > 0 && _percentage <= 100, "Invalid percentage");
    //remaining code
}

Note : (-) means remove the line and (+) means add the line

Conclusion: By adding this validation, the contract ensures that _percentage values are always within a logical and safe range, preventing potential underflow and ensuring correct balance calculations.

c4-bot-9 commented 4 months ago

Discord id(s) for hunter(s): [object Object]