Liquid Staking

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

Queued withdrawals need slippage protection because users can end up withdrawing less/more than expected

Vulnerability Details

Queued withdrawals need slippage protection. Users enter the asset amount they wish to withdraw, but they end up withdrawing a different amount. This final amount is set during the WithdrawalPool::_finalizeWithdrawals function, which can get called at a much later time than the withdrawal initiation and the assets-shares ratio has changed a lot.

function _finalizeWithdrawals(uint256 _amount) internal {
uint256 sharesToWithdraw = _getSharesByStake(_amount);
uint256 numWithdrawals = queuedWithdrawals.length;
totalQueuedShareWithdrawals -= sharesToWithdraw;
for (uint256 i = indexOfNextWithdrawal; i < numWithdrawals; ++i) {
uint256 sharesRemaining = queuedWithdrawals[i].sharesRemaining;
if (sharesRemaining < sharesToWithdraw) {
// fully finalize withdrawal
sharesToWithdraw -= sharesRemaining;
continue;
}
if (sharesRemaining > sharesToWithdraw) {
// partially finalize withdrawal
queuedWithdrawals[i] = Withdrawal(
uint128(sharesRemaining - sharesToWithdraw),
uint128(queuedWithdrawals[i].partiallyWithdrawableAmount + _getStakeByShares(sharesToWithdraw))
);
indexOfNextWithdrawal = i;
@> withdrawalBatches.push(WithdrawalBatch(uint128(i - 1), uint128(_getStakeByShares(1 ether))));
} else {
// fully finalize withdrawal
indexOfNextWithdrawal = i + 1;
@> withdrawalBatches.push(WithdrawalBatch(uint128(i), uint128(_getStakeByShares(1 ether))));
}
sharesToWithdraw = 0;
break;
}
// entire amount must be accounted for
assert(sharesToWithdraw == 0);
emit WithdrawalsFinalized(_amount);
}

Here is the point that the assets-share ratio gets captured for the withdrawals of this batch.

Impact

Users may withdraw significantly less or more than they expected too, depending on the assets-share ratio during the finalization of the withdrawal.

Tools Used

Manual review

Recommendations

Capture the assets-share ratio at the time of the withdrawal initiation or add slippage protection and return back the stLink if the withdrawal falls outside the slippage.

Updates

Lead Judging Commences

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.