Liquid Staking

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

Staking Pool Prioritization of reSDL Tokens Not Implemented

Summary

The protocol's documentation mentions that if the StakingPool lacks deposit room and later gets space, users with more reSDL tokens should be prioritized for deposits in PriorityPool. However, this prioritization mechanism is not implemented in the actual PriorityPool::_depositQueuedTokens function, which can lead to fairness and order issues for users with larger reSDL balances who expect priority.

Vulnerability Detail

The vulnerability arises from the discrepancy between the protocol documentation and the actual implementation of the deposit process. According to the documentation, users with higher reSDL token balances should be prioritized for deposits when the StakingPoolhas limited room and later gains availability. However, in the PriorityPool::_depositQueuedTokens function, there is no logic that prioritizes deposits based on reSDL token holdings.

Instead, the function calculates the available deposit room and attempts to fill it with a mix of unused deposits and queued tokens, but without giving preference to users with higher reSDL balances. This inconsistency may lead to situations where users with fewer reSDL tokens are allowed to deposit before users with more reSDL tokens, which contradicts the intended functionality as described in the documentation.

Impact

This issue affects the fairness of the deposit process for users. Users holding more reSDL tokens might expect priority when the staking pool has limited room, but since the prioritization logic is absent, they may not receive the anticipated benefits. This can cause user dissatisfaction and could be considered a violation of the protocol's intended behavior.

Code Snippet

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/priorityPool/PriorityPool.sol#L693

function _depositQueuedTokens(
uint256 _depositMin,
uint256 _depositMax,
bytes[] memory _data
) internal {
if (poolStatus != PoolStatus.OPEN) revert DepositsDisabled();
uint256 strategyDepositRoom = stakingPool.getStrategyDepositRoom();
if (strategyDepositRoom == 0 || strategyDepositRoom < _depositMin)
revert InsufficientDepositRoom();
uint256 _totalQueued = totalQueued;
uint256 unusedDeposits = stakingPool.getUnusedDeposits();
uint256 canDeposit = _totalQueued + unusedDeposits;
if (canDeposit == 0 || canDeposit < _depositMin) revert InsufficientQueuedTokens();
uint256 toDepositFromStakingPool = MathUpgradeable.min(
MathUpgradeable.min(unusedDeposits, strategyDepositRoom),
_depositMax
);
uint256 toDepositFromQueue = MathUpgradeable.min(
MathUpgradeable.min(_totalQueued, strategyDepositRoom - toDepositFromStakingPool),
_depositMax - toDepositFromStakingPool
);
stakingPool.deposit(address(this), toDepositFromQueue, _data);
_totalQueued -= toDepositFromQueue;
if (_totalQueued != totalQueued) {
uint256 diff = totalQueued - _totalQueued;
depositsSinceLastUpdate += diff;
sharesSinceLastUpdate += stakingPool.getSharesByStake(diff);
totalQueued = _totalQueued;
}
emit DepositTokens(toDepositFromStakingPool, toDepositFromQueue);
}

Tool Used

Manual code review and documentation comparison.

Recommendation

To resolve this issue, implement logic in the PriorityPool::_depositQueuedTokens function that prioritizes users with more reSDL tokens when there is limited deposit room in the StakingPool. This could involve sorting queued deposits by reSDL token balances and ensuring those with higher balances are processed first, as per the protocol's intended design.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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