Liquid Staking

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

[M-2] Lack of Withdrawal Amount Validation in LSTRewardsSplitter::withdraw()function

Summary

The withdraw function in the LSTRewardsSplitter contract lacks a necessary check to ensure that the withdrawal amount does not exceed the available principalDeposits. This oversight can lead to logical inconsistencies in the contract's state

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

Vulnerability Details

There is currently no check to ensure that the requested withdrawal amount does not exceed the total principal deposits. Without such a check, a withdrawal might attempt to transfer more tokens than were originally deposited as principal, which could deplete rewards or cause errors.

Impact

The absence of this check can lead to an incorrect state where principalDeposits is negative or otherwise misrepresented. This could affect the contract's ability to accurately track deposits and withdrawals.

The reward-splitting mechanism in the LSTRewardsSplitter contract is designed to distribute only the rewards that exceed the principalDeposits. If the controller withdraws more than principalDeposits, it interferes with this logic, potentially reducing or consuming rewards that would otherwise be available for splitting among fee receivers. This breaks the expected functionality of the contract.

Tools Used

Manual Review

Steps to Exploit

  1. Logical Reasoning:

    • The controller, who has the authority to call withdraw, can specify an _amount greater than the available principalDeposits.

  2. Execution:

    • Assume the contract has 100 tokens in principalDeposits and 50 tokens in rewards.

    • The controller calls the withdraw function with an _amount of 120 tokens.

    • The function reduces principalDeposits by 120, resulting in a negative or inaccurate state, and transfers 120 tokens to the _receiver.

  3. Outcome:

    • The withdrawal includes 20 tokens from the rewards, which were not intended to be withdrawable as part of the principal.

    • This action breaks the intended functionality of the contract by misappropriating reward tokens, potentially leading to financial discrepancies and operational failures

Recommendations

Add validation check to ensure that _amount is less than or equal to principalDeposits before proceeding with the state update and token transfer.

function withdraw(uint256 _amount, address _receiver) external onlyController {
require(_amount <= principalDeposits, "Insufficient principal deposits"); //Adding check
principalDeposits -= _amount;
lst.safeTransfer(_receiver, _amount);
emit Withdraw(_amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 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.