Warbandry Contracts

Warbandry · for engineers

What locks,
what swaps

Warbandry is written so that balance can keep moving after launch and ownership cannot. Seven pieces, specified down to their events, the competitive mode with them. All of it is free to change until the coin deploys, and a named part of it freezes forever the moment the first roll is sold. That asymmetry is the thing to understand before touching anything.

The line

A module may read. It may never own.

The contracts are written against interfaces rather than implementations, so the game layer can be re-tuned for years without migrating a token. The split is not a matter of taste — it follows one rule, and every borderline case is decided by it.

A swappable module may read state and gate whether a match can happen. It may never touch coins, seeds, composition or ownership.

Frozen at the first roll

Never behind a pointer. A holder's floor is computed from these alone, so no owner action can strand collateral.

  • The observer — bound to the pool for its life. No owner, no lever, and no knowledge of the vault.
  • Every seed already written — written once when a creature is recruited, never rewritten and never rerolled.
  • Every decoder epoch already written — a roll decodes the same way on any day, forever.
  • The vault's core — ownership, the seats, the seeds, the coins each seat froze.
  • The floor — the sum of what each seat froze, less the melt fee. Storage and two numbers, nothing else.
  • The caps — melt 10%, carding 10%, freeze 0.001 ETH, naming 0.01 ETH, royalty 5%, the lock between 10 and 1,000 tokens.
  • Melt — it cannot be paused, delayed or refused for any reason but a lock or ownership.

Free to move afterwards

Owner-settable pointers, an append-only list, and parameters bounded in code. All of them views or allowlists; none of them holds a coin.

  • The renderer — the tokenURI view and its data files. Cosmetics evolve without touching a token.
  • The calculator — stateless: composition in, numbers out. Every balance number lands here, and its address is its version.
  • The match contract — registered in the vault's registry, and removable in one transaction.
  • New decoder epochs — appended, never edited, and they reach future rolls only.
  • The registry — at most eight games. A game may lock a composition and nothing else.
  • The owner parameters — the fees, the seat cap, the lock per creature, the pause. Each one under a cap in code.

The seven pieces

PieceMutabilityIt may never
ObserverImmutable Revert inside a swap. The hook swallows the revert, and the roll would be lost in silence.
DecoderAppend-only Decode a roll it has already decoded, differently.
VaultImmutable core + parameters Stop a melt, or read a pointer to compute a floor.
Renderer + its data filesReplaceable behind a pointer Revert on a token the vault accepted. A revert there hides the token from every marketplace.
Calculator + its tablesReplaceable behind a pointer Hold state — or stop answering once retired, since a match in flight still calls it.
Match contractReplaceable, removable Block a withdrawal of the free balance, or forfeit a stake.
Registry, inside the vaultOwner list Hold more than eight games, or leave a removed game's locks standing.

Guardrails

What the swap mechanism must respect

  1. The floor never depends on a swappable module. It is the sum of what each seat actually froze, times one minus the melt fee — the vault's own storage and two numbers, never a pointer. A seat keeps the amount it froze, so moving the lock for new creatures cannot move an existing floor. A bad calculator can mis-rank warbands; it can never strand collateral.
  2. Games lock composition, never funds. Pots are staked in the game contract, not the vault. Removing a game from the registry voids its locks the same second, so no third-party contract can freeze a warband forever.
  3. A match in flight uses the calculator recorded at its tick. The tick stores the pointer's value when the reveal closes and calls that address at settle, whatever the pointer says by then. A re-tune therefore reaches new ticks only, and can never move the odds of a pot already engaged. A retired calculator is never destroyed.
  4. Epochs only add. A new epoch may introduce creatures and traits and move the weights inside a cell, but every entry of the previous epoch must survive with a nonzero weight, and no trait ever changes its stat or its sign. The tier shares, the faction list and the trait split are epoch data too: a later epoch may move them, for rolls that come after it. What never changes is anything already rolled — a roll is decoded by the epoch in force at the height its record was written.

What must hold

The invariants an implementation must not break

Each of these holds from the first roll onward, and none of them can be revisited afterwards.

InvariantWhat it means in practice
The roll counter is gross and monotonic It counts coin ever bought, per wallet, and the wallet is the transaction's origin — hookData is never read. Sells, transfers and balance moves never decrement it. Buy 10,000 then sell everything and you still hold ten rolls; buy 1,000 more and the counter reaches 11,000, so an eleventh is written.
A seed is written once The commitment is keccak256(poolId ‖ wallet ‖ index ‖ subIndex) at fixed widths of 32, 20, 8 and 1 bytes, and the seed is keccak256(commitment ‖ drawBlockHash). The draw block sits outside the commitment, because a re-anchor rewrites it. Nothing ever rerolls an existing creature; the only path to a different one is a new roll.
The draw block is read the same way everywhere The chain's block-history contract at the L2 anchor first; native blockhash at the L1 anchor as the fallback. Reading early or late gives the same hash, so choosing when to settle cannot change the outcome.
The observer knows nothing of the vault It counts and it writes. The vault keeps its own bitmap, one bit per roll index per wallet, of what has been recruited. No contract answers "what can this wallet still recruit" — the browser joins the two reads itself.
Composition is the identity The vault's composition view is the source of truth: creature, trait, row, seed and frozen coins per seat, readable without the renderer. Recruiting appends; dismissing shifts the later seats left; the composition hash is one keccak over the ordered seats and the reserve word, so any change of member, order, formation, reserve or mode changes it.
Building is free; leaving and carding cost coins Dismissing to coins burns the melt fee out of what comes back. Making a card out of a member burns the carding fee — 2% at the start, never above 10% — pulled from the holder on top, so the card keeps the member's full floor. Moving a card into a warband burns the card token and costs nothing. Moving a member between two warbands is free.
The melt fee is capped in code Owner-settable in basis points under a hard-coded 10% ceiling, so a buyer can compute the worst-case floor of any warband before paying for it.
A lock stops a composition, never a transfer A registered game increments a counter on the token, so one warband can sit in several pools at once. The holder can still sell it; the match settles for the player whose balance is engaged, not for whoever holds the token.
The cosmetics path may never write Rendering lives in a view contract the vault points to, and each token carries one styleData word. Only the style contract writes it, and that pointer is the zero address at launch, so nobody does; the holder may always clear it. The vault treats the bits as opaque, and nothing about seeds or composition may ever pass through that path.

The frozen list

What becomes permanent the day after launch

The coin deploys with the observer already bound to its pool, and the deploy's own buy is the first roll. So this list binds from the pool's first block. Everything not on it is a parameter, a pointer or a later epoch.

The seed preimagekeccak256(poolId ‖ wallet ‖ index ‖ subIndex) at widths 32 / 20 / 8 / 1, then keccak256(commitment ‖ drawBlockHash). The sub-index is zero: a roll yields exactly one thing.
The record shapeWallet, first and last roll index, two anchors, the L2 height it was written at, and the settled hash. One record per buy, whatever the amount.
The two anchorsThe L2 height, read through the chain's block-history contract; the L1 estimate, read through blockhash as the fallback. Never mixed: one is addressed by L2 height, the other by L1 estimate.
The re-anchor ruleAllowed only when both anchors are unreadable, always to a future block, and by anyone. As many times as it takes, so no outage kills a roll.
AttributionThe transaction's origin, and nothing else. The hook's payload is never read.
The counterGross and monotonic, in the coin's base units.
The roll threshold1,000 tokens, and it never moves for the pool's life. The lever that does move is the vault's lock per creature.
Epoch 054 creatures, each with its faction and its tier; 25 traits, each with its stat and its sign. The tier shares, the faction list and the trait split are epoch data, movable for future rolls.
The epoch ruleA roll is decoded by the epoch in force at the height its record was written — not the epoch current when its creature is recruited.
The seat4 bytes: creature id 16 bits, trait 8, row 4, spare 4. Eight seats to a storage word.
The seat bound32, the width of the array. The cap the owner sets lives under it.
The two token kindsWarband or card, fixed at creation and never changed. A card holds exactly one member. One increasing id counter serves both, from 1.
The floorThe sum of what each seat froze, times one minus the melt fee. Storage and two parameters.
The fee capsMelt 10%, carding 10%, freeze 0.001 ETH per creature, naming 0.01 ETH, royalty 5%.
The lock's bounds10 to 1,000 tokens per creature, both bounds in code.
MeltNever pausable, never delayed.
The pauseIt covers recruiting from rolls, and carding. Nothing else.
styleDataWritten by the style contract alone; the holder may always clear it.
The reserve wordOne word per warband, written by the holder, opaque to the vault, cleared by any change of seats, and inside the composition hash. What a game reads into it is the game's business.
The registryAt most eight games. Add and remove take effect instantly, and removal voids every lock that game held.
The ownerA multisig, never renounced, with no delay on anything.

The promise

What a holder is owed, in one paragraph

Whoever runs Warbandry can change how your warband looks, how it scores in games, the melt fee — never above 10% — and what a new creature locks — never above 1,000 tokens. Your floor is what you locked. They can never touch your coins, your creatures, what your creatures are, or who owns them.

There is no delay anywhere: no notice period, no timelock, no window in which a holder gets to react. The guarantee is not that a change is announced in advance. It is that the dangerous change cannot be expressed at all — the melt fee has a ceiling in code, a melt cannot be stopped, the floor reads storage the owner cannot rewrite, and seeds, composition and ownership are out of the owner's reach entirely.

The vault

The contract a holder's money sits in

The ERC-721. It holds the coins, the warbands and the cards, and it ships on day one with the surface every future game reads — the registry, the lock, the calculator pointer — before any game exists.

The verbs

A player recruits a creature, dismisses it, and cards it. Freeze and melt stay the technical words for what happens to the coins. Recruiting from a roll pulls the lock — 1,000 tokens at launch — settles the roll if nobody else has, decodes the seed, and writes the seat. Dismissing to coins returns what that seat froze less the melt fee, and burns the fee. If the last seat leaves, the token is burned; the client warns first.

The two kinds

A warband holds up to the seat cap. A card holds exactly one member, and the kind is fixed when the token is minted. Moving a card into a warband is one gesture: the seat moves over with its seed and its coins, the card token is burned, and it costs nothing. The other direction — a member out of a warband into a new card — burns the carding fee in coins, pulled from the holder on top, so the card still holds the full amount its seat froze.

Naming

1 to 32 bytes of printable ASCII, minus the five characters that would need escaping inside the JSON and the SVG. No uniqueness — a token id already tells two warbands of the same name apart. Renaming is allowed at the same fee, an empty name restores the default, and naming works while the warband is locked, because it changes nothing in a duel.

The reserve word

One bytes32 a warband, written by its holder and opaque to the vault. It carries which seats are reserve, which of the two modes the warband plays, manual or automatic, and, for an automatic warband, the one condition and the swaps that condition fires. The vault checks nothing inside it: a malformed word is the match contract's to refuse at reveal, with a reason code and a refund. Every function that adds, removes or moves a seat clears the word, since it names seats by position and a shifted seat would name the wrong creature; the client writes it again in the next transaction. A cleared word is a warband with no reserve and no rule, which plays exactly as a warband did before the reserve existed. The composition hash covers it, so a lock covers it too: a rule cannot change between the reveal and the settlement.

The fees, and what bounds them

ParameterAt launchBound in code
Melt fee, burned out of what returns2%10%
Carding fee, in coins, burned, paid on top2%10%
Freeze fee, per creature0 ETH0.001 ETH
Naming fee0 ETH0.01 ETH
Royalty (ERC-2981)0%5%
Lock per creature1,000 tokens10 to 1,000 tokens
Seat cap2132, the storage bound

The seat cap starts at 21: the format's sixteen fielded creatures and five in reserve, the five a starting value the bench confirms. A reserve seat is a seat like any other, freezing the same coins and counting in the same floor. What stays under the renderer's own limit is the fielded count rather than the cap, since the renderer draws the fielded seats alone.

ETH fees accrue and are pulled by the fee recipient. The vault never pushes ETH, so a recipient that reverts can never block a freeze.

What it publishes

The subgraph never calls a view for history, so every event carries every field the history needs. Created and Burned; Recruited with the seat, the creature, the trait, the seed, where it came from and the coins frozen; Dismissed with where it went, what returned, what burned, and whether it was the last member; Formation, Named, Styled, AdjustmentSet, emitted with a zero word whenever a seat change clears it; Locked and Unlocked with the game; MetadataUpdate on every change of composition, name, formation or style, or marketplaces keep the old image. Every governance change emits its old and its new value.

The views: composition — the source of truth, readable without the renderer — compositionHash, floor, kind, name, styleData, adjustment, locks, isLocked, rollsUsed over a range of roll indexes, and every parameter and pointer.

Three rules that surprise people

The pause covers entries only — recruiting from a roll, and carding. A warband emptied of its last member is burned rather than kept as a husk. And a lock is a counter per game, not a flag: one warband can be engaged in several games at once, and none of those locks blocks a transfer.

The observer

The one contract that can never be redeployed

Frontier's hook calls it after every settled swap on the pool. It counts what each wallet has bought, gross, and writes a record when that count crosses a 1,000-token boundary. One record per buy covers a range of roll indexes, so the cost is the same whether a buy makes one roll or a thousand — which is what keeps a large buy from ever failing.

Each record carries two anchors: the L2 height, read through the chain's block-history contract, and the L1 estimate as a fallback through native blockhash. The history contract reaches about eleven hours back; the fallback is coarser and its window is about fifty-two minutes. Degraded, never dead.

settle(id) is open to anyone. It reads the draw block's hash and writes it once. Reading early or late gives the same hash, so choosing when to settle cannot change the outcome. reanchor(id) is open to anyone too, and only when both anchors have become unreadable: it writes a fresh pair, both in the future, as many times as it takes.

Three events — a roll written, a roll settled, a roll re-anchored — and the views that read a wallet's records, a record's status, and the seed of one roll. That is the whole surface.

It has no owner and no lever, because a bound hook extension is exactly what runs, forever. And it must never revert inside a swap: the hook swallows the revert, and the roll would be lost in silence. So there is no unbounded loop in it, no arithmetic that can trip, and the one external call it makes sits inside a try/catch.

The match contract

Ranked play, tick by tick

Every number in this section is an owner parameter with its cap in code — the starting values of one launch bracket, not laws. A bracket is a stake level and a format; nothing about the players.

The arena balance

Coins sit inside the match contract. Deposit any amount at any time, including while engaged. Withdraw any amount of the free balance at any time, and nothing may ever block that withdrawal — not a pause, not a removal from the registry, not a tick nobody settled. Entering moves the stake from free to engaged. Winnings land on the free balance and stay there until the player takes them. Accounting is per tick: one tick's pot can never pay another, and a tick nobody settles ends by refund.

Entering

One click is one match. The player signs a message naming the bracket and carrying a commitment — the warband, its composition hash and a salt, hashed in the client, the salt derived from a wallet signature so it can be rebuilt on any device. The keeper relays it; a player who would rather send the transaction calls the same function. Deposit and withdraw are the only transactions a player ever has to send. Cancelling takes effect at the next tick, and only if no pairing was possible there — so nobody can watch someone arrive and leave.

The tick

Every 30 seconds. The bracket's keeper sends one transaction carrying every entry it holds a secret for, and that transaction closes the window. Per entry, in order: the commitment matches, the player still owns the warband, the composition hash still matches, the reserve word is well formed, the format holds on the sixteen that fight, the vault's lock is taken, and the warband's composition-only half is read from its cache or computed and stored. An automatic warband, one whose swaps are written in advance, is checked twice: on its sixteen and on the warband those swaps would produce, and both halves are cached, which is what leaves settlement a comparison and a pick. Every failure is a refund of the stake, minus a small ETH gas fee, with a reason code — never a forfeit. An entry the transaction does not carry is refunded too. If no reveal arrives within 60 seconds of the tick's time, the tick did not happen: every entry stays in the pool, still engaged.

The format is the bracket's values at that moment: at most 16 members, at most 6 copies of one creature, one mythic, two legendaries, no relic until a relic kind exists, five reserve seats, three swaps a match, and no tier limit on what waits in reserve. Those are today's launch values, and the five and the three wait on the bench. A paired match never re-reads them. The caps bind the warband a swap produces as much as the one composed, so a reserve of five legendaries still brings in the two the format allows and no more.

The tick also records the calculator's address as the reveal closes, and settlement calls that address whatever the pointer says by then.

Pairing

Once the tick's first anchor is readable, anyone may pair. The caller submits the revealed entries sorted by rating and the contract only checks that the order does not decrease — verifying is linear, sorting is not. The field is cut into groups of 6, shuffled inside each group by the anchor's hash, and paired with neighbours. A player with no neighbour within 300 rating points, a pair that already fought inside the last hour, or the odd one out stays in the pool for the next tick: the lock released, the stake still engaged. Each paired match moves a fixed ETH fee from both gas balances into the gas pot. Where the bracket's adjustment window is zero, the second anchor is set 15 seconds ahead, 150 L2 blocks, and it is the one that decides. Where the window is set, pairing opens it instead and no draw block exists yet.

The adjustment

A warband carries five creatures beside its sixteen and may bring up to three of them in for one match, one for one. Which seats are reserve, which mode the warband plays and, for an automatic warband, its one condition and its swaps, all sit in the reserve word the vault holds. There are two modes, chosen per warband when it is composed. Manual asks its owner inside the match; automatic carries the answer in advance, as one condition about the opponent and a fixed set of swaps the contract applies at settlement. One contract runs both, and the bracket's adjustment window decides which one exists: at zero the bracket is automatic only.

In a manual bracket, pairing puts the match in a state of its own, awaiting adjustment. Each player signs Adjustment(matchId, adjustmentHash, nonce, deadline), the keeper holds both and calls revealAdjustments for that match as soon as it has both. An empty list is a legitimate answer: it says the base warband and it lets a match settle before the window ends. Per side the contract checks the signature, the nonce, the deadline, the hash against its preimage, that each swap pairs a reserve seat with a fielded one and names no seat twice, and that the warband the swaps produce still passes the format recorded at reveal. Every failure plays the base warband with a reason code, and none of them is a refund: the match is already paired and the opponent is owed a fight.

The timing rule is enforced on chain. Before the window's end, a reveal has to carry a valid sealed adjustment for both sides or that match is skipped untouched. From the window's end the keeper may sweep, a missing side counting as an empty adjustment. From the sweep grace on, anyone may sweep, so a keeper outage costs the adjustments of one window and never the match.

The draw anchor is set here, per match, in the transaction that reveals both adjustments, 15 seconds out, and never at pairing. The win probability is a public function of the two warbands, so a draw block readable during the window would let a player work out which of their swaps lands the draw on their side and send that one. The rule in one sentence: no draw block exists while a player may still choose. In an automatic bracket every adjustment is bound before the pairing, so the pairing anchors as it did.

The events: Paired carries the window's end; Adjusted(tick, matchId, player, ok, reason, swaps) lands once a side at the reveal; DrawAnchored(tick, matchId, l2, l1) when the anchor is written. Nothing at all is emitted when a sealed adjustment arrives, and that silence is deliberate: an event there would tell the opponent that the other side has answered, and how fast.

Said plainly: on chain the reserve is hidden from the screen, not from a reader of the chain. The seats and the reserve word are storage in a public contract, and Paired names both warband ids, so anyone reading the chain during the window knows the opponent's reserve, their mode and their rule. The client shows none of it, no event carries it, the lobby's odds are computed on base warbands. Once the fight is settled, the result shows the opponent's whole reserve: it is public in the vault already, and it says what you played against. What stays sealed either way is the opponent's answer. If the reading ever matters, the remedy needs no change in the vault: a later match contract takes the reserve as cards committed by hash and revealed with the adjustment, and the vault already holds cards.

The reserve, as bracket parameters

Parameter, per bracketAt launchBound in code
Reserve seats5the seat cap less the member cap
Swaps in a match3the reserve's seats
Tier limit on the reservenonea cap in code, written only if the bench asks for one
Adjustment window60 s · 600 L2 blocksa cap in code; 0 makes the bracket automatic only
Sweep grace300 s · 3,000 L2 blocksa cap in code
Minimum entrants to pair0 on the free bracket; six suggested on a staked oneper bracket; a tick under it pairs nobody and everyone stays in the pool
Adjustment rewardsized on measured gasa cap in code

Settlement

Anyone, in chunks of at most 50 matches, once the second anchor is readable; a match still awaiting its adjustment is skipped and the chunk carries on. Per match, the state that plays is decided first, side by side: in a manual bracket, whatever the adjustment reveal stored; in an automatic one, the side's own condition read against the opponent's base warband, locked since the reveal and unable to have moved, so the two rules never depend on each other. Then the recorded calculator returns a win probability in basis points, the draw is the anchor's hash combined with the match id, and the comparison decides. The pot is the two stakes; the rake comes out of it and the rest lands on the winner's free balance; both warbands unlock. The caller is reimbursed per chunk from the gas pot. Because the result is readable before it is paid, the client carries two states — result and settled — or a late settle looks like a missing payout.

The rating

Elo on chain, per season and per format, on the regulation bracket only. Everyone starts at 1000. K is 32, and 64 over an account's first 20 matches, because sorting a field that all starts at 1000 is the whole job at the beginning. The expected score comes from a rational lookup table over the rating difference — no 10^x anywhere in Solidity. Surprise is measured on the two ratings and never on the computed odds, or the rating would be measuring luck. A season change resets every rating to base. No decay on chain.

The rake

5% of the pot at the start, capped at 15% in code, set per bracket. Half is burned; half goes to an address the owner sets — the team's wallets at first. The contract holds no season pot; it only transfers, and the first seasons are paid by hand.

When the vault stops listing it

Every state-changing call checks first that the vault still registers this contract as a game. The moment it does not, the contract liquidates itself: no entries, no reveals, no pairing; everything engaged returns to the free balance; paired but unsettled matches are refunded, because their locks are gone and a composition may have moved. Withdrawals stay open throughout.

What it may never do, on top of the withdrawal it can never block

  1. Anchor a draw before both sides' adjustments are revealed, or the window has closed. While a player may still choose, no draw block exists for that match.
  2. Reveal one side's adjustment without the other's, before the window's end. After it, a missing side counts as an empty adjustment, and that is the sweep rather than a reveal of one side.
  3. Forfeit a silent player. Silence, a malformed adjustment, an illegal adjusted warband, a signature that fails: each one plays the base warband, and the fight goes on.

The keeper

The one trust point, and what it costs

The keeper is a service the team runs, one per bracket. It relays signed entries, sends the reveal for each tick in one transaction, submits the sorted order, settles in chunks, and re-anchors a window that lapsed.

The reveal is its alone — one registered address per bracket, changeable by the owner. One keeper per bracket, so two of them can never race with different batches and refund each other's players.

Its second job, in a manual bracket: it receives both sealed adjustments of a match, relays nothing until it holds both, sends the reveal the moment it does, and sweeps at the window's end. It sees both answers before the chain does, which is the trust the pool already places in it, bounded the same way: it can delay a match to the sweep and it can drop a side's answer, both visible in the events, and it can forge neither, since every adjustment is signed by its player. That is one more keeper transaction a tick, and several small ones rather than one large, since a match whose two players answered in ten seconds is not made to wait for the window.

What it costs. A reveal is about 200 k of gas an entry, and about 350 k for an automatic warband, since its adjusted half is computed and cached beside the base. An adjustment reveal is about 300 k a match. Both batch sizes are set under the chain's block gas limit, measured rather than assumed, and an automatic bracket's batch is set lower than a manual one's.

Everything after the reveal is open to anyone: pairing, settling, re-anchoring. Each action is reimbursed from a gas pot fed by a fixed ETH fee taken from both players at pairing. The fee is fixed rather than proportional because the work is: one reveal per player, a fiftieth of a settle, whatever the stake is. A third party settles at no loss, so an outage of ours has a cure that pays for itself.

What an outage costs is waiting, never a stake. An entry has these fates and no others:

The entryWhat happens to it
In the reveal, every check passedPaired.
In the reveal, a check failed — recomposed, transferred, illegal Refunded, minus the gas fee, with the reason. Nothing was visible before this transaction, so the failure gained its player nothing.
Not in the reveal — the secret never arrived, or it was left out Refunded. Not the player's doing, and nothing was gained by it.
No reveal transaction at all The tick did not happen. Every entry stays in the pool, still engaged, and the screen says "searching" one tick longer.

The keeper sees the pool one tick before anyone else. It cannot change anything with that — it can only deny, never take — and the entries it is looking at are already bound by their commitments. What closes the rest is a rule stated in public rather than in code: the operator does not play ranked.

Before the first buy

The order things are deployed in

  1. A full run on testnet against Frontier's real hook. A test coin, buys, rolls, recruits, a match tick — and the observer's worst-case gas measured under the real hook, then asserted in the suite.
  2. The reference vectors pass on the calculator. The arithmetic is integer and exact: the on-chain result reproduces the reference bit for bit, with no tolerance.
  3. An external audit of the three immutables — the observer, the decoder, the vault. The match contract and the renderer may be audited later; those two can be replaced, and these three never can.
  4. Admission to Frontier's catalog, with the final code. An extension that is not admitted cannot be bound to a pool at all.
  5. Deploy in order: the decoder with epoch 0, the renderer, the vault with its pointers set, the observer, then the coin with the observer bound. The deploy's own buy is the first roll.
  6. Source verification the same day.
  7. The match contract later, added to the registry when it is ready.

Still open

What has not been decided yet

OpenThe coin's name and its ticker. Three constants in one file that everything reads; choosing them is one commit, any time before the coin deploys.
OpenThe pool's fee setup and its opening value. The stated preference is a settable buy fee and sell fee under a cap in code. Fee behaviour binds when the pool is created, so that code has to be admitted to the platform's catalog first.
OpenThe rake per bracket, weighed against the burn it implies.
DeferredThe relic. How rare it is — one roll in fifty, twenty or ten — how it rolls, and what it does. The decoder reserves a kind field for it, and the match contract's relic limit stays at zero until one exists.
By hand at firstSeason rewards. Half the rake goes to an address the owner sets, and the contract holds no season pot.
OwedThe audit's budget and its schedule.
Still tuningThe numbers of the game itself — the stats, the abilities, the duel's constants. They live in the swappable calculator by design, so none of them is a deadline; none of them is settled either.