When the newRewards variable, calculated as the difference between the contract's LST token balance and principalDeposits, becomes negative.
This line attempts to subtract the absolute value of newRewards from principalDeposits using an unsigned integer (uint256), which can lead to an underflow if the absolute value of newRewards is greater than principalDeposits. https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/lstRewardsSplitter/LSTRewardsSplitter.sol#L101-L110
When the newRewards variable calculated as the difference between the contract's LST token balance and principalDeposits becomes negative. In this case, the contract attempts to subtract the absolute value of newRewards from principalDeposits using an unsigned integer (uint256). However, if the absolute value of newRewards is greater than principalDeposits, an underflow occurs, resulting in principalDeposits becoming a large positive value instead of a negative value.
The vulnerability can be triggered by calling the performUpkeep function when the contract's LST token balance is less than principalDeposits.
The reason for this vulnerability is the incorrect handling of negative newRewards values in the performUpkeep function. The subtraction of the absolute value of newRewards from principalDeposits is performed using an unsigned integer (uint256), which can lead to an underflow if the absolute value of newRewards is greater than principalDeposits.
Using an unsigned integer (uint256) for the subtraction operation in the performUpkeep function is a mistake, as it does not properly handle negative values and can lead to an underflow.
Scenario:
The LSTRewardsSplitter contract is deployed with an initial principalDeposits value of 100.
A user calls the withdraw function to withdraw 50 tokens, reducing principalDeposits to 50.
The contract's LST token balance is manipulated externally, causing it to become less than principalDeposits. For example, the balance becomes 30.
Another user calls the performUpkeep function.
Inside performUpkeep, newRewards is calculated as 30 - 50 = -20.
The contract attempts to subtract the absolute value of newRewards (20) from principalDeposits (50) using uint256, resulting in an underflow.
principalDeposits becomes a large positive value instead of the expected negative value, violating the contract's invariant.
When newRewards is negative, the contract attempts to subtract the absolute value of newRewards from principalDeposits. However, this subtraction is performed using an unsigned integer (uint256), which can lead to an underflow if the absolute value of newRewards is greater than principalDeposits.
Manual Review
The subtraction operation should be performed using signed integers to handle negative values correctly.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.