Purpose
TheRedeemQueue contract enables delayed, batched redemptions of vault shares into underlying assets. Redemptions are processed in two phases:
- Oracle pricing – Shares are priced via a trusted price report.
- Liquidity settlement – Vault liquidity is allocated to fulfill priced requests.
Overview
TheRedeemQueue enables users to convert their vault shares into underlying assets, introducing a time delay enforced by an oracle-defined redeemInterval. It maintains the following core invariants:
- Request Format: Each request is structured as a
(shares, timestamp)pair. - Non-Cancellable: Redemption requests cannot be cancelled to prevent griefing (e.g., submitting and canceling after unstaking starts).
- Multiple Requests Allowed: Users may submit multiple independent redemption requests.
reportTimestamp, the system processes all requests with:
Liquidity Processing (Two-Stage)
To enable flexible and asynchronous liquidity management, redemption is handled in two distinct phases:- Post-Request: Vault curators monitor and, if needed, pull liquidity from external protocols.
-
Post-Oracle Report:
- Once a valid report is submitted and sufficient liquidity is available,
- The vault curator (or any other trusted actor) invokes
handleBatches(n)on theRedeemQueue, - This action triggers the movement of required assets from the vault (and associated subvaults) to process redemption requests.
Scalability Approach
Unlike deposits, redemption requests are never cancelled, which allows for a simplified and gas-efficient tracking model: A prefix sum array is used to efficiently manage cumulative share redemptions over time.Redemption Processing Logic
-
On Redemption:
When a user redeems
amountof shares at timeT, the system logs:prefixSum[T] += amount -
On Oracle Report:
At
reportTimestamp, all requests with:are marked as processed. -
Post-Processing:
- The curator ensures the necessary asset liquidity is available,
- Then calls
handleBatches()to finalize processing.
-
User Claim:
After requests are processed, users can call:
to claim assets for their requested vault shares corresponding to each processed timestamp.
Storage Layout
All internal state is maintained inRedeemQueueStorage, including:
Structs
Request
Represents a single redemption request from a user:
timestamp: When the request was submitted.shares: Amount of vault shares being redeemed.isClaimable: Set to true after batch is fulfilled.assets: Amount of assets claimable for this request (set after pricing).
Batch
Represents a priced redemption batch:
assets: Total value fulfilled for the batch (via oracleshares / report.price).shares: Total shares matched in this batch.
View Functions
requestsOf(account, offset, limit)
Returns paginated redemption request data for the specified account. Each request includes:
- Timestamp
- Shares
- Claimable status
- Asset amount
batchAt(index)
Returns the (assets, shares) for a given redemption batch.
getState()
Returns core system state:
- Current
batchIterator(next unfulfilled batch index) - Total
batches - Total
demandedAssetsstill awaiting liquidity - Total
pendingSharesthat are not yet claimable
State Transition Guarantees
- Non-Cancellable Requests
- Prevents griefing where a user requests redemption, causing curator to pull liquidity, then cancels.
- Price Separation
- Oracle reports must be delayed by at least
redeemIntervalseconds from the original request.
- Oracle reports must be delayed by at least
- Asynchronous Fulfillment
- Liquidity can be managed independently of oracle report submission.
Events
RedeemRequested(account, shares, timestamp)RedeemRequestClaimed(account, receiver, assets, timestamp)RedeemRequestsHandled(counter, demand)