Skip to content

Fees

GoMarket charges fees in two unrelated places: on CLOB trades, and on winning parlay payouts. The mechanics are different in each.

Fees are charged on the taker asset — the asset flowing from taker to maker — and accrue to a per-mint fee vault PDA.

Fee vault seeds = ["fee_vault", mint]
Maker’s sideTaker pays the makerFee taken in
BUYoutcome tokensoutcome tokens
SELLcollateralcollateral
price = calculate_price(maker_amount, taker_amount, side);
min_price = min(price, ONE - price);
match side {
Side::Buy => (fee_rate_bps * min_price * outcome_tokens) / (price * BPS_DIVISOR),
Side::Sell => (fee_rate_bps * outcome_tokens / BPS_DIVISOR) * min_price / ONE,
}

The min(price, 1 − price) term is the important part. It scales the fee by how far the price is from a certainty, so the effective rate is highest at $0.50 and falls toward zero at the extremes.

YES pricemin_priceRelative fee
$0.500.50maximum
$0.20 or $0.800.2040% of max
$0.05 or $0.950.0510% of max

A trader buying a 3¢ longshot is risking 3¢ to make 97¢. Charging them the same percentage as someone trading a coin flip would be a far larger share of their actual risk. Scaling by min(p, 1−p) keeps the fee proportional to the value at stake rather than to the notional.

Takers pay; makers don’t. The validator enforces this at insert: an order that is marketable on arrival must carry at least the taker fee rate in feeRateBps, or it’s rejected. A resting order that is later taken doesn’t pay — it was the maker on that fill.

So feeRateBps on your order is not optional decoration. Set it correctly for the role your order will play, or the insert fails.

The on-chain handler independently validates fee <= taking, so a malformed fee rate cannot consume the entire payment.

A parlay’s fee is charged on the gross potential payout, at claim time, and only on a winning slip.

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

Three properties:

  • No fee on the stake. Placing a parlay costs exactly your stake.
  • No fee on a loss. You lose the stake, nothing more.
  • The rate is snapshotted at create time. fee_bps_at_create is written into the Parlay account when you place it and read back at claim. An admin update_config between those two moments cannot change what you pay.

The cap is 10% (fee_bps ≤ 1000), enforced at initialize and on every update_config.

At claim, the vault pays net to the user and fee to config.treasury in the same transaction.

stake $10
legs 3, at 50% / 40% / 25%
combined 0.05
potential_payout $200
fee_bps_at_create 200 (2%)
fee = floor(200_000_000 × 200 / 10_000) = 4_000_000 → $4
net = $200 − $4 = $196
SourceDestination
CLOB trade feesPer-mint fee vault PDA, ["fee_vault", mint]
Parlay feesconfig.treasury token account

Both are on-chain accounts controlled by the program’s admin authority, which in production is a Squads multisig.

CostNotes
Solana transaction feesPaid by the executor for CLOB settlement; paid by you for parlay instructions
Priority feesThe executor escalates these on retries
Mint / mergeNo fee — a par conversion, not a trade
Redeem / refundNo protocol fee
Cancelling an orderFree; off-chain only
SpreadNot a fee, but usually your largest real cost on a thin book