FLOORLaunch app

Architecture

Four programs share the work. The venue program owns money and executes trades; the other three hold facts the venue reads before it lets a trade through. Two of those facts come from off chain through keeper sets.

The programs

floor_venue  (3vkpdUbz...)         floor_halt   (hZWUysrR...)
  Venue        seeds ["venue"]       HaltConfig   seeds ["config"]
  Participant  seeds ["participant", wallet]      HaltState  seeds ["halt", symbol]
  QuoteAsset   seeds ["quote", mint]
  Pool         seeds ["pool", stock_mint, quote_mint]
                                   floor_caps   (riN4V5uU...)
floor_notice (4MLRiWbL...)           CapsConfig   seeds ["config"]
  NoticeConfig seeds ["config"]      SymbolCap    seeds ["cap", symbol]
  IssuerNotice seeds ["notice", mint]

swap in floor_venue takes the pool, the symbol's HaltState, the mint's IssuerNotice, the symbol's SymbolCap and the caps CapsConfig as accounts, checks them in that order, then calls floor_caps::record_execution by CPI signed with the venue PDA. The caps config stores that PDA as its recorder; no other signer can count shares.

One of each

Every object that must be unique is a PDA whose seeds are the thing it is unique for:

  • one Pool per (stock mint, quote mint): seeds ["pool", stock_mint, quote_mint];
  • one SymbolCap per symbol: ["cap", symbol], where the symbol is a 12-byte padded ticker;
  • one HaltState per symbol: ["halt", symbol];
  • one IssuerNotice per mint: ["notice", mint];
  • one Participant per wallet and one QuoteAsset per mint.

A second pool for the same pair, or a second notice for the same mint, cannot be created because the address is already in use.

Keeper feeds

Two facts cannot be computed on chain: whether the primary exchange has halted a stock, and the stock's prior-month consolidated average daily volume. Both arrive through keeper sets with the same shape:

  • a config holds up to 16 keeper keys and a threshold (1 to the keeper count), plus a keeper_epoch that increments on every change to the set; votes cast under an older epoch are void;
  • a keeper proposes a value for the next sequence (halt) or for a month (ADV); the first vote opens the proposal, later votes must match it or fail with ProposalMismatch; a keeper cannot vote twice (AlreadyVoted);
  • when the votes reach the threshold the value is applied and an event is emitted (HaltChanged, AdvPosted).

Halt events carry a sequence number and must arrive in order (seq == applied seq + 1, else StaleSequence), and a vote that would not change the state is refused (NoChange). ADV can only be posted for a month that has ended (MonthNotOver) and never for a month older than the one on record (OlderMonth). A revision of the prior month's ADV that leaves this month's executed shares above the new cap triggers breach at once.

Sources the keepers read: Nasdaq Trader's trade halts feed and CTA notices for halts; the NYSE Consolidated Volume Summary for ADV. The venue board on the landing page reads Nasdaq's public endpoints for the same facts so a visitor can compare.

Trust model

AuthorityHeld byCan doCannot do
Venue authoritymultisigset fees up to 10 percent, set the fee recipient, pause the venue or a pool, admit and revoke participants, register quote assets, create poolstake user funds, mint stock, change a pool's mints, skip a halt or cap check
Halt authoritymultisigset the keeper set and thresholdpost a halt directly
Caps authoritymultisigset keepers, list symbols, set reserved symbol counts for affiliates, pause a symbol voluntarily, declare a breachchange the cap percentages or the throttle (constants in code), record executions
Notice authoritymultisigfile a notice, record an objection inside the windowlift an objection, shorten the 30 days
Keepersoperator-run and third-party signersvote on halt state and monthly ADVapply anything alone when the threshold is above one
Upgrade authoritythe deployer until a multisig takes itupgrade the programsnothing else; it is disclosed on the disclosures page

The app and the site

The Next.js site serves the landing page, the docs and /app. /app reads the four programs through /api/rpc, a relay that forwards a fixed list of read and send methods to a keyed RPC provider. Before launch the app runs in preview: live mainnet accounts, every input and quote working, transaction buttons replaced by "Opens at launch". The landing's board reads /api/board, which gathers Nasdaq last sale, market status, daily volumes and the halt feed, plus Jupiter prices for the Superstate mints.