Skip to main content
A place call reverts unless it clears all of these gates. Quote them client-side before sending the transaction — every value below is readable on-chain.

Constraint table

Liability is the maximum the pool might have to pay: Strike W, Range P_max, Ladder max(payouts). It is reserved against the bankroll at place time and released at settle.

The effective multiplier

effectiveMaxMultiplierBps() is a live gate that scales linearly with bankroll utilization:
Formula
A 100× Strike that quotes fine on an idle pool can revert minutes later when other bets fill the liability budget. Re-read effectiveMaxMultiplierBps() (or consume the BankrollSync event, which carries all the precomputed caps) right before placing.

Ladder mass snapping

The contract checks the Ladder EV identity in exact integer math — a float-solved probability set almost never lands on it after rounding to WAD. The reference client rounds masses with a largest-remainder allocation, then transfers single units of mass between buckets until the on-chain check passes (see snapMassToChain in the web app’s ladderQuotes). If you build Ladder args yourself, do the same: quote with the exact contract formula, and adjust masses (not payouts) until Σ massWad × payouts / WAD == EV × stake.

expectedCommitId freshness

Every place call pins the epoch it bets under. Read currentCommitId() immediately before sending; if the keeper rotates the epoch between your read and your transaction, the call reverts CommitMismatch — just re-read and retry. There is no max-age gate on an open epoch, so an open epoch never goes “stale” on its own.
All caps in one read: subscribe to the BankrollSync event, which emits availableBankroll, effectiveMaxMultiplierBps, maxStakeCap, and maxBetLiabilityCap after every place, settle, and stake movement — no eth_call polling needed. See Events.