Skip to main content
Placing is a single on-chain call per bet: approve USDG once, then placeStrike, placeRange, placeTieredBetter, or placeShuffle on ChancePool. Full signatures live in Contract methods; this page covers how to build the args correctly.

Choose a mode

See Bet modes for the payout math of each.

Common args (all modes)

Keep expectedCommitId fresh

Every bet pins the epoch it settles under. If the epoch rotates between your read and your transaction landing, the place reverts CommitMismatch. The fix is mechanical:
TypeScript
There is no epoch max-age: an open epoch stays placeable until the keeper rotates it.

Mode-specific gotchas

  • Strike - multipleBps is gated by the live effectiveMaxMultiplierBps(), which shrinks as bankroll liability fills. Quote it immediately before placing, not at page load.
  • Range - the band must bracket expected value: payoutMin ≤ 0.85 × stake ≤ payoutMax, and payoutMax − stake must fit both the liability cap and Kelly.
  • TieredBetter - the contract checks Σ massWad × payouts / WAD == EV × stake in exact integer math. Snap your float probabilities onto the identity (largest-remainder rounding, then move single mass units between buckets until the check passes) or the place reverts InvalidOdds. Preview with validateTieredBetter. See Bet constraints.
  • Shuffle - snap payouts so Σ payouts · K == N · EV × stake. Picks must be distinct and in range. Preview with validateShuffle.

Attribution

platform and game land on the BetPlaced event (emit-only - never stored on the bet, and echoed back through the API’s bet payloads). Pass stable identifiers so your wagers are attributable in analytics:

After the transaction

The betId comes back as the return value and on BetPlaced. From here, follow Results & proofs - you don’t need to poll the contract.