Liquid Staking

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

If rewards are distributed based on the liquid staking token holdings, users who have not participated in the manual withdrawal will have their rewards diluted, as the total supply of tokens will be higher than the actual staked amount.

Summary

The strategyWithdraw function allows the contract owner to manually withdraw tokens from a strategy without burning the corresponding liquid staking tokens or updating the totalStaked variable. This violates the expected behavior of the staking pool, where any withdrawal should be accompanied by a proportional reduction in the liquid staking token supply and the total staked amount.

How it happens:

  1. The contract owner calls the strategyWithdraw function, specifying the index of the strategy, the amount to withdraw, and any additional withdrawal data.

  2. The function checks if the strategy exists at the given index.

  3. If the strategy exists, it calls the withdraw function of the strategy contract with the specified amount and withdrawal data.

  4. The withdrawn tokens are transferred back to the staking pool contract.

  5. However, the function does not burn any liquid staking tokens or update the totalStaked variable to reflect the withdrawal.

Vulnerability Details

Lack of proper accounting and token burning logic within the strategyWithdraw function. When the contract owner calls this function, specifying the strategy index, withdrawal amount, and any necessary withdrawal data, the function directly interacts with the strategy contract to withdraw the tokens. However, it fails to update the totalStaked variable and does not burn any liquid staking tokens, leading to an inconsistency between the actual staked amount and the liquid staking token supply.

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L188-L195

function strategyWithdraw(
uint256 _index,
uint256 _amount,
bytes calldata _data
) external onlyOwner {
require(_index < strategies.length, "Strategy does not exist");
IStrategy(strategies[_index]).withdraw(_amount, _data);
// Vuln: Missing logic to burn liquid staking tokens and update totalStaked
}

Impact

The totalStaked variable will not accurately represent the total amount of tokens staked in the pool, as it is not updated when tokens are withdrawn through strategyWithdraw.

Since the liquid staking tokens are not burned during the withdrawal, the total supply of these tokens will remain unchanged, effectively inflating the token supply relative to the actual staked amount.

Tools Used

Vs Code

Recommendations

  1. Burn the corresponding amount of liquid staking tokens when withdrawing from a strategy.

  2. Update the totalStaked variable to reflect the decrease in the total staked amount.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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