Program reference
Instructions
| Instruction | Who | What it does |
|---|
init_market(fee_bps, borrow_bps_per_hour, keeper_bps, lp_cooldown_secs, max_price_age, open_fee, max_open_coll_bps, max_leverage, fill_delay_secs, fill_window_secs) | authority | Creates the market and its USDC vault; refuses an oracle that does not read as a SOL price |
set_params(..., max_leverage, fill_delay_secs, fill_window_secs, opens_paused) | authority | Changes the same settings; opens_paused stops new positions while closes, checks, liquidations and LP moves go on |
init_book | authority | Ties a client-created book account (10,896 bytes) to the market |
close_book | authority | Closes a book that holds no position, no pending open and no check round; rent back |
lp_deposit(amount) / lp_withdraw(shares) | LP | Shares against the pool balance; withdrawals wait out the cooldown and must leave the pool large enough for the open collateral under the cap |
request_open(slot, version, cts, pubkey, nonce, coll) | trader | Takes collateral plus the fixed fee, checks the pause and the exposure cap, holds the slot; cts is two ciphertexts, size and w (collateral per unit of size) with the side in bit 40 |
settle_open(offset) | anyone (keeper) | Fills a request at the oracle price from its window and queues open_pos |
reclaim | trader | Returns the collateral of a rejected open, or of an open with no answer after 300 s |
close_record | trader | Closes a closed or liquidated position's account; rent back to the trader |
chk128(offset) | anyone | Queues a check round over all 128 slots at the oracle price |
liquidate | anyone | Settles a marked slot: collateral to the pool, 1% to the caller |
request_close | owner | Asks to close; the exit is the first oracle price in the request's window |
settle_close(offset) | anyone (keeper) | Fills the close at that price and queues close_pnl; the answer pays the owner. A late answer is queued again at the same exit |
Accounts
| Account | Seeds | Holds |
|---|
| Market | ["market"] | authority, USDC mint, vault, oracle, pool balance, LP shares, fees, oldest price allowed, fixed fee per position, exposure cap, open collateral, pause |
| Vault | ["vault"] | USDC, owned by the market |
| LP account | ["lp", owner] | shares, last deposit time |
| Position | ["pos", book, slot, version] | owner, slot, entry, collateral, state, sealed close record, payout |
| Book | client keypair | occupancy bits, 128 nonces, 128 ciphertext pairs, slot versions, check state, opens waiting for an answer |
Position states: requested, pending (filled, waiting for the cluster), open, rejected, close requested, closing, closed, liquidated.
Oracle
Pyth's SOL/USD price account 7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE, read by the program itself: owner must be
Pyth's receiver program, the feed must be SOL/USD, the update fully verified, and the price no older than the
market allows. A keeper or trader cannot choose the price of a check, an open or a close.
Constants
| Name | Value |
|---|
SLOTS | 128 per book and per check round |
MAX_LEVERAGE | 10 (the highest cap a market may set) |
max_leverage | a market setting, checked inside MPC at open; the first market starts at 5 |
fill_delay_secs, fill_window_secs | market settings: a request fills at an oracle price published at least the delay after it and within the window after that (2 s and 20 s on mainnet) |
max_price_age | a market setting, 1 to 600 s; 30 s on mainnet, where Pyth's SOL account updates every 10 s |
MAX_CONF_BPS | 100 (a price whose confidence band is wider than 1% is refused) |
RETRY_AFTER_SECS | 120 (a check or close with no answer can be queued again) |
MIN_COLLATERAL | 10 USDC |
OPEN_TIMEOUT_SECS | 300 (an open with no answer by then can be reclaimed) |
open_fee | a market setting, up to 100 USDC; 1 USDC proposed, since a position costs two Arcium computations (about $0.32 each) plus its share of check rounds; refunded with a rejected or timed-out open |
max_open_coll_bps | a market setting; 1,000 proposed: collateral of unsettled positions up to 10% of the pool, so at 10x the total size stays within the pool |
PAYOUT_SCALE | 1e13 |
Errors
| Code | Name | Meaning |
|---|
| 6000 | AbortedComputation | The cluster returned a failed computation |
| 6001 | BadSlot | Slot index out of range |
| 6002 | SlotTaken | Slot holds a position, or its version moved on |
| 6003 | NotPending | Position is not waiting for its open answer |
| 6004 | ZeroAmount | Amount must be positive; collateral at least 10 USDC |
| 6005 | Cooldown | LP cooldown has not passed |
| 6006 | WrongMarket | Book belongs to another market |
| 6007 | WrongOracle | Oracle account is not the market's, or does not read as a fully verified SOL/USD price |
| 6008 | StalePrice | Oracle price is older than the market allows (30 s on mainnet) |
| 6009 | EntryOutOfBand | Unused since opens fill at the oracle price (kept so later codes keep their numbers) |
| 6010 | CheckInFlight | A check round on this book is still waiting for its answer |
| 6011 | NotOpen | Position is not open |
| 6012 | NotRejected | Position was not rejected, and its open has not timed out |
| 6013 | NotFlagged | Slot was not marked by a check |
| 6014 | NotOwner | Only the position owner can close it |
| 6015 | WideConfidence | The oracle's confidence band is wider than 1% of the price |
| 6016 | BadConfig | A market setting is out of range |
| 6017 | NotFinished | Position is not closed or liquidated |
| 6018 | BookNotEmpty | Book still holds a position, a pending open or a check round |
| 6019 | OpensPaused | New positions are paused by the market authority |
| 6020 | ExposureCap | Open collateral would pass the market's share of the pool |
| 6021 | PoolEmpty | The pool is empty while shares remain; deposits are closed |
| 6022 | NotYet | No oracle price inside the request's fill window yet |
| 6023 | FillExpired | The request's fill window has passed |
| 6024 | NotRequested | Position is not waiting for its fill |