Processing User Redemptions
Reserve vs Component Fulfilment
Fulfilling a redemption request will have a different impact on the performance of the Node depending on whether the reserve balance or a component balance is utilized. See more details here.
Overview
User redemptions in the protocol follow an asynchronous pattern:
User requests redemption (shares → Escrow)
Rebalancer fulfills redemption (Node → Escrow)
User claims assets (Escrow → User)
Request State Structure
struct Request {
uint256 pendingRedeemRequest; // Shares waiting to be processed
uint256 claimableRedeemRequest; // Shares processed and ready
uint256 claimableAssets; // Assets ready for withdrawal
uint256 sharesAdjusted; // Shares after swing pricing
}
Step 1: User Requests Redemption
function requestRedeem(
uint256 shares,
address controller,
address owner
) external returns (uint256)
Actions:
Validates owner permissions
Transfers shares to Escrow
Updates request state:
request.pendingRedeemRequest += shares request.sharesAdjusted += adjustedShares // If swing pricing enabled sharesExiting += shares // Tracks total pending redemptions
Step 2: Rebalancer Fulfills Redemption
Three fulfillment methods:
A. From Reserve
function fulfillRedeemFromReserve(address controller)
function fulfillRedeemBatch(address[] memory controllers)
B. From ERC4626 Component
function fulfillRedeemRequest(
address node,
address controller,
address component
) external returns (uint256 assetsReturned)
C. From ERC7540 Component
function fulfillRedeemRequest(
address node,
address controller,
address component
) external returns (uint256 assetsReturned)
All methods eventually call:
function finalizeRedemption(
address controller,
uint256 assetsToReturn,
uint256 sharesPending,
uint256 sharesAdjusted
) external
Which:
Burns shares from Escrow
Updates request state:
request.pendingRedeemRequest -= sharesPending request.claimableRedeemRequest += sharesPending request.claimableAssets += assetsToReturn request.sharesAdjusted -= sharesAdjusted sharesExiting -= sharesPending
Transfers assets to Escrow
Step 3: User Claims Assets
Users can claim using either:
function withdraw(uint256 assets, address receiver, address controller)
function redeem(uint256 shares, address receiver, address controller)
These functions:
Check available assets via
maxWithdraw()
ormaxRedeem()
Transfer assets from Escrow to receiver
Decrement claimable amounts
Important Notes
Liquidation Order
Reserve is always used first
Components follow liquidationQueue order
Enforced by
enforceLiquidationOrder()
Swing Pricing
Applied at request time
Stored in
sharesAdjusted
Affects final asset amount
State Tracking
sharesExiting
tracks total pending redemptionsUsed for reserve calculations
Updated during request and fulfillment
Timing
Fulfillment only during rebalance window
Claims can happen anytime
No timeout on pending requests
Last updated