Withdraw

Withdraw by unstaking sPLUSD to PLUSD if needed, escrowing PLUSD into the WithdrawalQueue, and claiming USDC yourself. The claim re-screens your address, burns your PLUSD, and pulls USDC from the Withdrawal Queue Wallet via the queue contract’s standing allowance. Single call, no off-chain signer in the critical path.

Withdraw to settle. User-pulled claim from the Withdrawal Queue Wallet via standing allowance. Claim re-checks compliance, burns PLUSD, and pays USDC atomically.
Withdraw to settle. User-pulled claim from the Withdrawal Queue Wallet via standing allowance. Claim re-checks compliance, burns PLUSD, and pays USDC atomically.

Flow

  1. Unstake sPLUSD by calling sPLUSD.redeem(shares). PLUSD returns to your wallet. Skip if you already hold PLUSD.
  2. Call WithdrawalQueue.requestWithdrawal(amount). Your PLUSD moves into the queue's escrow and a queue_id is assigned. The queue's totalRequested aggregate increases. The PLUSD transfer to the queue triggers PLUSD._update, which checks your whitelist entry and the 90-day freshness window. A stale or revoked entry reverts the request.
  3. The Relayer detects your request and runs KYT on your address off-chain. On a clean result, the Relayer signs a claim attestation and serves it via API. Your frontend fetches the attestation when ready.
  4. Call WithdrawalQueue.claim(queueId, attestation, signature) yourself when you're ready. The queue verifies the signature against the configured attestor address, re-checks WhitelistRegistry.isAllowed(you) as a backstop, checks claimAmount ≤ totalClaimable, calls USDC.transferFrom(WithdrawalQueueWallet, you, amount) against the standing allowance, burns your escrowed PLUSD, and increments totalClaimed. All in the same transaction.
Self-pulled. No Relayer signature, no off-chain step, no waiting for an external party to fund your entry. The Withdrawal Queue Wallet is topped up periodically by the Trustee and Team from the Capital Wallet under the 3-of-5 cosigner quorum. As long as the wallet has USDC, the queue has allowance against it, and your address is still whitelisted, you can claim immediately.

Compliance re-check at claim

Whitelist entries can be revoked between request and claim if a sanctions hit lands on your address (passive re-screening, OFAC list update, manual revoke). The claim re-check catches this. If revoked, the claim reverts and your escrowed PLUSD stays in the queue pending ADMIN disposition.

If your whitelist entry’s freshness window expires (no clean screen in 90 days), the request itself reverts at PLUSD._update. Re-enrol via the standalone enrolment endpoint (see Onboarding) to refresh, then retry the request.

Queue aggregates

The WithdrawalQueue tracks three numbers that bound everything:

Aggregate What it is
totalRequested Cumulative PLUSD escrowed across all withdrawal requests ever submitted
totalClaimed Cumulative USDC paid out (equals cumulative PLUSD burned via claim)
totalClaimable Currently outstanding obligations: totalRequested - totalClaimed

The safety invariant on every claim is require(claimAmount ≤ totalClaimable). This is independent of the allowance from the Withdrawal Queue Wallet. Even if allowance is set to MAX_UINT, the queue physically refuses to pull more than it owes. Allowance is the permission ceiling. The aggregate ledger is the spending discipline.

Delays

During shutdown

If the protocol has set an exchange coefficient on the WithdrawalQueue (see Default management), every claim pays out USDC at face_value * coefficient instead of face_value * 1.0. The coefficient applies the same way to PLUSD direct-redeem and sPLUSD-unstake-then-redeem. The coefficient ratchets up only as recoveries land. Once coefficient = 1.0, normal economics resume.

There is no separate “shutdown mode”. The protocol continues operating with the haircut applied at the queue.