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.