Skip to content

On-chain futures program reference

The futures program (ameba-futures) holds each market in one account: every trader’s cash, every resting order, every maker ladder, every position and the market’s backing. This page is for integrators. It describes structure and limits, not byte layouts. Build transactions with the API or the Rust client, and see the Math appendix for the formulas.

Property Value
Accounts One market account per index and expiry, created against one oracle Period. A registry PDA ["ameba-range-v1", "registry", product_id, expiry_ts] makes it unique.
Creation CreateMarket, signed by three council seats of the governance controller.
Header AFRANGE1, layout version 1. A layout change means new markets, not a migration.
Grid Positions 0..=grid. On Amoeba’s markets the grid is 200 and one step is one index point.
k Atoms one lot of a one-step claim pays in full. 10,000 on Amoeba’s markets: $0.01 per lot per point.
Vault A USDC token account owned by the PDA ["ameba-range-v1", "authority", market].
Reference value The index value the market is listed at. Never a settlement value.

The PDA seed ameba-range-v1, the header AFRANGE1 and the AR* event tags keep the program’s earlier name: they are its on-chain identity and do not change.

A claim is a position: a side, an interval [lo, hi) of grid positions and a number of lots. At settlement S, a long pays clamp(S − lo, 0, hi − lo) steps of k atoms per lot, and a short pays the rest of the set, (hi − lo) × k atoms per lot.

  • Opening. A long pays its price per lot, p; a short funds the rest of the set, (hi − lo) × k − p. The price places the entry on the price line: entry = lo + p ÷ k.
  • Redeem. A long and a short of the same owner on the same interval redeem for their backing into free cash, at fill time or with Redeem. Intervals that differ in either end release nothing.
  • Split and Merge. Split cuts a claim at a position into two adjacent claims with the same lots; Merge joins identical intervals, or adjacent ones with equal lots.
  • Transfer. Gives lots of a claim to another owner unchanged. The owner must be a wallet key (on the ed25519 curve), never a program address such as the Earn vault.
  • Submit trades one claim shape against the book with a proposed package, then, in GTC or post-only mode, rests the remainder. Its limit is the most a long pays per lot, or the least a short accepts. Naming one of the owner’s claims makes it a close order: the opposite side on the same interval, which reserves the claim instead of cash.
  • Resting orders escrow exactly what they would put in at their own limit: limit × lots for a long, (set − limit) × lots for a short. Cancel releases it.
  • Quote publishes the owner’s maker ladder over [lo, hi): a bid and an ask on every one-step claim [x, x + 1), in depth tiers, fully escrowed: the bid per bid lot and k − ask per ask lot. Steps inside its core quote every tier; the other steps quote only the last tier’s lots. Quote is post-only against the whole book. CancelQuote withdraws it; inventory stays.
  • A ladder’s inventory is per step, so its one-step claims net step by step.

A package is the set of fills of one Submit. At every grid step, the filled long lots covering it equal the filled short lots covering it. The proposal travels in the instruction. The program rebuilds the complete arc list from its own account, every live order and ladder step, and checks:

  • shape and balance: fills within each order’s lots and coverage equal at every step;
  • price: complementary slackness against the node potentials in the proposal, so no cheaper package exists;
  • quantity: if the taker is short of its quantity, no zero-cost path closes another lot;
  • FIFO: no equal-price exchange fills an older order more.

The resting book never crosses: Submit matches before it rests, post-only fails if anything would fill, and Quote is post-only. A proposal is checked against the book as it is when the transaction executes. A stale one fails with an error such as NotBestPrice or FifoViolation and changes nothing.

After every instruction the program checks:

  • custody (deposits − withdrawals) = free + reserved + backing;
  • reserved = exactly the escrow of resting orders and ladders;
  • while open, backing = k × long coverage = k × short coverage: one complete set behind every promised payoff;
  • once final, backing = what the remaining claims pay.

There are no fees and no funding. Withdraw pays only free cash.

One Earn vault serves the whole product: the PDA ["ameba-range-v1", "earn", operator]. Its idle cash is a USDC token account it owns; in each market it funds, its cash and inventory are an ordinary trader slot whose owner is the vault’s address. CreateVault is permissionless; Earn’s vault is the one the deployment’s treasury operates. Each depositor has a position PDA ["ameba-range-v1", "earn-lp", vault, owner].

  • VaultDeposit mints shares at the vault’s highest value over every settlement outcome: its idle cash plus its value in each of its markets, which the instruction names in the vault’s order. The first deposit into an empty vault gets one share per atom.
  • VaultWithdraw pays at the vault’s lowest value, from its idle cash and then its cash in the markets the transaction names to draw from. Where a market’s free cash is short, it retires the vault’s ladder there to release its escrow; the maker quotes again on its next pass. The vault’s last shares wait while its highest value is above what they would get (NotSettled).
  • The operator signs VaultFund and VaultDefund, which move cash between the idle cash and a market. A market where the vault then holds nothing leaves its list. The vault can be in at most 13 markets at once: deposits and withdrawals name every one of them in one transaction (VaultCapacity).
  • Submit, Cancel, Quote, CancelQuote, Split, Merge and Redeem act for the vault in one of its markets when its operator signs. Withdraw and Transfer never do: vault cash leaves only through VaultWithdraw. Nobody can give the vault a claim either: it would raise the vault’s highest value, which deposits pay, for free.

Per-market Earn pools came before the vault, on Amoeba’s development chain only. The mainnet program refuses every pool instruction (CreatePool, PoolDeposit, PoolWithdraw, PoolMigrate).

Instruction Who What it does
Finalize Anyone Reads the market’s oracle Period. A Settled period at or after expiry fixes S = floor(value × k ÷ step_value) in units of 1/k step. A Failed period, or one still Live after expiry, waits for CouncilSettle.
CouncilSettle The governance council (three seats) After a Failed period, or any time after expiry with no settlement: fixes S from the value it names.
Settle Anyone, once final Pays claims into their owners’ free cash.
SettleMaker Anyone, once final Pays a maker ladder’s inventory and releases its escrow.
Prune Anyone, once final Releases resting orders’ escrow.

Settlement is measured in 1/k of a step, so every payout per lot is a whole number of atoms, and a long plus its short pays exactly the set.

Limit Value
Grid 0 to 200 points
Maker ladders 4 per market, each at most 256 steps wide; 1,024 ladder arcs per book
Resting orders 64 per market
Traders 128 per market; idle slots are reused
Claims 1,024 per market
FIFO search 30,000 edges per package
Earn vault 13 markets at once

Exceeding a limit fails with an explicit error (OrderCapacity, ClaimCapacity, MakerCapacity, TraderCapacity, VaultCapacity, SearchLimit, or InvalidPrice for a ladder that is too wide) and changes nothing. Submit and Quote need a 256 KiB heap frame (RequestHeapFrame). Clients set a 1.4 million compute-unit limit on every transaction.

  • Program errors are custom codes 0x46520000 + n, named in API responses: for example InsufficientFunds, NotTradable, MinFill, WouldCross, ClaimReserved, NotComplement, NotBestPrice, FifoViolation.
  • Every state change logs an event: ARDEPO01, ARWDRW01, ARTAKE01, ARFILL01, ARLADR01, ARPLACE1, ARCANCL1, ARQUOTE1, ARREDM01, ARXFER01, ARFINL01, ARSETL01, ARMKSE01, ARMRKT01, and ARVCRT01, ARVDEP01, ARVWDR01, ARVFND01 and ARVDFD01 for the Earn vault. The API decodes them; see Events and indexing.
  • Every instruction carries the canonical read-only governance gate account and a signed gate epoch. A frozen gate or a stale epoch fails closed. Clients bind the current epoch before signing.