Liquid Staking

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

Potential Denial of Service (DoS) in `WithdrawalPool.sol`'s `_finalizeWithdrawals` Function

Summary

A Denial of Service (DoS) vulnerability exists in the WithdrawalPool.sol contract within the _finalizeWithdrawals function. By queuing an excessive number of withdrawal requests, an attacker can cause the function to exceed the block gas limit during execution. This results in failed transactions, preventing the processing of withdrawals and effectively halting the withdrawal functionality of the staking platform.

Vulnerability Details

Excessive Withdrawal Queueing

// Attacker queues a large number of withdrawal requests
for (uint256 i = 0; i < 10000; i++) {
withdrawalPool.queueWithdrawal(attackerAddress, 1 ether);
}

Explanation:

The attacker repeatedly invokes the queueWithdrawal function to add a substantial number of withdrawal requests to the queuedWithdrawals array. This dramatically increases the length of the array, setting the stage for gas exhaustion when the contract attempts to process these withdrawals.

Triggering the Finalization Process

// Attacker attempts to finalize withdrawals, causing gas exhaustion
withdrawalPool.performUpkeep(performData);

Explanation:

When performUpkeep is called, it internally invokes _finalizeWithdrawals. Due to the inflated size of the queuedWithdrawals array, the for-loop within _finalizeWithdrawals consumes an excessive amount of gas. This exceeds the block gas limit, causing the transaction to revert and preventing any withdrawals from being processed.

Partial Withdrawal Processing

// Attempting to process withdrawals after queueing
withdrawalPool.withdraw(withdrawalIds, batchIds);

Explanation:

Even attempts to process individual withdrawals using the withdraw function can fail if the underlying loop in _finalizeWithdrawals is already gas-exhausted. This ensures that the withdrawal functionality remains unusable until the queue is reduced to a manageable size.

Impact

  • Service Disruption: Legitimate users are unable to process their withdrawal requests, leading to inaccessibility of funds.

  • Operational Halting: Core functionalities of the staking platform are compromised, affecting user trust and platform reliability.

  • Financial Loss: Users may experience delays in accessing their staked funds, potentially leading to financial losses if liquidity is urgently needed.

Tools Used

  • Manual Code Review

Recommendations

1. Process Withdrawals in Batches

Implementation:

Modify the _finalizeWithdrawals function to handle a fixed number of withdrawals per transaction, thereby preventing gas exhaustion.

function _finalizeWithdrawals(uint256 _amount, uint256 _maxIterations) internal {
uint256 iterations = 0;
for (uint256 i = indexOfNextWithdrawal; i < queuedWithdrawals.length && iterations < _maxIterations; ++i) {
// Existing processing logic
iterations++;
if (iterations >= _maxIterations) {
break;
}
}
// Handle remaining withdrawals as needed
}

Explanation:

By introducing a _maxIterations parameter, the function limits the number of withdrawals processed in a single transaction. This ensures that the function remains within the gas limits, even when a large number of withdrawals are queued.

2. Implement a Maximum Queue Size

Implementation:

Set a cap on the number of withdrawal requests that can be queued at any given time.

uint256 public constant MAX_QUEUED_WITHDRAWALS = 1000;
function queueWithdrawal(address _account, uint256 _amount) external onlyPriorityPool {
require(queuedWithdrawals.length < MAX_QUEUED_WITHDRAWALS, "Withdrawal queue is full");
// Existing queueing logic
}

Explanation:

By enforcing a maximum limit on the queuedWithdrawals array, the contract prevents the queue from growing indefinitely. This mitigates the risk of gas exhaustion during the withdrawal finalization process.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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