Liquid Staking

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

Withdrawal Amount Can Exceed Principal Deposits in LSTRewardsSplitter Contract

Summary

The withdraw function in the LSTRewardsSplitter contract contains a vulnerability that allows withdrawing an amount that exceeds the available principal deposits.

Vulnerability Details

This can lead to an underflow of the principalDeposits variable, resulting in an inconsistent state of the contract and potential loss of user funds.

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/lstRewardsSplitter/LSTRewardsSplitter.sol#L79-L83

function withdraw(uint256 _amount, address _receiver) external onlyController {
principalDeposits -= _amount;
lst.safeTransfer(_receiver, _amount);
emit Withdraw(_amount);
}

The issue arises because the withdraw function directly subtracts the _amount from principalDeposits without performing any checks to ensure that the withdrawal amount is within the available principal deposits. If the _amount is greater than principalDeposits, the subtraction will result in an underflow, causing principalDeposits to become a large positive value.

This vulnerability can be exploited by calling the withdraw function with an _amount that exceeds the current principalDeposits. As a result, the contract will transfer more tokens than intended to the _receiver, effectively allowing the unauthorized withdrawal of funds.

Impact

The underflow of principalDeposits results in an inconsistent state of the contract, where the recorded principal deposits do not accurately reflect the actual deposits made by users.

Tools Used

Manual Review

Recommendations

Aheck 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.