Liquid Staking

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

The check for minimum deposit to Staking Pool is bypassed easily

Summary

PriorityPool.sol uses queueDepositMin to validate the minimum amount of tokens deposited to Staking Pool during automated calls of _depositQueuedTokens & otherwise the caller can meniton the _depositMin but both the times it is bypassed as the check in the _depositQueuedTokens function is wrong .

Vulnerability Details

PriorityPool.sol uses
https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/core/priorityPool/PriorityPool.sol#L39C3-L40C36

// min amount of tokens that can be deposited into the staking pool in a single tx
uint128 public queueDepositMin;

to monitor minimum amount deposited to Staking Pool here -
https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/core/priorityPool/PriorityPool.sol#L437C2-L440C6

function performUpkeep(bytes calldata _performData) external {
bytes[] memory depositData = abi.decode(_performData, (bytes[]));
_depositQueuedTokens(queueDepositMin, queueDepositMax, depositData);
}

but when calling _depositQueuedTokens function it is actually checking it with deposit room of Strategy and with sum of _totalQueued + unusedDeposits but instead it should be checking it against toDepositFromQueue which is the actual amount that is send to Staking Pool from Priority Pool and not the others mentioned -
https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/core/priorityPool/PriorityPool.sol#L701C7-L717C1

@> 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
);

Impact

Amounts smaller than _depositMin can be send from PriorityPool.sol bypassing the minimum deposit amount check, which should have been skipped .

Tools Used

Manual Review

Recommendations

Add this check to _depositQueuedTokens function after calculation of toDepositFromQueue

if(toDepositFromQueue < _depositMin)
stakingPool.deposit(address(this), 0, _data);
else
stakingPool.deposit(address(this), toDepositFromQueue, _data);
Updates

Lead Judging Commences

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

Appeal created

angrymustacheman Submitter
8 months ago
inallhonesty Lead Judge
8 months ago
inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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