Skip to main content

Redemptions

Olla is an async vault: burning stAztec for Aztec is a two-step process. The user calls requestRedeem to enqueue a withdrawal, and later claims the finalized assets.

The redemption flow

function requestRedeem(uint256 shares, address controller, address owner)
external
returns (uint256 requestId);

The flow is:

  1. requestRedeem burns shares from owner, locks the current withdrawalRate, and stores a request keyed by requestId. controller is the address authorised to claim it.
  2. During the next rebalance, OllaCore calls finalizeWithdrawals on the vault. Requests are finalized in FIFO order until buffer liquidity is exhausted; if slashing reduced the rate after a request was made, that request's payout is adjusted down at finalization time.
  3. Once a request is finalized, claimableRedeemRequest(requestId, controller) returns a non-zero value. The controller (or an approved operator) can then claim the assets.

Poll for finalization:

uint256 claimable = vault.claimableRedeemRequest(requestId, controller);
if (claimable > 0) {
uint256 assets = vault.claimRequestById(requestId);
}

claimRequestById is the preferred claim entry point because it takes an explicit request id. See Claiming finalized requests for the ERC-4626 alias.

Slippage semantics

requestRedeem has no minAssetsOut parameter. Instead, the exchange rate is locked at the moment the request is enqueued, and the final payout is:

payout = shares * min(lockedRate, rateAtFinalization) / 1e18

In practice this means:

  • If no slashing occurs between request and finalization, the payout equals shares * lockedRate. The user is protected from adverse rate movement after they sign.
  • If slashing occurs, the payout is adjusted down so the loss is shared with non-exiting holders. This cannot be avoided by any participant, by design.

If your integration needs a hard floor on the payout, check claimableRedeemRequest(requestId, controller) before calling the claim function and surface the value to the user. There is no on-chain revert for "payout below target".

note

Because the rate is locked at request time, the user does not need to re-sign or re-quote between request and claim. The only variable is whether a slashing adjustment happens in between.

Permit variant and the owner argument

requestRedeemWithPermit behaves like requestRedeem but pulls shares into the vault using the permit-set allowance:

function requestRedeemWithPermit(
uint256 shares,
address controller,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 requestId);
caution

The permit variant always treats msg.sender as the owner. Unlike requestRedeem(shares, controller, owner), you cannot use it to queue a redemption on behalf of a different owner. For operator-mediated flows, use the non-permit requestRedeem with setOperator (see Operators and Controllers).

Claiming finalized requests

There are two ways to claim a finalized request. Both end up in the same internal path.

✅ Preferred: claim by id

function claimRequestById(uint256 requestId) external returns (uint256 assets);

Takes an explicit request id. Reverts if the request does not exist, is not yet finalized, or the caller is neither the controller nor an approved operator.

❌ Compatibility alias: redeem

function redeem(uint256 shares, address receiver, address controller)
external
returns (uint256 assets);
caution

This is the ERC-7540 redeem. The signature matches ERC-4626 but the semantics are asynchronous: it looks up a finalized request for controller whose share amount matches shares and claims it. If no matching finalized request exists, the call reverts. Generic ERC-4626 tooling will call this expecting a synchronous exit and be surprised. Prefer claimRequestById when you control the integration.

Use maxRedeem(controller) to check the total claimable shares for a controller. Note that maxRedeem on Olla returns claimable shares (finalized and waiting to be claimed), not "how many shares the controller could exit right now via requestRedeem". See ERC-4626 Compatibility for the full table.

Inspecting requests

FunctionReturns
pendingRedeemRequest(requestId, controller)Shares still pending for the given request (zero once finalized)
claimableRedeemRequest(requestId, controller)Assets claimable for the given request (non-zero once finalized)
activeRequestIds(owner)All request ids currently tracked for an owner
maxRedeem(controller)Total claimable shares across all finalized requests for a controller