Liquid Staking

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

missing approvals leads to deposit function revert transaction at certain condition

Summary

No approval for withdrawalPool in PriorityPool::_deposit results in any deposit() call failing when queuedWithdrawals != 0 .

Vulnerability Details

In PriorityPool::_deposit

function _deposit(
address _account,
uint256 _amount,
bool _shouldQueue,
bytes[] memory _data
) internal {
// CODE
611:@> if (totalQueued == 0) {
uint256 queuedWithdrawals = withdrawalPool.getTotalQueuedWithdrawals();
613:@> if (queuedWithdrawals != 0) {
uint256 toDepositIntoQueue = toDeposit <= queuedWithdrawals
? toDeposit
: queuedWithdrawals;
617:@> withdrawalPool.deposit(toDepositIntoQueue); //@audit no approval, this will always revert
toDeposit -= toDepositIntoQueue;
IERC20Upgradeable(address(stakingPool)).safeTransfer(_account, toDepositIntoQueue);
}

If the if statement at Line 611 is satisfied, it will query the queuedWithdrawals and process them according to the logic inside the if statement at Line 613.

At Line 617, we call withdrawalPool.deposit without providing any approvals.

looking at withdrawalPool::deposit() we see that It attempts to transfer the token from PriorityPool, but this operation will always revert due to the lack of approvals.

function deposit(uint256 _amount) external onlyPriorityPool {
token.safeTransferFrom(msg.sender, address(this), _amount);
lst.safeTransfer(msg.sender, _amount);
_finalizeWithdrawals(_amount);
}

this happens because in PriorityPool::initialize() we only gave approvals to _stakingPool , and nothing to withdrawalPool

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));
135:@> token.safeIncreaseAllowance(_stakingPool, type(uint256).max);
}

Impact

PriorityPool::deposit() reverts while totalQueued == 0 and queuedWithdrawals != 0

Tools Used

Manual review

Recommendations

withdrawalPool should have approvals

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.