Delayed Redemptions Liquidation
A delayed redemption is collateral that has been submitted to an issuer but has not yet settled into the output token. Full liquidation can transfer this pending position to the liquidator together with the account's immediate assets.
What a redeemer is
A redeemer is a contract created for one redemption request. It records the request and receives the output tokens when the issuer settles. A gateway records which account owns the redeemer and is the only contract allowed to move funds from it.
During liquidation, ownership of an unclaimed redeemer moves from the Credit Account to the liquidator. The liquidator therefore receives a future claim, not immediately spendable tokens. Once settlement arrives, the liquidator claims the output through the gateway.
Preview before liquidation
The details object returned by
getLiquidationDetails()
contains every output expected from the liquidation. Select the delayed ones:
const delayedOutputs = details.receivedAssets.filter( asset => asset.isDelayed, );
| Value | Type | Meaning |
|---|---|---|
details.receivedAssets | ReceivedAsset[] | Complete list of immediate and delayed liquidation outputs |
delayedOutputs | DelayedReceivedAsset[] | Items from receivedAssets whose isDelayed field is true |
delayedOutputs[].token | Address | ERC-20 expected when the redemption settles |
delayedOutputs[].amount | bigint | Exact amount when claimable; estimate while pending |
delayedOutputs[].redeemerAddress | Address | undefined | Redeemer currently owned by the Credit Account and assigned to the liquidator if execution succeeds |
delayedOutputs[].claimableAt | bigint | undefined | Estimated Unix timestamp; undefined means claimable now |
This preview answers what the liquidator is buying before execution. The redeemer address is informational at this stage: the SDK builds the correct liquidation transaction, including the ownership assignment. After execution, use the liquidator address to query the redeemers it now owns.
List current withdrawals
Using the attached SDK instance, query the delayed withdrawals currently owned by the liquidator after liquidation:
const withdrawals = await sdk.liquidations.getLiquidatorWithdrawals({ liquidator, });
| Value | Type | Meaning |
|---|---|---|
liquidator | Address | Wallet that received the redeemers during liquidation |
withdrawals | LiquidatorWithdrawal[] | Current pending and claimable withdrawals owned by liquidator |
withdrawals[].sourceToken | Address | Asset submitted for redemption |
withdrawals[].token | Address | ERC-20 receivable from settlement |
withdrawals[].amount | bigint | Exact amount when claimable; estimate while pending |
withdrawals[].claimableAt | bigint | undefined | Estimated Unix timestamp; undefined means claimable now |
withdrawals[].redeemer | Address | undefined | Redeemer owned by the liquidator |
The SDK queries every supported redemption gateway and returns its pending and claimable redeemers for the liquidator address. Redeemers do not need to be saved before executing the liquidation. Fully claimed withdrawals are not returned.
Check status with the SDK
Extract the redeemer addresses returned above and query their current status:
const compressor = sdk.withdrawalCompressor; if (!compressor) throw new Error("Delayed withdrawals are not supported"); const redeemers = withdrawals.flatMap(withdrawal => withdrawal.redeemer ? [withdrawal.redeemer] : [], ); const statuses = await compressor.getWithdrawalStatus(...redeemers);
| Variable | Type | Meaning |
|---|---|---|
compressor | IWithdrawalCompressorContract | SDK reader for delayed-withdrawal state |
redeemers | Address[] | Redeemer addresses returned in withdrawals |
statuses | WithdrawalStatus[] | Status corresponding to each address in redeemers |
statuses[i] describes redeemers[i]:
| Status | Meaning |
|---|---|
NULL | The address is not a supported redeemer |
PENDING | The issuer has not completed settlement |
CLAIMABLE | Output tokens are available at the redeemer |
CLAIMED | No pending or claimable output remains |
claimableAt is only an estimate. Use the current status before claiming.
Build claim calls
The high-level method above is intended for monitoring. To obtain encoded claim calls, query the same data through the withdrawal compressor:
await compressor.loadWithdrawableAssets(); const withdrawalTokens = [ ...new Set( compressor .getWithdrawableAssets() .map(asset => asset.withdrawalPhantomToken), ), ]; const current = await compressor.getExternalAccountCurrentWithdrawals( liquidator, ...withdrawalTokens, ); const claimCalls = current.claimable.flatMap( withdrawal => withdrawal.claimCalls, );
| Variable | Type | Meaning |
|---|---|---|
withdrawalTokens | Address[] | Supported delayed-withdrawal configurations known to the SDK |
current | CurrentWithdrawals | Pending and claimable withdrawals returned by the compressor |
current.pending | PendingWithdrawal[] | Withdrawals that have not settled |
current.claimable | ClaimableWithdrawal[] | Settled withdrawals and their encoded claim calls |
claimCalls | MultiCall[] | Calls for all outputs currently available to claim |
Each item in claimCalls contains the protocol gateway in target and the
encoded method in callData. Pass those values to the operator's existing
transaction pipeline.
Protocol-specific redeemers
Securitize
Each redemption request creates a SecuritizeRedeemer. The redeemer sends its
DS tokens to Securitize's redemption account and stores the starting NAV and
timestamp. The resulting stablecoin is later delivered to the redeemer.
The SDK reports:
PENDINGwhile no stablecoin is available andpendingDsTokenAmountis non-zero;CLAIMABLEas soon as the redeemer holds stablecoin; andCLAIMEDafter the gateway has claimed the balance and cleared the pending amount.
While pending, the displayed output is a NAV-based estimate. Once claimable,
the output is the redeemer's actual stablecoin balance. Its generated claim
call targets the SecuritizeRedemptionGateway and encodes
claim([redeemer]); the gateway transfers the complete stablecoin balance to
the liquidator.
Securitize requires the new redeemer owner to be a registered wallet. Check
details.isLiquidatorEligible before liquidation; the transfer reverts if the
liquidator is not eligible.
Source: SecuritizeRedeemer.sol and SecuritizeRedemptionGateway.sol.
Midas
Each redemption request creates a MidasRedeemer. It submits the mToken
redemption to the Midas vault, stores the returned requestId, and records the
start time. The requested quote token is later delivered to the redeemer.
The SDK reports:
PENDINGwhile the Midas request status is pending;CLAIMABLEwhen the request is no longer pending and the redeemer holds quote tokens; andCLAIMEDwhen neither a pending estimate nor claimable quote-token balance remains.
While pending, the displayed output is estimated from the current mToken rate
and the request's quote-token rate. Once claimable, the output is the
redeemer's exact quote-token balance. Its generated claim call targets the
MidasGateway and encodes
withdrawFromRedeemer(redeemer, claimableAmount). Claims are per redeemer.
In permissioned Midas mode, the liquidator must have the gateway's greenlisted
role. Check details.isLiquidatorEligible before submitting the liquidation.
Source: MidasRedeemer.sol and MidasGateway.sol.