Liquid Staking

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

Withdrawal Amount Not Validated Against Principal Deposits in `LSTRewardsSplitter`

Summary

withdraw function directly subtracts the _amount from principalDeposits without checking if _amount is less than or equal to principalDeposits. This allows withdrawing more than the available principal, leading to an underflow and violating the rule.

Vulnerability Details

This can lead to a scenario where the principalDeposits value underflows, allowing the withdrawal of more tokens than the actual principal deposits.

Validation steps

  1. The withdraw function directly subtracts the _amount from principalDeposits without checking if _amount is less than or equal to principalDeposits. https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/lstRewardsSplitter/LSTRewardsSplitter.sol#L79-L83

principalDeposits -= _amount;

This can lead to an underflow of principalDeposits if _amount is greater than principalDeposits.

Scenario:

  1. The LSTRewardsSplitter contract is deployed with an initial principalDeposits value of 100 tokens.

  2. A malicious user calls the withdraw function with an _amount of 150 tokens, which exceeds the current principalDeposits value.

  3. The withdraw function subtracts 150 from principalDeposits, resulting in an underflow and setting principalDeposits to a large value (e.g., 2^256 - 50).

  4. The lst.safeTransfer function is called with the _amount of 150 tokens, transferring more tokens than the actual principal deposits to the _receiver address.

  5. The principalDeposits value is now in an inconsistent state, allowing further withdrawals that exceed the actual principal deposits.

Impact

The principalDeposits value will be in an inconsistent state. It will have a value that is much larger than the actual principal deposits, which can lead to further issues and unexpected behavior in other functions that rely on principalDeposits.

Tools Used

Manual Review

Recommendations

Add a validation check in the withdraw function to ensure that the withdrawal amount does not exceed the available principal deposits.

function withdraw(uint256 _amount, address _receiver) external onlyController {
+ require(_amount <= principalDeposits, "Withdrawal amount exceeds principal");
principalDeposits -= _amount;
lst.safeTransfer(_receiver, _amount);
emit Withdraw(_amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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