Assessment reports>Concrete>Design>Component: Withdrawal

Component: Withdrawal

During the withdrawal process, when there are not enough withdrawable assets, the WithdrawalQueue contract is used to store and manage pending withdrawal requests. When transferring assets to the receiver fails, the ParkingLot contract is used to temporarily hold the withdrawn assets.

WithdrawalQueue

When the vault calls the function requestWithdrawal, a new WithdrawalRequest is pushed into the array _requests, which records the following:

  • cumulativeAmount — The sum of all assets submitted for withdrawals, including this request. The amount for this withdrawal request can be derived by calculating the difference between its cumulativeAmount and that of the previous request.

  • recipient — The address that can receive the funds.

  • timestamp — The block.timestamp when the request is created.

  • claimed — This indicates whether the request has been claimed.

The vault owner claims withdrawal requests through the function batchClaimWithdrawal, which uses the function batchClaim of the WithdrawalQueueHelper library to process requests sequentially, starting from the first unclaimed request in the order they were added to the array _requests. During this process, the function prepareWithdrawal of the WithdrawalQueue contract is used to retrieve the recipient and amount for each withdrawal request and to check whether the current _avaliableAssets are sufficient to fulfill the request. If so, it returns the remaining available assets after processing this request; otherwise, it returns an uninitialized avaliableAssets (see Finding ref for details).

function prepareWithdrawal(uint256 _requestId, uint256 _avaliableAssets)
    external
    onlyOwner
    returns (address recipient, uint256 amount, uint256 avaliableAssets)
{
    // [...]
    amount = request.cumulativeAmount - prevRequest.cumulativeAmount;

    if (_avaliableAssets >= amount) {
        assert(_requestsByOwner[recipient].remove(_requestId));
        avaliableAssets = _avaliableAssets - amount;
        request.claimed = true;
        // [...]
    }
}

When the available assets are insufficient or the number of processed requests reaches the maximum value set by the owner, the function batchClaim will call the function _finalize of the WithdrawalQueue contract to update the storage variable lastFinalizedRequestId, which records the last claimed request ID.

ParkingLot

When transferring assets to the receiver fails, the vault will deposit the withdrawn assets into the ParkingLot contract. This contract records the total amount of assets each receiver is entitled to receive, as well as the timestamp of each receiver's most recent deposit by the vault.

Users can withdraw temporarily stored assets at any time through the function withdraw of the ParkingLot contract. However, if the assets remain unclaimed for more than one year since the last deposit, the _rescuer can withdraw them using the function rescueFunds.

Zellic © 2025Back to top ↑