Skip to main content

Sub-accounts

info

Preview. The user-visible API is stable. The address-derivation scheme is finalized before mainnet.

A sub-account is an address derived from a master account. It holds its own balance and its own risk.

Summary​

A sub-account moves funds in and out only through its master. A master can have up to 32 sub-accounts.

warning

A sub-account cannot sign today, so it cannot trade today.

A sub address is a hash of the master address and the index. No private key exists for it. An action reaches an account in one of two ways: the account's own key signs it, or an approved agent of the account signs it. A sub-account can use neither:

  • It has no key, so it cannot sign for itself.
  • Its approved-agent set is always empty. create_sub_account never fills it. approve_agent adds an agent to the signer's account. Only the sub-account could approve an agent of the sub-account, and the sub-account cannot sign.

So a sub-account is a fund-segregation bucket that the master funds and defunds. It cannot place orders, hold positions it opened itself, or enrol in portfolio margin. Use one master account per trading strategy until sub-account signing ships.

Model​

Each sub-account is a first-class account in the state machine. It has its own balance and its own liquidation threshold. A side map records which master owns which sub-account. "First-class" describes the ledger, not the signing surface: no sub-account can sign, so none can act. See the summary warning.

The hard cap is 32 sub-accounts per master. At the cap, create_sub_account returns PRECONDITION_FAILED.

Transfers​

Transfers run only between a master and its sub-accounts:

An external withdrawal to a third address must come from the master. A sub-account cannot withdraw off-chain directly.

Address derivation​

Each sub-account index n maps to an address derived from the 20-byte master address:

sub_addr_n = first_20_bytes( keccak256( master_addr || uint64_be(n) ) )

Anyone can compute a sub-account address without on-chain state. The derivation is fixed by consensus at V1 launch. Until then, treat the returned address as authoritative.

Fund-segregation guarantees​

GuaranteeMechanism
A sub-account loss cannot drain the masterThe sub-account liquidates against its own balance. The master sees only the transfer ledger.
A sub-account loss cannot drain other sub-accountsEach sub-account is a first-class isolation boundary.
The master can choose to backstop a losing sub-accountA voluntary sub_account_transfer deposit.
The master cannot be forced to backstopA sub-account blowup stays in the sub-account.
The master can withdraw out of a sub-accountA sub_account_transfer, only if the sub-account stays in the Safe tier after the transfer.

Creating​

{
"type": "create_sub_account",
"params": { "name": "scalping-desk", "explicit_index": null, "shared_stp_group": false }
}
FieldTypeDescription
namestring ≤ 64 charsBookkeeping label
explicit_indexuint32 | nullThe slot to claim. null takes the next free slot.
shared_stp_groupboolRequired. There is no default: a body without this field fails admission with a missing-field error. true puts the sub-account in the master's self-trade-prevention group, so the book refuses a match between master and sub-account. false leaves it out of the group, so the two can match each other.

Response:

{
"accepted": true,
"data": {
"sub_index": 0,
"sub_address": "0x<derived>",
"name": "scalping-desk"
}
}

Indices only increase. An allocated index is never reused, even after the sub-account is emptied and abandoned. Use explicit_index with care.

Funding​

{
"type": "sub_account_transfer",
"params": { "sub_index": 0, "deposit": true, "amount": "1000000000" }
}

amount is in USDC base units (6 decimals). deposit: true moves funds from the master to the sub-account. deposit: false moves them back.

For spot assets, use sub_account_spot_transfer. It adds an asset field.

A transfer must leave the sub-account in the Safe tier. A withdrawal that would push it into T0 or worse is rejected with MARGIN_INSUFFICIENT. Add margin first, then withdraw the excess.

Trading from a sub​

A sub-account cannot trade today. It holds no key, so it cannot sign an order. See the summary warning.

An agent does not open a path either, and the attempt fails silently. approve_agent writes the agent under the recovered signer's account. Its body carries agent, name and expires_at_ms. It has no owner field and no delegation field. So a master that signs approve_agent for a sub-account approves an agent on the master. The action is accepted, the agent set of the sub-account stays empty, and no error appears.

The remap that lets a master act on a sub-account covers three actions only: create_sub_account, sub_account_transfer and sub_account_spot_transfer. Every other action lands on the signer's own account. A master can move funds in and out of a sub-account, and nothing else.

There is no workaround. Use one master account per trading strategy until sub-account signing ships.

Liquidation isolation​

The tiered liquidation of a sub-account uses its own account value and maintenance margin. A blowup in sub_0 does not put sub_1 or the master at risk.

You can also set the margin mode of a sub-account to StrictIso per asset. The positions in that asset then do not count toward cross-asset portfolio margin, even if the master is enrolled.

Per-sub PM enrollment​

warning

Not available. user_portfolio_margin enrols the signing account. Its body carries only enroll. It has no target field, and a sub-account cannot sign. So a sub-account cannot enrol in portfolio margin, and a master cannot enrol one on its behalf.

The master enrols itself:

{ "type": "user_portfolio_margin", "params": { "enroll": true } }

To run one strategy on portfolio margin and another on classical margin today, use two master accounts.

Querying​

curl -X POST https://api.testnet.mtf.exchange/info \
-d '{"type":"account_state","address":"0x<master>","detail":"overview"}'

The response lists the sub-accounts. Each row has exactly three keys: index, address and equity. equity is one aggregate number. The row has no label field and no clearinghouse state. To read the positions of a sub-account, query clearinghouse_state with its address.

You can read each sub-account as a first-class account. Pass its address as address to account_state, open_orders, user_fills and the other reads. Reads work. Writes do not (see the summary warning).

Limits​

LimitDefaultNotes
Sub-accounts per master32V2 may raise the limit
Sub-account name length64 charsUTF-8. Length is the only check.
Concurrent transfers in flight8 per masterMempool cap
Master can withdraw from a sub-accountYes, if it stays SafeOtherwise rejected
Sub-account can withdraw off-chainNoThe withdrawal must go through the master
Sub-account can have agentsNoapprove_agent writes under the signer, and a sub-account cannot sign
Sub-account can be multi-sigNoIn V1, only the master can be multi-sig

Use patterns​

Strategy separation​

Each strategy has its own agent key, its own liquidation envelope and its own PnL reporting.

Risk firewalling​

The main book keeps the full upside. A sub_0 blowup costs at most its deposit.

A/B portfolios​

A quarterly comparison of NAV per sub-account decides which one gets more allocation.

Edge cases​

Show edge cases
  • create_sub_account takes effect at the next block, like all state changes. A sub-account cannot approve an agent or trade, so no agent-traffic race exists.
  • The master transfers from a sub-account during its T1 liquidation. The transfer is rejected, because the collateral of the sub-account is in use. The transfer is allowed once the sub-account is Safe again.
  • The master deletes or abandons a sub-account. V1 does not support this. A sub-account stays in the index forever. An empty sub-account has no state cost.
  • The agent key of a sub-account is compromised. The master revokes it. The master holds the delegation authority. Use the same approve_agent with expires_at_ms in the past.
  • A sub-account of a sub-account is not supported, and it is not reachable: a sub-account cannot sign create_sub_account.

Full setup sequence​

See also​

FAQ​

Show FAQ

Q: Are sub-account fees aggregated with master for tier purposes? A: Yes. The 30-day volume tier adds up the volume of the master and all its sub-accounts. Trading in a sub-account counts toward the tier discount of the master.

Q: Can a sub receive funds from another account directly (not via master)? A: Yes. The general account-to-account transfer action (send_asset) can target a sub-account address like any other account. After that, the funds sit in the balance of the sub-account. They do not have to flow through the master.

Q: Do subs share a nonce space with master? A: No. Each sub-account has its own nonce sequence, separate from the nonces of the master and of sub_0.

Q: Can I convert a sub-account into a master / detach it? A: Not in V1. A sub-account stays a sub-account. To detach one, create a new account at a different address and transfer the funds.