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 itscumulativeAmount
and that of the previous request.recipient
— The address that can receive the funds.timestamp
— Theblock.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
.