Liquid Staking

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

Negative Rewards Can Decrease Total Staked Amount in StakingPool

Summary

The StakingPool contract has a vulnerability in the _updateStrategyRewards function that allows negative rewards to decrease the totalStaked amount incorrectly. This can lead to inconsistencies between the actual total staked amount and the totalStaked variable, potentially enabling attackers to manipulate the system and cause further vulnerabilities.

Vulnerability Details

The StakingPool contract in StakingPool.sol has a vulnerability in the _updateStrategyRewards function that allows negative rewards to decrease the totalStaked amount incorrectly. This can lead to inconsistencies between the actual total staked amount and the totalStaked variable. https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L550-L553

// ...
if (totalRewards != 0) {
totalStaked = uint256(int256(totalStaked) + totalRewards); // <-- @audit Negative rewards can decrease totalStaked
}
// ...
}

The issue occurs when totalRewards is negative, indicating a loss in the strategy rewards. The code directly adds the negative totalRewards to totalStaked, effectively decreasing the totalStaked amount. However, totalStaked should represent the total amount of tokens staked in the pool and should not be decreased by negative rewards.

Impact

The totalStaked amount may not accurately reflect the total tokens staked in the pool, leading to incorrect calculations and discrepancies in the system.

Tools Used

Vs

Recommendations

Handle negative rewards properly. Instead of directly updating totalStaked with the negative rewards, the code should ensure that totalStaked never decreases below the actual total staked amount.

// ...
- if (totalRewards != 0) {
- totalStaked = uint256(int256(totalStaked) + totalRewards);
- }
+ if (totalRewards > 0) {
+ totalStaked = uint256(int256(totalStaked) + totalRewards);
+ } else if (totalRewards < 0 && uint256(-totalRewards) < totalStaked) {
+ totalStaked -= uint256(-totalRewards);
+ }
// ...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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