Skip to content

Real vs Play Money Split — two economies, one deploy

2026-07-19

Until today the chip was a deploy-wide constant (CHIP_TOKEN): one deploy transacted exactly one token, staging ran playSKPK-only, and offering a real-money table meant a chain cutover. Now every table carries a money-kind (play | real): a play table transacts playSKPK (earned on the claim board), a real table transacts SKPK/tSKPK (bought at the cage teller) — side by side in the same deploy, selected by the table row at the cage's single chipMint(kind) seam.

What shipped:

  • tables.money_kind (typed column, default play, migration 0095) + custody_entries.money_kind. Every read exposes it (table status, lobby rows, getTableModeAndSettings); the cage derives the mint from the ROW — no request field can redirect a deposit to the wrong economy (proven: a playSKPK-only user cannot fund a real table; the whole transaction reverts).
  • skpk_enabled — the real economy's kill-switch (game_settings global, fail-closed OFF, per-environment). Enforced at real-table create and fund; withdraw/settle/escape are never gated (funds always leave). Staging is ON; production stays OFF until real-money launch — the flip is a settings row, not a deploy.
  • Canonical-USDC backingnumero-token's wrap/unwrap re-bound from the retired self-minted SKUSDC to a configured external USDC mint (init_real_backing; Circle devnet USDC on staging, mainnet USDC later). Backing-mint substitution and foreign-destination payouts revert on-chain; conservation is adversarially tested. SKUSDC has no path into the chip anymore.
  • One custody deployment per economy — custody vaults bind one mint for life, so the real economy got a byte-identical numero-custody under a fresh program id (GiKdXReu…, the real-economy cargo feature swaps only declare_id). The cage routes escape/claim/dispute by the entry's stamped kind; a real table's escape lands in the real custody vault and redeems in tSKPK.
  • UI: the header shows both balances (playSKPK, and the real chip in the money green — tSKPK on staging, SKPK at mainnet); the lobby gains a play/real filter and real-row money styling; the cage teller becomes the functional USDC⇄tSKPK buy/cash-out window when the switch is on; the create form offers "real $" only while the switch is on.

Devnet was brought up the same day: numero-token upgraded, the real custody deployed + inited, the backing bound to Circle devnet USDC — verified on-chain.

See: decision · smart contracts guide — plan real-play-money-split.