> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chance.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Placing bets

> Building place args per mode, keeping expectedCommitId fresh, and attributing bets to your platform.

Placing is a single on-chain call per bet: approve USDG once, then `placeStrike`, `placeRange`, or `placeLadder` on ChancePool. Full signatures live in [Contract methods](/protocol/contract-methods); this page covers how to build the args correctly.

## Choose a mode

| Your game                                              | Mode   | You provide              |
| ------------------------------------------------------ | ------ | ------------------------ |
| Double-or-nothing, crash-style multiples               | Strike | `multipleBps`            |
| "Always pays something" bands                          | Range  | `payoutMin`, `payoutMax` |
| Dice, wheels, prize tables — any discrete distribution | Ladder | `payouts[]`, `massWad[]` |

See [Bet modes](/protocol/bet-modes) for the payout math of each.

## Common args (all modes)

| Arg                 | How to build it                                                                                                                                                              |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stakeAmount`       | USDG units; must clear `minBet` / `maxBetAmount` / `maxStakeCap()`                                                                                                           |
| `clientSeed`        | 32 random bytes, **non-zero**. This is the player's entropy contribution — generate it client-side and keep it so users can [verify fairness](/protocol/provably-fair) later |
| `expectedCommitId`  | Read `currentCommitId()` right before sending (see below)                                                                                                                    |
| `affiliate`         | Optional affiliate address; zero address for none                                                                                                                            |
| `platform` / `game` | Optional attribution strings, ≤ 64 bytes each (empty string = unset)                                                                                                         |

## 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:

```ts TypeScript theme={"theme":"css-variables"}
async function placeWithRetry(place: (commitId: bigint) => Promise<Hash>) {
  for (let attempt = 0; attempt < 2; attempt++) {
    const commitId = await readCurrentCommitId()
    try {
      return await place(commitId)
    } catch (err) {
      if (!isCommitMismatch(err) || attempt === 1) throw err
    }
  }
}
```

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 the liability cap.
* **Ladder** — 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`. See [Bet constraints](/protocol/bet-constraints).

## 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:

| Field      | Example             |
| ---------- | ------------------- |
| `platform` | `chance.money`      |
| `game`     | `dice.chance.money` |

## After the transaction

The `betId` comes back as the return value and on `BetPlaced`. From here, follow [Results & proofs](/integrate/results-and-proofs) — you don't need to poll the contract.
