Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Overflow Vulnerability Due to Incorrect Conversion of Negative int256 to uint256 in Staking Calculation

Summary

The contract implementation involves the conversion of totalStaked (a uint256) to int256 and its subsequent addition to totalRewards (an int256). While the conversion and addition work correctly for positive results, a potential vulnerability arises when the result of int256(totalStaked) + totalRewards is negative. If this negative result is then converted back to uint256, it can lead to an overflow, resulting in a very large, incorrect value for totalStaked.

Vulnerability Details

The vulnerability is present in the following line of code, where the contract attempts to add totalStaked (converted to int256) with totalRewards (which can be negative), and then convert the result back to uint256:

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L550

// update totalStaked if there was a net change in deposits
if (totalRewards != 0) {
totalStaked = uint256(int256(totalStaked) + totalRewards);
}

The variable totalRewards is of type int256 to handle both positive and negative values. To accommodate the addition, totalStaked (a uint256) is first converted to int256. While the addition works correctly for positive values, the issue arises when the result of int256(totalStaked) + totalRewards is negative. Converting this negative result back to uint256 will lead to an overflow, producing a large, incorrect number.

Impact

If int256(totalStaked) + totalRewards produces a negative result, converting this to uint256 can corrupt the totalStaked value. This could lead to:

  • Incorrect tracking of the total staked tokens.

Tools Used

Manually

Recommendations

Check for Negative Results Before Conversion: Before converting the result of int256(totalStaked) + totalRewards back to uint256, ensure that the result is non-negative. If the result is negative, it can lead to a large overflow value that corrupts the totalStaked variable, resulting in faulty staking operations. By adding a simple check, you can prevent this issue:

int256 newTotalStaked = int256(totalStaked) + totalRewards;
require(newTotalStaked >= 0, "Error: totalStaked cannot be negative");
totalStaked = uint256(newTotalStaked);
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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