Liquid Staking

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

Missing checks in setting `PriorityPool::queueDepositMin` and `PriorityPool::queueDepositMax` variables

Summary

The PriorityPool::queueDepositMin and PriorityPool::queueDepositMax are the minimum and maximum amount that can be deposited into strategies at once. These state variables can be set by the PriorityPool::initialize and PriorityPool::setQueueDepositParams functions. For seemless operation of the Protocol, the minimum deposit value should always be less than the maximum deposit value.
However, the two functions set these values without checking for this condition.

Vulnerability Details

The issue lies in the PriorityPool::initialize and PriorityPool::setQueueDepositParams function's lack of check on the input parameters before making the necessary state changes. Consider the code snippets below:

function initialize(
address _token,
address _stakingPool,
address _sdlPool,
uint128 _queueDepositMin,
uint128 _queueDepositMax
) public initializer {
__UUPSUpgradeable_init();
__Ownable_init();
__Pausable_init();
token = IERC20Upgradeable(_token);
stakingPool = IStakingPool(_stakingPool);
sdlPool = ISDLPool(_sdlPool);
queueDepositMin = _queueDepositMin;
queueDepositMax = _queueDepositMax;
accounts.push(address(0));
token.safeIncreaseAllowance(_stakingPool, type(uint256).max);
}

and

function setQueueDepositParams(
uint128 _queueDepositMin,
uint128 _queueDepositMax
) external onlyOwner {
queueDepositMin = _queueDepositMin;
queueDepositMax = _queueDepositMax;
emit SetQueueDepositParams(_queueDepositMin, _queueDepositMax);
}

Here is the github link to the function https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/priorityPool/PriorityPool.sol#L549-L556

Impact

Where these parameters are set wrongly due to the lack of check in the function, it can cause some undesirable Protocol behaviour especially where other checks depend on the value of these state variables. Note that these parameters are used for some checks in some functions internally.
Though it could be argued that this is not an issue since these state variables can be set over and again using the PriorityPool::setQueueDepositParams function, it should be noted that this can go unnoticed while the protocol acts in a misleading manner.
To further explain this point, suppose by some chance, these state variables are set as queueDepositMin = 100 and queueDepositMax = 10 since there are no checks to prevent this. Suppose the stakingPool.getStrategyDepositRoom() in the PriorityPool::checkUpkeep function returns a value of 50, then the PriorityPool::checkUpkeep function will return false when it should in fact return true. This happens because the check is carried out using 100 instead of 10 i.e. 50 < 100 returns true whereas 50 < 10 returns false.
Thus the Protocol may misbehave subtly without showing any visible signs of abnomaly.

Tools Used

Manual Review

Recommendations

Add some checks to both functions to ensure that the minimum deposit amount is always less than the maximum deposit amount as below:

function initialize(
address _token,
address _stakingPool,
address _sdlPool,
uint128 _queueDepositMin,
uint128 _queueDepositMax
) public initializer {
+ if(_queueDepositMin >= _queueDepositMax ) revert();
__UUPSUpgradeable_init();
__Ownable_init();
__Pausable_init();
token = IERC20Upgradeable(_token);
stakingPool = IStakingPool(_stakingPool);
sdlPool = ISDLPool(_sdlPool);
queueDepositMin = _queueDepositMin;
queueDepositMax = _queueDepositMax;
accounts.push(address(0));
token.safeIncreaseAllowance(_stakingPool, type(uint256).max);
}
function setQueueDepositParams(
uint128 _queueDepositMin,
uint128 _queueDepositMax
) external onlyOwner {
+ if(_queueDepositMin >= _queueDepositMax ) revert();
queueDepositMin = _queueDepositMin;
queueDepositMax = _queueDepositMax;
emit SetQueueDepositParams(_queueDepositMin, _queueDepositMax);
}
Updates

Lead Judging Commences

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