Skip to main content
Testnet values — not real money. Any concrete feeRateBps, k, or bps numbers quoted on this page apply to the ADI-testnet deployment (chainId 99999) and are placeholder rates used for partner integration and load-testing — no real money flows. The formula (fee = k × P × (1 − P) × outcomeTokens) and the integration contract (market.feeTakerBps as the canonical signing input) are stable across environments.

The formula

  • P is the execution price, 0 < P < 1.
  • k is a period-specific coefficient.
  • outcomeTokens is the number of outcome tokens traded.
  • The curve peaks at P = 0.5 (max uncertainty) and decays to 0 at the extremes.
  • Both sides of every fill pay this fee. CTFExchange._chargeFee fires on each leg of _matchOrders / _fillFacingExchange — the same feeRateBps value the user signed into the EIP-712 Order is deducted from the asset they’re receiving (collateral on SELL, outcome tokens on BUY). Earlier docs claimed “maker fee is always 0”; that matched a transitional MVP path where signed orders carried feeRateBps = 0. As of the on-chain-fees rollout, every signed Order carries the live feeTakerBps and the contract takes the fee on both legs.

Why quadratic (not linear)?

The linear min(P, 1−P) curve (Polymarket’s default) is twice as expensive at the top of the book. For tail markets the linear curve still charges meaningful fees; the quadratic curve naturally eases to zero. Holding feeRateBps constant, the curves compare as follows (illustrative — the absolute % depends on the rate set on the market): Effective feeRateBpsk: feeRateBps = k × 10_000. Per-wallet fee tier (and the resulting makerBps / takerBps) is available at GET /api/me/fee-tier.

Three fee surfaces — which one to use

The API exposes three fee values; partners often ask which one “actually applies.” Short answer:
Only market.feeTakerBps belongs in the signed Order. Signing with the platform period rate or your tier rate produces a digest that doesn’t match the CTFExchange reconstruction → bad_signature on every order. Always pull feeTakerBps from the per-market response and pass it into your signing helper unmodified.
A worked example for a tier-1 partner on a market with feeTakerBps = 400: The on-chain charge uses 400 (because that’s what the signed Order carries); the per-fill /api/me/fees row records 350 (your post-discount rate after the platform refunds the difference via the rebate ledger). The two values reconcile in the rebate accrual, not at fill time.

Charging direction

The asset the fee is taken in is determined by which side of the fill each party held — the same rule applies regardless of maker/taker role:
  • Seller (whichever side is sending outcome tokens for collateral): fee deducted from collateral proceeds. fee_collateral = k × P × (1−P) × outcomeTokens.
  • Buyer (whichever side is sending collateral for outcome tokens): fee deducted in outcome tokens. fee_tokens = k × (1−P) × outcomeTokens.
Both give the same USD value for the same fill — just denominated in the asset that side is receiving. On a single match the contract charges both legs; per-fill /api/me/fees carries one row per denomination per trade (unit ∈ {USDC, OUTCOME_TOKENS}, role ∈ {maker, taker}).

How fees appear in the response

Every Trade object carries:
For per-fill audit, use GET /api/me/fees.

On-chain equivalence

The off-chain fee matches the on-chain fee charged by CTFExchange at settlement time, modulo integer-division rounding (≤ 1 atomic USDC unit). Same feeRateBps value signs into the EIP-712 Order.

Fee cap

Contract enforces feeRateBps ≤ MAX_FEE_RATE_BIPS (1000). Peak-at-0.5 at the cap is 2.5%. Raising requires Board approval and redeploy.

Examples

Rebates

The schedule covers fees. Mirror-image rebates to market makers are a separate system (PS-MM Rebate Model v7 §2). Rebates settle monthly. Contact partners@predictstreet.com.