Liquid Staking

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

`StakingPool::getUnusedDeposits` will return a misleading value because it considers donated Tokens as well.

Summary

getUnusedDeposits includes tokens that were donated to the pool

Vulnerability Details

getUnusedDeposits is supposed to represent tokens that have been deposited into the stakingPool and have not yet been deployed to strategies. But they eventually get deposited into strategies when _depositLiquidity is called.

donateTokens is a function users call to send tokens to the stakingPool without minting LSTs. As a way to donate to the protocol.

The issue here is that: when getUnusedDeposits is called, it returns the balance of the stakingPool (which will include the donated tokens).

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

Impact

Donated tokens inflate the balance reported by getUnusedDeposits(), making it appear that there are more idle, deployable assets than there really are. This could lead to over-deployment of tokens into strategies, causing the pool to run out of liquidity when it's needed for withdrawals or other operations.

If all the unused tokens, including donated ones, are deployed into yield strategies, the pool might lack the liquidity needed to fulfill withdrawal requests.

If donated tokens are included in strategies, they will earn yield, but because no LSTs are minted for them, the protocol won’t properly track who should be entitled to the rewards generated by these tokens.

There will be yield generated that isn’t attributed to any user, which can lead to accounting errors or even unfair allocation of rewards. This introduces complications in distributing earned rewards properly to regular depositors.

Tools Used

Manual Review

Recommendations

There should be a way to differentiate unusedDeposits from donated Tokens. Introduce a variable that tracks donated tokens. And then subtract this value when querying getUnusedDeposits :

function donateTokens(uint256 _amount) external {
token.safeTransferFrom(msg.sender, address(this), _amount);
totalStaked += _amount;
+ totalDonated += _amount;
emit DonateTokens(msg.sender, _amount);
}
function getUnusedDeposits() external view returns (uint256) {
+ return token.balanceOf(address(this)) - totalDonated;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
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.