TremorDocs
Docs menu
Market mechanics

Status and lifecycle

Upcoming → Live → Finalizing → Finalized → Closed, and who can do what in each.

Status

StatusCondition
Upcomingnow < start
Livestart ≤ now < expiry
Finalizingnow ≥ expiry, not yet finalized
Finalizedfinalize has run: finalVariance and payoutPerUnit are fixed
ClosedNothing outstanding, strategies docked, unsold inventory burned, residual collateral freed

The Lens encodes status as uint8 (0 Upcoming, 1 Live, 2 ExpiredUnfinalized, 3 Finalized, 4 Closed); the API uses lowercase strings. Status is only half the picture — what a user can actually do depends on the legs and on whether the market is current.

Who can do what

UpcomingLive, before saleEndLive, after saleEndFinalizingFinalizedClosed
Buy
Exit
Redeem
Checkpoint
Finalize✓ when complete
Stop issuance (writer)
Close (writer)✓ if nothing sold✓ if nothing outstanding✓ if nothing outstanding✓ if nothing outstanding✓ if nothing outstanding

stopIssuance remains callable on chain after saleEnd, but by then the ISSUE leg is dead by its own Deadline, so it only docks an empty strategy — the app stops offering it once issuance is closed either way.

Buying and exiting additionally require the market to be current — every passed sample point stored. See Checkpoints and finalization.

The app derives the trade rail's tabs from exactly this table, so it never offers a button whose only possible outcome is a revert.

Sequence

WRITE     writer:  createVault (once) → approve USDC → deposit → createSeries
                   createSeries mints maxUnits to the vault and ships ISSUE, EXIT and SETTLE in one tx
BUY       buyer:   approve USDC to the router → router.swap(ISSUE order, USDC)
                   receipts out, premium into the vault, skew rises, collateral reserved at the cap
EXIT      holder:  approve receipts to the router → router.swap(EXIT order, units)
                   USDC out at the bid, receipts burned, skew falls, reservation released
UPDATE    anyone:  accumulator.checkpoint(id, 32)      repeat until stored == available
EXPIRE    saleEnd passes → ISSUE dead by Deadline; expiry passes → EXIT dead by Deadline
FINALIZE  anyone:  accumulator.finalize(id)
                   fixes finalVariance and payoutPerUnit; releases the cap surplus to the writer
REDEEM    holder:  router.swap(SETTLE order, units)
                   USDC out at payoutPerUnit, receipts burned, reservation released
CLOSE     writer:  factory.closeSeries(id)   only with nothing outstanding

Who signs what

ActorActionCall
Writercreate a vaultfactory.createVault() — idempotent
Writerfund itusdc.approve(vault), vault.deposit(amount)
Writeropen a marketfactory.createSeries(vault, params)(id, receipt)
Writerwithdraw unreserved collateralvault.withdrawFree(amount, recipient)
Writerclose new salesfactory.stopIssuance(id)
Writerwind a series upfactory.closeSeries(id)
Buyerbuyusdc.approve(router), router.swap(issueOrder, amountIn, takerData)
Holderexitreceipt.approve(router), router.swap(exitOrder, units, takerData)
Holderredeemreceipt.approve(router), router.swap(settlementOrder, units, takerData)
Holderburn a worthless positionfactory.burnWorthless(id, units)
Anyoneupdate the marketaccumulator.checkpoint(id, maxSamples)
Anyonefix the payoutaccumulator.finalize(id)

Note what is missing: nobody ships, nobody docks, nobody approves Aqua. All three are done by the controller and the vault, which is what makes the collateral guarantees hold.

Where the UI reads it

Lists and live fields come from TremorLens.states(from, to) over RPC, chain-first. The backend adds fill history, the reconstructed quote path and vault event history. Both poll every 8–30 s, and every executable number on a ticket is re-quoted on chain immediately before the transaction is built.