StETHRedeemManager
Title: StETHRedeemManager
Abstract contract implementing EIP-7540 Asynchronous ERC-4626 Tokenized Vaults.
LP shares are burned immediately on requestRedeem; WETH is delivered
asynchronously in FIFO order as Lido withdrawal claims arrive.
Supports partial fulfillment: a request can receive a portion of its WETH now
and the remainder from future Lido claims.
Actors:
- owner - whose shares are burned on requestRedeem.
- controller - controls when and to whom assets are claimed.
- operator - approved by owner/controller to act on their behalf.
Flow:
- Owner (or operator for owner) calls
requestRedeem(shares, controller, owner). Shares burned immediately; a request record is created forcontroller. - As ETH arrives from Lido claims,
_serveRedeemRequestsallocates WETH to the oldest pending requests first (FIFO). Partial allocation is supported:_redeemHeadadvances only when a request is fully allocated. - Controller (or operator for controller) calls
claimRedeem(receiver, controller)which transfers all currently claimable WETH for that controller toreceiver.
Accounting invariants:
_pendingRedeemAssets= sum of (assets - claimableAssets) for all requests. Subtracted from totalAssets() so remaining LPs see the correct share price._reservedRedeemAssets= sum of (claimableAssets - claimedAssets) for all requests. Excluded from swap liquidity and from totalAssets().
Functions
setOperator
Grant or revoke operator privileges for msg.sender as controller.
Operators can call requestRedeem and claimRedeem on behalf of the controller.
function setOperator(address operator, bool approved) external returns (bool);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Always true (EIP-7540 compliance). |
isOperator
Returns whether operator is approved to act on behalf of controller.
function isOperator(address controller, address operator) public view returns (bool);
requestRedeem
Burn shares from owner and register an async redemption request.
The WETH payout is delivered asynchronously (FIFO) as Lido withdrawal
claims arrive. Caller must be owner or an approved operator for owner.
function requestRedeem(uint256 shares, address controller, address owner)
public
virtual
returns (uint256 requestId);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Vault shares to redeem. |
controller | address | Address that will control when/to whom assets are claimed. |
owner | address | Address whose shares are burned. |
Returns
| Name | Type | Description |
|---|---|---|
requestId | uint256 | Global ID for this request (use with claimRedeem). |
claimRedeem
Transfer all currently claimable WETH for controller to receiver.
Caller must be controller or an approved operator for controller.
function claimRedeem(address receiver, address controller) public virtual returns (uint256 totalClaimed);
Parameters
| Name | Type | Description |
|---|---|---|
receiver | address | Address to receive the WETH. |
controller | address | The controller whose claimable assets are claimed. |
Returns
| Name | Type | Description |
|---|---|---|
totalClaimed | uint256 | Total WETH transferred (0 if nothing is currently claimable). |
redeemRequestIds
Returns all request IDs controlled by controller (including fully claimed ones).
function redeemRequestIds(address controller) external view returns (uint256[] memory);
redeemRequest
Returns the full status of a single request.
function redeemRequest(uint256 requestId)
external
view
returns (uint256 assets, address controller, uint256 claimableAssets, uint256 claimedAssets);
redeemQueueLength
Total number of requests ever created (includes fully claimed ones).
function redeemQueueLength() external view returns (uint256);
reservedRedeemAssets
WETH currently reserved for allocated (but not yet claimed) redeem requests. This WETH is excluded from swap liquidity.
function reservedRedeemAssets() external view returns (uint256);
pendingRedeemRequest
EIP-7540: assets still pending allocation for a specific request.
Returns 0 if controller does not match the request's controller.
function pendingRedeemRequest(uint256 requestId, address controller) external view returns (uint256);
claimableRedeemRequest
EIP-7540: assets claimable but not yet claimed for a specific request.
Returns 0 if controller does not match the request's controller.
function claimableRedeemRequest(uint256 requestId, address controller) external view returns (uint256);
Events
OperatorSet
Emitted when a controller grants or revokes operator status (EIP-7540).
event OperatorSet(address indexed controller, address indexed operator, bool approved);
RedeemRequested
Emitted when an LP submits a redemption request.
event RedeemRequested(
uint256 indexed requestId,
address indexed controller,
address indexed owner,
uint256 shares,
uint256 assets
);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | Global ID assigned to this request. |
controller | address | Address that controls claiming for this request. |
owner | address | Address whose shares were burned. |
shares | uint256 | Vault shares burned. |
assets | uint256 | WETH amount promised. |
RedeemClaimed
Emitted when claimable WETH is transferred to a receiver.
event RedeemClaimed(address indexed receiver, address indexed controller, uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
receiver | address | Address that received the WETH. |
controller | address | Controller whose claimable assets were claimed. |
assets | uint256 | Amount of WETH transferred. |
Errors
NotAuthorized
error NotAuthorized();
MinSharesRequired
error MinSharesRequired(uint256 shares, uint256 minimum);
InsufficientClaimable
error InsufficientClaimable();
Structs
RedeemRequest
One entry per redemption request.
struct RedeemRequest {
uint256 assets; // total WETH owed (fixed at requestRedeem time)
address controller; // address that controls when/to whom assets are claimed
uint256 claimableAssets; // WETH allocated so far (may be partial)
uint256 claimedAssets; // WETH already transferred to a receiver
}