OriginDOCS

Settlement & Custody

Deposits & Withdrawals

Deposits

Origin accepts deposits of Arc-native stablecoins, crypto, and RWAs. Users transfer the asset to the Margin Vault address; on confirmation (sub-second, given Arc's deterministic finality), the asset is credited to the user's collateral balance and immediately available for trading.

Deposits are confirmed once Arc finalizes the block containing the transfer. Because Arc finality is deterministic and sub-second, there is no probabilistic confirmation count. Finalized means final.

Withdrawals

Users can withdraw any portion of their free collateral (collateral not locked as initial margin against open positions, and not reserved as Order Margin against open orders) at any time. Withdrawals are processed by submitting a withdrawal request that the Margin Vault validates against the user's solvency post-withdrawal: the account must remain HEALTHY after the withdrawal.

Approved withdrawals settle on Arc within sub-second finality. There is no withdrawal queue or hold period for routine withdrawals.

WebSocket Event Trust Model

Origin's off-chain components emit a deterministic event stream over WebSocket: order acknowledgments, fills, position updates, funding payments, liquidations, and ADL events. This event stream is the canonical source of truth for client-side state.

WebSocket Fills are Authoritative for Trading

When the matching engine produces a fill, the fill event is emitted to both counterparties over WebSocket within milliseconds. Clients should treat the WebSocket fill event as definitive: the trade has occurred, the position has changed, the realized PnL is booked.

This is correct because:

  1. The matching engine is deterministic. Given the same sequenced inputs, it produces the same fills. The fill the client sees over WebSocket is the same fill that will be committed on-chain.
  2. Risk invariants are pre-checked. A fill that would violate solvency invariants (Section 5.2.4) is auto-cancelled before any WebSocket event is emitted. There is no scenario where a client sees a fill event that subsequently fails to settle on-chain.
  3. Settlement cadence is short. Settlement batches commit at sub-second cadence on active markets; the gap between WebSocket fill and on-chain finality is bounded and short.

On-Chain Settlement Confirms Finality

The on-chain settlement event signals that the fill is now part of the canonical Arc-anchored exchange state. This matters for:

  • Auditability. Every fill is publicly verifiable on Arc.
  • Self-custody. Once settled on-chain, the position and balance changes are reflected in the Margin Vault. If the off-chain operator subsequently fails, the on-chain state at the most recent batch is the user's authoritative balance.
  • Compliance and reporting. Tax and regulatory reporting derives from on-chain records.

For trading decisions, the WebSocket event is sufficient and authoritative. For custody assurance, the on-chain event is the moment of finality.

Sequence Numbers and Gap Detection

Every WebSocket message carries a per-stream monotonically increasing sequence number. Clients should:

  • Verify sequence numbers are contiguous on each stream.
  • On gap, reconnect and request a snapshot (private streams) or a partial replay (public streams).
  • Never assume an event was missed silently; gaps always indicate transport-level issues.

Reconciliation

Origin publishes account-state and order-state endpoints (REST) that return the canonical position, balance, and open-order set. Production trading systems should reconcile against these endpoints periodically (default 60 seconds) to detect any divergence between local and server state. Reconciliation discrepancies are extremely rare but possible during stream reconnections; the REST endpoint always reflects the post-fill state visible to the matching engine.

Settlement Batch Structure

A settlement batch is a signed message submitted by the Settlement Submitter to the on-chain Settlement contract. Its structure:

BatchHeader
    batch_id              uint64
    parent_batch_id       uint64
    sequencer_timestamp   uint64        (engine timestamp at batch close)
    market_state_root     bytes32       (Merkle root of all market states)
    account_state_root    bytes32       (Merkle root of all account states)

BatchBody
    fills[]               list<FillRecord>
    funding_settlements[] list<FundingRecord>
    liquidations[]        list<LiquidationRecord>
    adl_events[]          list<ADLRecord>
    deposit_acks[]        list<DepositAck>
    withdrawal_reqs[]     list<WithdrawalRequest>

Signature
    submitter_signature   bytes65       (signed over BatchHeader || H(BatchBody))

The on-chain Settlement contract validates:

  1. Signature is from the authorized submitter.
  2. parent_batch_id matches the most recent finalized batch (no skips, no forks).
  3. Each individual record passes its own invariants. Fills must reference real accounts and pay correct fees; liquidations must satisfy bankruptcy bounds; withdrawals must leave the account HEALTHY.
  4. The aggregate state-root transition is consistent with the records.

If any check fails, the entire batch is rejected and resubmitted. There is no partial commit.

Cadence

Batch commit cadence is configurable per system load. On active markets during peak hours, batches commit at 250 to 500ms intervals. During quiet periods, batches commit on a longer schedule to amortize gas, with a maximum interval bound (default 5 seconds) to keep client-visible finality predictable.

Reorg Resistance

Because Arc has deterministic finality, there is no reorg model: once a batch is included in a finalized Arc block, it is irreversible. Clients do not need to wait for a confirmation count.

On-Chain Records

Every settlement, liquidation, ADL event, and funding payment is recorded on-chain on Arc. These records are publicly auditable and form the canonical history of the exchange.

Self-Custody Guarantees

The Margin Vault provides an emergency exit path: if the off-chain operator goes offline or becomes unresponsive past a threshold (default 24 hours), users can withdraw free collateral directly through an on-chain procedure that does not depend on the operator. This bounds the worst-case impact of operator failure to (a) inability to trade, and (b) inability to apply pending fills, neither of which can result in loss of custody. The transition into this mode and its mechanics are specified in Section 10.1.

FX Settlement via StableFX

StableFX is not invoked on every trade. Most activity only updates internal USD-denominated margin balances; no on-chain FX conversion occurs. StableFX is invoked only for three specific settlement types.

Internal Accounting Settlement (no StableFX)

The common case. A user trades GOOGL/KRW, which routes to the canonical GOOGL/USD book and updates the account's USD PnL. The display layer converts to KRW. No StableFX transaction occurs. This is fast and imposes no FX settlement cost or latency on normal trading activity.

User Currency Conversion

When a user explicitly converts collateral (e.g., KRW1 to USDC, EURC to USDC, or withdrawing USDC as JPY1), Origin requests a live executable RFQ from StableFX at the actual notional size of the conversion. The rate used is not the oracle mark but the live executable quote:

  1. Request RFQ from StableFX: from_currency, to_currency, notional.
  2. Validate quote is within acceptable spread vs. oracle mark.
  3. Present rate to user with expiry timestamp.
  4. On user acceptance, execute settlement on-chain via StableFX.
  5. Credit converted balance to account.

Liquidation Collateral Conversion

When a user with non-USD collateral is liquidated, the seized collateral must be converted to USDC to replenish the insurance fund. The flow:

  1. Risk Engine detects account equity below maintenance margin.
  2. Liquidation Engine closes or reduces the canonical USD position.
  3. Protocol computes remaining deficit or surplus in USD.
  4. If collateral must be seized, the relevant non-USD balance (e.g., KRW1) is seized from the Margin Vault.
  5. A StableFX RFQ is requested at the seizure notional, using a short TTL (1 second for fast markets).
  6. The conservative FX rate applies: ask price is used when converting local currency to USDC (Section 4.3.5).
  7. Conversion executes on-chain via StableFX.
  8. USDC proceeds cover the shortfall; any surplus returns to the user.

Large liquidations are broken into chunks to avoid moving the FX market and to allow multiple RFQ providers to compete.

Settlement Executor State Machine

Every StableFX conversion is tracked through a settlement state machine:

REQUESTED → QUOTED → ACCEPTED → PENDING_SETTLEMENT → SETTLED
                                                    ↘ FAILED
                                      ↓
                                  EXPIRED / CANCELED

A quote is not used as final settlement proof until the SETTLED state is confirmed on-chain. If settlement fails, the protocol falls back to the next available RFQ provider. Provider-level failure rates are tracked and providers with deteriorating settlement reliability are down-weighted in the oracle blend (Section 8.3.4).

Treasury Rebalancer

The insurance fund and protocol fee balances are maintained in a target currency composition (primarily USDC, with small allocations in supported local stablecoins for anticipated withdrawal demand). A Treasury Rebalancer monitors actual vs. target composition and routes excess local-currency balances back to USDC through StableFX using staged RFQs:

  • Rebalancing is gradual: large balances are converted over multiple transactions to avoid FX market impact.
  • Rebalancing activity is published on-chain and included in the insurance fund transparency dashboard (Section 7.5.4).
  • Haircuts are tightened automatically if rebalancing liquidity deteriorates for a given currency.