Liquid Staking

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

Incorrect Handling Of Negative newRewards and Incorrect Handling of newReward comparison

Summary

Vulnerability Details

Incorrect Handling of Negative newReward

The LSTRewardsSplitter::performUpkeep function handles the splitting of rewards between fee receivers.

function performUpkeep(bytes calldata) external {
int256 newRewards = int256(lst.balanceOf(address(this))) - int256(principalDeposits);
if (newRewards < 0) {
principalDeposits -= uint256(-1 * newRewards);
} else if (uint256(newRewards) < controller.rewardThreshold()) {
revert InsufficientRewards();
} else {
_splitRewards(uint256(newRewards));
}
}
principalDeposits -= uint256(-1 * newRewards);

From the code block above , if the newRewardsis negative , current logic tries to cast it to uint256 after multiplying by -1. However, casting negative integers to uint256 does not make sense, and underflow can occur.

uint256 type cannot represent negative values. If a negativeint256 is cast touint256, it will become a large positive number (since uint256 wraps around). This can lead to incorrect and dangerous behavior.

Incorrect Handling of newReward comparison

else if (uint256(newRewards) < controller.rewardThreshold())

If newRewards is negative, casting it to uint256 here can create an extremely large positive number due to underflow, leading to an incorrect comparison with the rewardThreshold. This would result in unintended behavior.

Impact

Tools Used

Manual Review

Recommendations

Incorrect Handling of Negative newReward

Before trying to cast, check whether the rewards are negative and handle the principal update differently to avoid underflows or incorrect conversions.

Incorrect Handling of newReward comparison

compare the rewards before casting them to uint256. If they are negative, don't proceed with the rewards comparison and handle it as a special case (e.g., reverting or reducing principal).

Suggested Fix

function performUpkeep(bytes calldata) external {
int256 newRewards = int256(lst.balanceOf(address(this))) - int256(principalDeposits);
// Handle negative rewards correctly
if (newRewards < 0) {
// Avoid underflow by checking that the principal can be reduced by this amount
uint256 reduction = uint256(-newRewards);
require(principalDeposits >= reduction, "Underflow: Principal deposits too low");
principalDeposits -= reduction;
}
// If new rewards are positive, proceed
else if (uint256(newRewards) < controller.rewardThreshold()) {
revert InsufficientRewards();
} else {
_splitRewards(uint256(newRewards));
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

eagles Submitter
10 months ago
inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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