Withdrawal Queue Mechanics
Overview
The withdrawal queue system orchestrates asset withdrawals across multiple chains and vaults through two fixed-size queues:
Local queue for same-chain vaults
Cross-chain queue for vaults on other networks
Queue Structure
// Fixed size for all queues
uint256 public constant WITHDRAWAL_QUEUE_SIZE = 30;
// Queue storage
uint256[WITHDRAWAL_QUEUE_SIZE] public localWithdrawalQueue;
uint256[WITHDRAWAL_QUEUE_SIZE] public xChainWithdrawalQueue;Queue Management
Queue Registration
/// @notice Add a new vault to the portfolio
/// @param chainId chainId of the vault
/// @param superformId id of superform in case its crosschain
/// @param vault vault address
/// @param vaultDecimals decimals of ERC4626 token
/// @param oracle vault shares price oracle
function addVault(
uint32 chainId,
uint256 superformId,
address vault,
uint8 vaultDecimals,
ISharePriceOracle oracle
)
external
onlyRoles(MANAGER_ROLE)
{
if (superformId == 0) revert();
// If its already listed revert
if (isVaultListed(vault)) revert VaultAlreadyListed();
// Save it into storage
vaults[superformId].chainId = chainId;
vaults[superformId].superformId = superformId;
vaults[superformId].vaultAddress = vault;
vaults[superformId].decimals = vaultDecimals;
vaults[superformId].oracle = oracle;
uint192 lastSharePrice = vaults[superformId].sharePrice(asset()).toUint192();
if (lastSharePrice == 0) revert();
_vaultToSuperformId[vault] = superformId;
if (chainId == THIS_CHAIN_ID) {
// Push it to the local withdrawal queue
uint256[WITHDRAWAL_QUEUE_SIZE] memory queue = localWithdrawalQueue;
for (uint256 i = 0; i != WITHDRAWAL_QUEUE_SIZE; i++) {
if (queue[i] == 0) {
localWithdrawalQueue[i] = superformId;
break;
}
}
// If its on the same chain perfom approval to vault
asset().safeApprove(vault, type(uint256).max);
} else {
// Push it to the crosschain withdrawal queue
uint256[WITHDRAWAL_QUEUE_SIZE] memory queue = xChainWithdrawalQueue;
for (uint256 i = 0; i != WITHDRAWAL_QUEUE_SIZE; i++) {
if (queue[i] == 0) {
xChainWithdrawalQueue[i] = superformId;
break;
}
}
}
emit AddVault(chainId, vault);
}Withdrawal Processing
State Tracking
Withdrawal Route Calculation
Queue Processing Logic
Asset Tracking
Optimization Strategies
Gas Optimizations
Prioritizes idle assets (no withdrawal cost)
Processes local withdrawals before cross-chain
Batches cross-chain operations
Uses unchecked blocks for counters
Caches chain indexes and lengths
Slippage Protection
Asset Validation
Gas Analysis
Estimated Costs
Local withdrawals: ~100k-200k gas
Cross-chain operations: varies by chain
Batch processing savings
Queue Security Implications
Maximum queue size impact
Reordering attack vectors
Front-running mitigations
Slippage Protection Analysis
Minimum output validation
Cross-chain slippage handling
Price impact considerations
Error Types
Last updated