SettleKit docs

Parlays as composed proofs

fw-parlay — N-leg cross-fixture tickets settled atomically by N Merkle proofs.

A parlay is a conjunction of proofs. fw-parlay (devnet 7FcnF7RUVdP9CgWPmJ7AezErDMoXtPNVeYatWDU7jNaN) is the third SettleKit consumer: a ticket names up to four legs across different fixtures, and settlement reads one proven MatchFacts account per leg — the same goalshield trust pattern, N times in one transaction. No leg can settle on anything but a Merkle-proven score; the whole ticket resolves atomically.

The live demonstration is a real ticket across the last two matches of the 2026 World Cup — France–England (third place) and Spain–Argentina (the Final) — bought before either kicked off and settled by two proofs after the Final: 8w4b…ep4N (built by tools/parlay-demo.ts).

How a ticket is priced

The markets price the legs; the parlay composes them. At purchase, each leg's price is read from the live fw-markets LMSR account (PDA re-derived on-chain from the leg's (fixture, kind, param) — the caller cannot substitute a market):

payout = stake × Π (1e6 / leg_price_ppm) × (1 − fee)     — capped by pool.max_payout

computed in a running WAD fixed-point accumulator (no overflow at four legs), with a min_payout slippage guard. Locked leg prices are stored on the ticket.

Solvency, structurally

The house pool reserves the full potential payout at purchase:

vault_balance ≥ reserved_payouts        — after every instruction

buy_ticket requires payout − stake ≤ free_liquidity before reserving; loss, void, claim, and refund each release exactly what they owe. The authority can only withdraw unreserved liquidity — accounting runs on the ledger, never on raw token balances.

Leg semantics mirror settle_market

Supported leg kinds: match winner, over/under, both-teams-to-score, draw-no-bet, odd/even — evaluated from the proven (home_goals, away_goals, phase) with logic mirrored from fw-markets (locked by a parity unit test). A draw-no-bet leg on a draw voids to odds 1.0 (divided out of the payout, the industry convention); any lost leg loses the ticket; a ticket whose facts never arrive refunds after its deadline — the same no-oracle backstop philosophy as everywhere else in SettleKit.

Try it

pnpm test:svm            # parlay.test.ts: 12 integration tests incl. the full
                         # buy → settle → claim path against the mock oracle
npx tsx tools/parlay-demo.ts   # the real cross-match ticket (devnet)