Liquid Staking

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

Queued Tokens Not Deposited Due to Calculation (Inefficient Utilization of Queued Tokens)

Here

Description: The _depositQueuedTokens function has a logic flaw that can cause queued tokens to remain undeployed under certain conditions, even when there is an opportunity to deposit them. This happens due to the calculation of toDepositFromQueue, which determines how many tokens from the queue will be deposited. Specifically, the problem occurs when the staking pool deposits fully utilize the available deposit room (strategyDepositRoom), leaving no room for the queued tokens to be deposited.”

The problematic portion of the calculation is as follows:

uint256 toDepositFromQueue = MathUpgradeable.min(
MathUpgradeable.min(_totalQueued, strategyDepositRoom - toDepositFromStakingPool),
_depositMax - toDepositFromStakingPool
);

“The issue arises when toDepositFromStakingPool fully occupies the available deposit room (strategyDepositRoom). In this case, strategyDepositRoom - toDepositFromStakingPool can become zero, resulting in toDepositFromQueue being zero, even if there are tokens available in the queue. As a result, no queued tokens are deposited, delaying their utilization.”

Impact:

  • Inefficient Token Utilization: Queued tokens may remain unused, reducing the efficiency of the staking process. This delay in token deployment can lead to reduced staking yields for users who have tokens waiting in the queue.

  • Missed Deposit Opportunities: Even when the system has an opportunity to deposit queued tokens, it fails to do so due to the miscalculation, resulting in potential performance degradation of the staking strategy.

  • Suboptimal System Behavior: The function is designed to prioritize unused staking pool deposits, but the unintended consequence is that queued tokens may not be deposited when they should be, leaving assets idle unnecessarily.”

Proof of Concept:

Consider the following scenario:

-unusedDeposits = 100 LINK: Amount of unused deposits in the staking pool.

  • strategyDepositRoom = 80 LINK: Available room in the staking strategy.
    -_totalQueued = 50 LINK: Tokens waiting in the queue for deposit.
    -_depositMax = 100 LINK: Maximum allowed deposit.

The function's calculations proceed as follows:

  1. toDepositFromStakingPool = MathUpgradeable.min(100, 80, 100) = 80 LINK.

  2. toDepositFromQueue = MathUpgradeable.min(50, 0, 100 - 80) = 0 LINK.

Since the staking pool deposits (80 LINK) fully use the strategyDepositRoom, there is no room left for the queue tokens. Even though 50 LINK is waiting in the queue, none of it is deposited due to the toDepositFromQueue calculation resulting in zero. This leaves the queued tokens undeployed, missing an opportunity to stake them.

Recommended Mitigation:
To ensure that queued tokens are considered for deposit, modify the calculation of toDepositFromQueue to account for any remaining deposit room after handling staking pool deposits. The following adjustment ensures that if there is remaining deposit room, queued tokens are processed:

uint256 remainingDepositRoom = strategyDepositRoom - toDepositFromStakingPool;
uint256 toDepositFromQueue = remainingDepositRoom > 0 ?
MathUpgradeable.min(_totalQueued, remainingDepositRoom) : 0;
Updates

Lead Judging Commences

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

Support

FAQs

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