Liquidity Provision
Oracle uses a pure Central Limit Order Book (CLOB) — no AMM, no shared liquidity pools, no LP vaults with share tokens. Liquidity comes from resting limit orders, and the protocol incentivizes LPs in two ways:
- Maker rebates — paid per fill, funded from the taker fee. Instant.
- Liquidity rewards — a daily USDC budget per market, awarded to wallets that held tight two-sided quotes. Extended quadratic scoring: multi-level depth, gold-band bonus, super-linear uptime weighting, anti-spoofing clamp, 40% per-wallet cap.
Both programs run independently. Any resting order is automatically eligible for both — no opt-in, no vault deposits.
1. Maker Rebates
Every fill on Oracle pays a rebate to the resting (maker) side. Rebates settle into the maker's usdc_balance at match time — spendable immediately, no claim step.
Fee split per fill
| Party | Flow |
|---|---|
| Taker | Pays taker_fee_bps on notional (default 2%) |
| Maker | Receives maker_rebate_bps of notional (default 0.5%) |
| Treasury | Receives the remainder |
Calculation
taker_fee = floor(fill_size × fill_price × taker_fee_bps / 10_000)
maker_rebate = floor(fill_size × fill_price × maker_rebate_bps / 10_000)
fill_price is in micro-USDC per outcome token (6 decimals). fill_size is outcome tokens.
Example — fill 1,000 YES @ $0.65, default bps:
- Taker pays:
1,000 × 650,000 × 200 / 10,000=13,000,000µUSDC = $13.00 - Maker earns:
1,000 × 650,000 × 50 / 10,000=3,250,000µUSDC = $3.25
Who earns it
Only orders that rest on the book and get matched by an incoming taker earn the rebate. A GTC limit order that sits and gets filled: rebate. A market order (IOC) that crosses the spread: no rebate — it's the taker. Partial fills pay pro-rata.
Changing fees
Fees are read live from FeeConfig on oracle-vault. Changes require an admin tx and are announced ≥24h in advance.
2. Liquidity Rewards
A daily per-market USDC budget is distributed to wallets that hold resting orders inside a configured spread band. The Oracle scoring formula extends a quadratic distance base with five mechanics that reward real depth, uptime, and two-sided balance — and punish spoofing and whale capture.
Per-sample scoring
Every 30 seconds the engine snapshots each market's order book. For each wallet with resting orders, compute:
(a) Per-order distance (quadratic base). For every resting order inside max_spread_bps:
order_score = size × ((max_spread − distance_from_mid) / max_spread)² × in_game_multiplier
A quote at mid earns size × multiplier. Halfway to the band → 25% (0.5²). At the boundary → 0.
(b) Multi-level depth. Sum across every resting order on the side, with a per-level decay by rank-from-mid. Rewards real depth, not just a single tight quote:
side_score = Σ order_score(o) × level_decay(rank(o))
level_decay(rank) = 1 / (1 + 0.5 × rank) // 1.00 / 0.67 / 0.50 / 0.40 / …
(c) Gold-band bonus. Orders within the tightest 25% of max_spread get a 1.5× multiplier on top of the quadratic.
(d) Combined sides (single-sided penalty).
combined = max( min(bid_score, ask_score), max(bid_score, ask_score) / c )
c = 2 // stricter than the c=3 used elsewhere; single-sided = 50% credit
Symmetry bonus: if |bid − ask| / max ≤ 0.20, multiply combined by 1.10.
Daily aggregate
uptime = active_samples / 2880 // active = non-zero combined score
daily_score = (Σ sample_scores) × uptime^0.8
Super-linear uptime penalty (uptime 95% → ×0.96, 80% → ×0.83, 50% → ×0.57).
Anti-spoofing clamp: a wallet's cancel_ratio over a rolling 5-min window = cancels / (cancels + fills). If > 0.50 with any cancels, every sample in that window is scored ×0.5.
Daily distribution
At 00:00 UTC, pro-rata by daily_score, then cap at 40% per wallet:
raw_payout(w) = daily_score(w) / Σ daily_scores × daily_budget_usdc
max_share = daily_budget_usdc × 0.40
final_payout(w) = min(raw_payout(w), max_share)
Any undistributed remainder from cap enforcement rolls into the next day's budget.
Credits accumulate in a wallet-level claimable_micro_usdc — a single balance across every market.
Per-market configuration
Each market has its own max_spread_bps, min_size, daily_budget_usdc, in_game_multiplier. See GET /v1/rewards/config. Markets without a config earn nothing.
3. Claim Flow
Reward credits are distinct from wallet balance. Claiming moves USDC from the fee treasury (on Fogo) to the user's proxy wallet USDC ATA.
On-chain plumbing
- Vault instruction:
claim_rewardsonoracle-vault(Fogo) - Signer: the vault PDA
[b"vault"](CPI-signed transfer) - Authority:
operatoronly (relayed — user doesn't pay gas) - Source:
fee_treasuryUSDC token account - Destination: ATA of the user's
proxy_walletPDA[b"proxy", user]
API
POST /admin/rewards/claim
X-Admin-Key: <admin key>
{
"wallet": "<bs58 user pubkey>",
"amount_micro_usdc": 5000000 // optional; defaults to full claimable
}
Response (200):
{
"claimed_micro_usdc": 5000000,
"remaining": 400000,
"signature": "5Kx8..."
}
The signature is the Fogo tx. remaining reflects claimable_micro_usdc after the decrement; the decrement is atomic and clamps at zero (never negative, even on over-claim).
Failure mode: tx succeeds, Redis decrement fails
If the on-chain tx lands but the Redis decrement errors, the response is still 200 with remaining: null and a warning field flagging manual reconciliation. The funds are delivered on-chain; only the accounting counter is out of sync. Operator must reconcile manually.
Public self-service endpoint
Not yet shipped. Today all claims are operator-relayed and admin-key-gated. Market makers running continuous strategies should arrange scheduled sweeps with the Parti team.
4. Running a Market Maker
The reference market-making bot is oracle-lp (Rust). It:
- Subscribes to the order-book WebSocket
- Maintains symmetric two-sided quotes around mid, scaled by
spread_bpsandsize - Cancels and re-posts when mid moves >
requote_bps - Tracks inventory per market, skews the constrained side on drift
Typical loop (pseudocode)
while True:
book = GET /v1/markets/{id}/book
mid = book["yes_price"] # micro-USDC per token
# Cancel existing resting orders
POST /v1/orders/cancel-all { market_id, user, signature, nonce }
# Re-post inside the rewards band
for offset_bps in [spread_bps, spread_bps*2, spread_bps*3]:
POST /v1/orders {
side: "buy", outcome: "yes",
price: max(1, mid - offset_bps),
size: N, order_type: "gtc",
signature, nonce
}
POST /v1/orders {
side: "sell", outcome: "yes",
price: min(9999, mid + offset_bps),
size: N, order_type: "gtc",
signature, nonce
}
sleep(5)
Order type is gtc (not post_only) because cancel-all runs before each rebalance, so there are no stale LP orders to cross with.
Picking spread_bps
Quote inside the market's max_spread_bps — quotes outside earn rebates on fills but score 0 for rewards. Rule of thumb: spread_bps ≈ max_spread_bps / 4 for the tightest level, widening geometrically.
Key endpoints for market makers
| Endpoint | Use |
|---|---|
GET /v1/markets/{id}/book |
Current order book state |
POST /v1/orders |
Place orders (gtc or post_only) |
POST /v1/orders/cancel-all |
Bulk cancel before requoting |
WS book:{market_id} |
Real-time book updates |
GET /v1/rewards/config |
Per-market max_spread_bps, min_size, daily_budget |
GET /v1/rewards/leaderboard?market_id= |
Current-day scoreboard |
GET /v1/rewards/wallet/{wallet} |
Cumulative claimable balance |
5. Deposit & Operational Limits
Market makers hold significant inventory. The protocol enforces per-tx and aggregate bridge caps — see Deposits & Withdrawals for the full table. Summary:
| Tier | Max USDC per bridge tx |
|---|---|
| Retail (default) | 10,000 |
| LP | 1,000,000 |
| Institutional | 10,000,000 |
Plus a global 100,000 USDC/day bridge aggregate cap across all users. Native Fogo deposits (if you're already on-chain) bypass both limits.
Tier upgrade is a single on-chain tx: POST /admin/bridge/user-tier with tier: 1 (LP) or tier: 2 (institutional).
6. Why CLOB, not AMM
- Correct price discovery — prediction markets have binary terminal values, so LP-against-AMM strategies bleed to informed traders. A CLOB lets makers step back when they're out-gunned.
- Risk isolation — one market's volatility doesn't affect another's liquidity.
- LP control — makers choose exactly which markets to provide on, at what spread, with what size.
- Capital efficiency — no idle depth in deep out-of-the-money bands; capital quotes where the flow is.