Skip to content

How Parlays Work

A parlay — GoCombo in the product — is a single slip carrying 2 to 10 legs. Each leg is one market plus a YES or NO pick. The per-leg probabilities multiply into a combined probability, and the payout multiplier is its reciprocal.

Every leg has to land. One loss and the slip pays nothing.

┌─────────────────────────── Parlay ────────────────────────────┐
│ stake $10 potential payout $200 │
├───────────────────────────────────────────────────────────────┤
│ leg 0 Market #412 YES p = 0.50 Pending │
│ leg 1 Market #518 NO p = 0.40 Pending │
│ leg 2 Market #603 YES p = 0.25 Pending │
├───────────────────────────────────────────────────────────────┤
│ combined = 0.50 × 0.40 × 0.25 = 0.05 → multiplier 20× │
└───────────────────────────────────────────────────────────────┘

This is the thing to internalise first. A parlay is not a basket of outcome tokens and it does not trade against the CLOB.

CLOB positionParlay
CounterpartyAnother traderThe parlay vault (house)
Represented byFungible YES/NO SPL tokensA non-transferable Parlay PDA
Price sourceLive order bookPer-leg probability, locked at create time
Exit earlyYes — sell into the bookNo
Partial exitYesNo — all or nothing
Programmarketshigh-market-parlay

The parlay program never touches the YES/NO mints. It holds USDC and pays USDC. Legs are references to markets, priced once.

Legs are currently AMM markets; CLOB order-book markets can’t be used yet. → CLOB Markets as Legs

create_parlay
│
▼
┌─────────┐
│ Active │──────────────────┐
└────┬────┘ │
┌──────────────────────┼──────────────────┐ │ void_parlay
│ any leg lost │ all legs in, │ │ (admin)
│ │ none lost │ │ all legs
▼ ▼ ▼ ▼ cancelled
┌──────┐ ┌──────┐ ┌────────┐ ┌──────────┐
│ Lost │ │ Won │ │ Voided │ │ Refunded │
└──────┘ └──┬───┘ └───┬────┘ └──────────┘
│ claim_parlay │ admin already
▼ ▼ paid out
┌──────────────────────────┐
│ Claimed │
└──────────────────────────┘

Three instructions do the work:

InstructionWhoWhen
create_parlayYouLocks the stake, snapshots every leg’s probability
settle_legAnyoneOnce a leg’s market is Resolved or Cancelled
claim_parlayYouOnce the slip is Won — or Voided, for a stake refund

settle_leg is permissionless by design — the outcome is fully determined by on-chain market state, so whoever pays the transaction fee gains nothing by being the one to call it. Users, operators and indexers can all keep state fresh.

Per leg, the probability comes from the underlying market and is written into the Parlay account at create time. It is never recomputed. You are paid at the multiplier you locked.

combined = ∏ pᵢ accumulated in 1e12 fixed point
payout = stake × 1e12 / combined

The high-precision accumulator matters: doing this in the legs’ native 1e6 scale truncates badly on longshots. A 4-leg slip at 5% each would pay 166,666× instead of the true 160,000× — a 4.2% overpay straight out of the vault.

→ Pricing & Payout Math

A parlay must clear several gates before the program accepts it:

GuardRule
Leg count2 ≤ N ≤ max_legs (hard cap 10)
Probability bandInside [prob_floor_bps, prob_ceiling_bps]; hard bounds 1%–99%
Market qualityMinimum age, AMM depth (b) and settled volume
Duplicate marketsRejected
Same-event correlationTwo legs from one event: rejected
Market statusEvery leg’s market Open and before end_time
Collateral mintMust match the vault’s
Stake boundsWithin min_stake … max_stake
Payout cap≤ config.max_payout
Slippage≥ your min_payout
Vault solvencyExposure + this payout ≤ 80% of the vault balance
Pausedis_paused must be false

Every threshold is admin-tunable config within hard bounds, so read them from the config account rather than hardcoding.

The correlation guard is the one that surprises people: you cannot combine “Team A wins” with “Team A wins by 2+”. Multiplying near-identical probabilities as if independent would massively overprice the slip against the house.

→ Leg Eligibility

Each leg settles independently against its market’s terminal state:

MarketLeg becomesEffect on the slip
Resolved, your side wonWonContinues
Resolved, your side lostLostSlip dies immediately
CancelledVoidedDivided out of the multiplier; payout shrinks

If every leg ends up cancelled the slip itself becomes Voided — the stake is refunded, but you still have to claim it.

A voided leg doesn’t kill the slip and doesn’t win it. It’s removed from the product, and the remaining legs determine a smaller payout. Mixed won-and-voided slips settle fine.

→ Settlement & Claiming

You’re betting against a USDC vault with two invariants that always hold:

1. vault.amount ≥ total_exposure (always)
2. total_exposure + new_payout ≤ 0.8 × (vault.amount + stake) (at create)

The 20% buffer absorbs rounding drift, all of which is biased toward the house. Admin withdrawals cap at vault.amount − total_exposure, so idle funds can leave but reserved funds cannot.

If a slip you want would breach invariant 2, it’s rejected with ExposureLimitExceeded — reduce the stake.

→ Vault & Solvency

Charged on the gross payout, at claim, only on a winner:

fee = floor(potential_payout × fee_bps_at_create / 10_000)
net = potential_payout − fee

No fee on the stake, no fee on a loss, no fee on a refunded slip, and the rate is snapshotted at create time so a config change can’t alter what you pay.

One deadline to know: a won slip stays claimable only until parlay.claim_deadline. Past it an admin can refund the stake and the winnings are forfeited. → Settlement & Claiming

Trader GuideBuild and place a slip, step by step
Pricing & Payout MathThe multiplier, the accumulator, the recompute
Leg EligibilityEvery rule that can reject a leg
Settlement & ClaimingPer-leg settle, claim, void
Vault & SolvencyExposure accounting and the 80% rule
CLOB Markets as LegsThe price accumulator on CLOB markets — and why they aren’t legs yet
Risk ControlsExposure limits, correlation policy, vault operations