Skip to main content

Account modes

An account carries ONE of three modes: unified, standard or portfolio. /info account_state reports it as abstraction.

Two different things are called a "mode"

This page is about the account mode. cross / isolated / strict_iso is a position setting and lives in margin modes. They are independent axes: a standard account can hold isolated positions, and a portfolio account can hold cross ones.

What each mode changes

The three modes do not sit on one dial. They move three separate properties, and each mode moves a different subset:

What counts as collateralHow margin is computedWhere the USDC is held
unifiedUSDC onlySum of each position's requirementOne balance
standardUSDC onlySum of each position's requirementTwo wallets: perp and spot
portfolioUSDC plus eligible spot tokens, at a governance haircutScenario (SPAN) sweep over the whole accountOne balance

unified is the origin: one balance, USDC only, per-position sum. standard changes ONLY the third column. portfolio changes ONLY the first two.

Only standard changes the ledger. unified and portfolio fund every product from ONE USDC balance. A standard account holds a perp wallet and a spot wallet, and USDC crosses between them only by an explicit transfer — see standard is two wallets.

unified

The default. Every account starts here, and an account that has never sent user_set_abstraction is in it.

One USDC balance backs every product. A perp loss, a spot-margin loss and an option premium all draw on it, and any of them can consume what another was counting on. withdrawable is what is left after every open requirement.

standard

Two USDC wallets, and an explicit transfer between them. An account that enters standard at or above block 5,710,001 (node 0.9.7) gets the two wallets. An account that was already in standard below that height keeps one balance — see before the split.

account_state reports the posture as split: true for two wallets, false for one balance.

standard is two wallets

WalletWhat it fundsWhere to read it
Perp walletPerp orders and positions, option orders and escrow, withdrawals. Liquidation judges this wallet aloneaccount_value and withdrawable on account_state
Spot walletSpot orders and fillsThe USDC row (signing_id 100) of spot.balances

The full list of which action reads which wallet is in the standard-mode split.

The spot wallet starts empty. usd_class_transfer is the only way USDC crosses:

  • Perp → spot moves free collateral only. USDC that margins an open position stays in the perp wallet.
  • Spot → perp moves USDC that no resting spot order holds.

A perp loss cannot reach the spot wallet. A split account's perp bankruptcy is absorbed by the insurance fund and ADL, never by its spot USDC. For full isolation, with its own address and its own liquidation, use a sub-account.

Each wallet funds its own orders, with no cap. A perp or option order is admitted against the perp wallet's free collateral. A spot order is admitted against the spot wallet. A spot order the spot wallet cannot fund is refused with insufficient spot balance. A split account has no reservations and no spot margin.

Not live yet

Uncapped admission, the refusal of an unfunded spot order and the refusal of every reservation ship with the next node release after 0.9.7. Until then, a live node:

  • caps the perp and option orders of a split account by its perp and option reservations, so a split account with no perp reservation opens no perp position;
  • accepts a spot order the spot wallet cannot fund as a no-op, and answers filled with total_sz: "0".

To trade perps on a live node, first set a perp reservation with user_set_abstraction kind: 1.

Reading the two wallets. account_value and withdrawable are the perp wallet. The USDC row of spot.balances is the spot wallet. Its total includes the USDC that resting spot bids hold, so total − hold is what a new spot order may spend. The account total is account_value plus that row's total.

Before the split

An account that entered standard below block 5,710,001 reads split: false. It keeps ONE USDC balance and a spending cap per product. The caps are called reservations, and there are three:

ScopeCovers
perpPerpetual positions, cross AND isolated
spotSpot and spot margin — one cap for both
optionOption escrow

Set each one with user_set_abstraction kinds 1–3. Read them back on account_state.reservations.

The caps are fail-closed. An unset reservation is zero, and zero admits nothing.

A reservation binds admission only. No liquidation, ADL, settlement, funding or seizure path reads it, and neither does any cash path — withdraw, transfer, vault or Earn. So a reservation:

  • cannot hold back your own money (withdrawable is unaffected);
  • cannot make the account harder to liquidate;
  • cannot stop a loss in one product from consuming another product's USDC.

A reservation is a cap on what you may OPEN, not a wall around money you hold. To get two wallets, switch to unified and back to standard. Both changes need a flat account.

portfolio

Portfolio margin, for accounts that qualify. Enrol with user_portfolio_margin. Two things change:

Eligible spot tokens become collateral. A token whose governance pm_collateral_haircut is positive is credited at balance × mark × haircut, and the FULL un-haircut exposure is folded into the scenario sweep as a long spot leg — so a crash in the collateral raises the requirement. USDC is weight 1 and is never haircut. In the other two modes, a non-USDC spot balance is worth nothing as collateral.

Margin becomes a scenario sweep. Instead of summing each position's requirement, the engine stresses the whole account and takes the worst outcome, with a concentration penalty. Offsetting positions can require LESS than their sum; a concentrated book can require more.

Two governance limits gate entry, read at enrol time only:

LimitDefaultKnob
Minimum net value100,000 USDCSetPmMinEnrollValueCents
Enrolled accounts512SetPmMaxEnrolledUsers

Leaving is always allowed, even while the account is underwater under PM margining — PM can require MORE than the per-asset sum, so blocking the exit would trap an account inside the worse model.

standard and portfolio are mutually exclusive

Enforced in both directions, so the pair is unreachable:

  • user_set_abstraction refuses while the account is PM-enrolled — "cannot change abstraction while enrolled in portfolio margin".
  • user_portfolio_margin refuses while the account is in standard mode — "cannot enroll portfolio margin in standard abstraction mode".

unified is the way between them: leave one, then enter the other.

This is also why abstraction can be a single three-valued field. In state these are two separate things — a mode value and an enrolment row — and the field reports portfolio whenever the enrolment exists.

Changing mode

user_set_abstraction kind 0 with value 1 (standard) or 0 (unified).

The account must be FLAT on every surface. The node refuses the change while any of these exists: a perp position, a resting perp order, a parked trigger, a live TWAP, a resting spot order, a spot TWAP, a spot-margin position, an option position, or an open RFQ quote. The rejection names what it found.

Entering standard splits the USDC: all of it stays in the perp wallet, and the spot wallet starts empty. Entry is refused while the perp wallet is below zero.

Returning to unified folds the spot wallet back into the one balance and clears every reservation. It is refused while the spot wallet is below zero.

Which mode do you want

You wantUse
The simplest thing; everything shares one balanceunified
Spot USDC that a perp loss cannot reach, moved between wallets by handstandard
Full isolation, with its own address and its own liquidationA sub-account, in any mode
Spot holdings to back perp positions, and offsetting risk to net offportfolio