StakeXDCDocs
Liquid staking

Withdrawals: instant vs queued

Every withdrawal goes through redeemWithQueue. It settles instantly while the vault has liquidity; otherwise it joins a public queue paid by position, recomputed at the share price when processed, and cancellable before processing.

Every withdrawal on the V3.2 vault goes through redeemWithQueue (or withdrawWithQueue). The vault automatically picks the fastest path your balance and the vault's liquidity allow: no admin approval, no per-user setting to flip.

Two separate pools of XDC. Instant withdrawals are served from the vault's free liquidity, which new deposits refill. Queued requests are paid from a dedicated queue budget that operations fund as masternode principal returns. New stakers' deposits are never consumed by the queue, and queued users are paid in order as each funding tranche arrives.

If your request is queued: the app shows your position in the queue and the total waiting ahead of you, not a date. When a backlog exists, the team resigns masternodes to fund the queue budget; the network enforces its own unbonding period (candidateWithdrawDelay, ~35 days from resignation under typical block times) before that XDC returns. As it is routed into the queue budget, requests are paid out in FIFO order (a request larger than the budget available at that moment is passed over and retried on the next pass, so smaller requests behind it can settle earlier). Your psXDC stays escrowed at its full share value while you wait and keeps following the share price. No action is needed from you, and you can cancel at any time to get your psXDC back.


The choice the vault makes for you

User calls redeemWithQueue(shares, receiver)
                        │
                        ▼
           ┌────────────────────────┐
           │  Does the buffer hold  │
   yes ◄───┤  enough XDC to cover   ├───► no
           │  shares × NAV?         │
           └────────────────────────┘
            │                          │
            ▼                          ▼
   Instant redeem in this tx   Escrow shares, enqueue FIFO
            │                          │
            ▼                          ▼
   Receive XDC immediately     Wait → paid to your wallet when processed

"Enough XDC" means the vault's unencumbered liquidity: its native balance minus what is already earmarked for the queue and for failed payouts (V3.2 removed the old percentage-based bufferBps buffer). When maxRedeem(you) covers the shares you're redeeming, the path is instant; otherwise the queue kicks in. Practically: while a queue backlog exists, most free liquidity is earmarked, so expect the queued path during those periods.


Path A: Instant redeem

When liquidity is sufficient:

  • Your psXDC shares are burned immediately.
  • XDC is sent to your receiver in the same transaction.
  • No queue entry is created.

Use cases: routine withdrawals while the vault has free liquidity, partner integrations expecting synchronous settlement.


Path B: Queued redeem

When liquidity is constrained:

  • Your psXDC shares are escrowed inside the vault (not burned).
  • A WithdrawalQueued(requestId, owner, shares) event is emitted.
  • The request enters the global FIFO queue, ordered by enqueue timestamp.

How the queue is drained

Anyone can call processWithdrawalQueue(maxRequests), which:

  1. Walks the FIFO, oldest first.
  2. For each request, values the escrowed shares at the current exchange rate (previewRedeem(shares)) and compares that against the queue budget (queueBackingBudget) — the XDC ring-fenced for queued requests. The vault's free liquidity that serves instant redemptions is not used for the queue.
  3. If the budget covers the request, it burns the escrowed shares and sends XDC to the original receiver. If it does not, the request is passed over, not cancelled — the processor moves on and tries the next request, and the skipped one is retried on the next pass once more budget has arrived. In practice this means a small request can settle before a larger, older one when the budget is topped up in tranches.
  4. If the receiver payout fails (e.g. a smart contract receiver that reverts on payment), the XDC is deferred into pendingQueuedAssets[receiver]. The user collects it later via claimQueuedAssets.

Auto-propose (the function that pushes new XDC into masternodes) is blocked while there is any backlog, so the protocol prioritizes outgoing user redemptions over locking up more XDC.

What replenishes liquidity

Two separate pools of XDC matter here:

  • The instant buffer (unencumbered vault balance) grows from new user deposits (any stake adds XDC) and any XDC returned from masternode resignations that is not earmarked for the queue. It serves redeemWithQueue calls that can settle immediately.
  • The queue budget (queueBackingBudget) grows only from XDC explicitly routed to it: the operations team's liquidity tranches (sent from the wallet holding MIGRATION_MANAGER_ROLE, a legacy role name; the vault earmarks these sends for queued requests) and, when a masternode is resigned through the vault, the returned principal up to the queue's unfunded amount. Instant withdrawals can never consume it, and deposits do not flow into it.

Masternode resignations return principal after the network's candidateWithdrawDelay (~35 days under typical block times). That unbonding delay is the main input to how fast the queue budget refills; it is a network property, not a settlement promise.

Queued requests keep following NAV until they are paid

Your request records the XDC value at enqueue time for the vault's accounting, but the payout is recomputed when the request is processed: the processor pays previewRedeem(shares) at the exchange rate of that moment. Reward distributions that land while you wait therefore do reach you — your escrowed shares keep appreciating exactly like unstaked psXDC. There is no reason to cancel and re-queue to capture a NAV increase; doing so only sends you to the back of the FIFO.

The queue is public — position, not a date

Every queued request is public on-chain data, and the app's Queue explorer card (on the public Transparency page, and also on Withdraw and Overview) shows the whole FIFO: each request's position, size, owner wallet and the XDC it would receive at the current share price, plus the total queued. Your own requests are highlighted.

Queue explorer: total queued, requests waiting, and every request by position with its escrowed psXDC and the XDC it would receive at the current share price

The app shows your position (e.g. #3 of 12) and the total queued ahead of you. No settlement date is shown or promised: smaller requests may settle first, and the payout is recomputed at the share price when processed. What the contract does guarantee: requests are processed in first-in-first-out order from the dedicated queue budget, a request the budget cannot yet cover is passed over (never cancelled) and retried on the next pass, escrowed shares are valued at the exchange rate of the moment they are paid, and you can cancel and recover your psXDC at any time.

Cancelling

You can call cancelQueuedWithdrawal(requestId) at any time before settlement. The escrowed psXDC shares are returned to your wallet; no XDC moves and nothing is lost.

Self-claim with claimQueuedAssets

Payouts normally land in your wallet automatically when the queue processes your request. If you ever see a queued request with a Claim button in the app, that means the queue processed your request but the XDC ended up in pendingQueuedAssets (e.g. your receiver bounced). Calling claimQueuedAssets(receiver) sweeps every XDC waiting for you into your wallet.


How the app uses these paths

The StakeXDC UI always calls redeemWithQueue; it never picks the path manually. Before you press Review withdrawal, the verdict panel tells you which path the transaction will take:

  • Instant — the vault has enough liquid XDC; the redemption settles in this transaction.
  • Joins the queue — the vault does not hold enough liquid XDC; your psXDC is escrowed and you enter the queue behind N requests. No settlement date is promised, and you can cancel any time before it is processed.

See the Request a withdrawal walkthrough for the step-by-step flow.

On this page