Liquidity Rewards
Oracle pays a daily USDC budget per market to wallets that post tight two-sided quotes with real depth and consistent uptime. The scoring formula extends the standard quadratic-distance base with five additions that reward genuine market-making and punish gaming.
How you earn
Every 30 seconds the engine snapshots each market's order book. For each wallet with resting orders, the rewards service computes a per-sample score, aggregates into a daily score, then distributes the market's budget at 00:00 UTC subject to a per-wallet cap.
1. Per-order distance score (quadratic base)
Baseline for every resting order within max_spread_bps of mid and at or above min_size:
order_score = size × ((max_spread − distance_from_mid) / max_spread)² × in_game_multiplier
A quote at mid earns full size × multiplier. Halfway to the band boundary earns 25% (0.5²). Outside the band earns 0.
2. Multi-level depth — sum across all levels
Most reward systems score only the single best order per side. Oracle scores every resting order in the band, with a per-level decay based on rank-from-mid:
side_score = Σ over orders o on this side of:
order_score(o) × level_decay(rank(o))
level_decay(rank) = 1 / (1 + 0.5 × rank)
// rank 0 = 1.00, 1 = 0.67, 2 = 0.50, 3 = 0.40
Net effect: 3 levels of 100-size at 10/30/60 bps from mid score ~1.9× a single 100-size level at 10 bps. Real two-sided depth is rewarded, not just a single tight quote.
3. Gold band bonus
Quotes within the tightest 25% of max_spread — the "gold band" — get a 1.5× multiplier on top of the quadratic. For a max_spread_bps=200 market, the gold band is 0–50 bps. Inside it, a 10-bps quote scores 0.95² × 1.5 ≈ 1.35 × size.
4. Tighter single-sided penalty
combined_side = max( min(bid_score, ask_score), max(bid_score, ask_score) / c )
c = 2
Single-sided quoting earns 50% credit of the active side (stricter than the standard c = 3 = 33% used elsewhere). Stronger push toward genuine two-sided markets.
Symmetry bonus: if the smaller side is within 80% of the larger (|bid − ask| / max ≤ 0.20), the combined side is multiplied by 1.10. Balanced books earn a premium on top.
5. Daily aggregate with uptime weighting
The sampler runs every 30s → 2880 samples/day. Let uptime = active_samples / 2880 (active = that sample had a non-zero combined_side score).
daily_score = (Σ sample_scores) × uptime^0.8
Super-linear penalty for gaps:
| Uptime | Multiplier |
|---|---|
| 100% | 1.00 |
| 95% | 0.96 |
| 90% | 0.92 |
| 80% | 0.83 |
| 50% | 0.57 |
| 25% | 0.33 |
A wallet that quotes 22 of 24 hours earns ~92% of what it otherwise would — a 2-hour outage costs 8%, not a linear 8.3%.
6. Anti-spoofing clamp
A wallet's cancel_ratio over a rolling 5-min window = cancels / (cancels + fills) restricted to that wallet. If cancel_ratio > 0.50 with at least one cancel in the window, every sample score in that window is halved.
Honest makers cancel occasionally (requoting when mid moves); spoofers cancel constantly (posting and pulling before fills). The clamp targets the latter without hurting normal requoting.
Distribution at 00:00 UTC
Each market's daily_budget_usdc is split across that day's scoring wallets pro-rata by daily_score:
raw_payout(w) = your_score / Σ all_scores × daily_budget_usdc
Per-wallet cap — no whale capture
A single wallet cannot claim more than 40% of a market's daily budget. This prevents one deep pocket from crowding out smaller LPs and keeps the maker set diverse.
max_share = daily_budget_usdc × 0.40
final_payout(w) = min(raw_payout(w), max_share)
Any remainder (budget not distributed because of caps) rolls into the next day's budget for that market — never lost.
Credits accumulate in a wallet-level claimable_micro_usdc — a single balance across every market you've scored on.
Claiming
Rewards are claimable on-chain. The operator relays your claim tx — you call the API, the operator submits the claim_rewards instruction on oracle-vault (Fogo), and USDC moves from the fee treasury into your proxy wallet's USDC ATA.
POST /admin/rewards/claim
X-Admin-Key: <admin key>
{
"wallet": "<bs58 fogo pubkey>",
"amount_micro_usdc": 5000000 // optional; defaults to full claimable
}
Response:
{
"claimed_micro_usdc": 5000000,
"remaining": 400000,
"signature": "5Kx8..."
}
The signature is the on-chain Fogo tx. remaining reflects the wallet's claimable_micro_usdc after the decrement. Decrement is atomic and clamps at zero.
The public self-service claim endpoint is on the near-term roadmap; today the claim is operator-relayed and requires the admin key. Market makers with active positions should contact the Parti team to schedule automated sweeps.
Endpoints
Current-day leaderboard
GET /v1/rewards/leaderboard?market_id=<hex>&day=YYYY-MM-DD
day defaults to today (UTC). Response:
{
"market_id": "abc123...",
"day": "2026-04-15",
"entries": [
{ "wallet": "4zGaxW...", "score": 42150.3 },
{ "wallet": "8vYu7k...", "score": 9880.2 }
]
}
Your claimable balance
GET /v1/rewards/wallet/{wallet}
Returns cumulative unclaimed micro-USDC across all markets:
{ "wallet": "4zGaxW...", "claimable_micro_usdc": 5400000 }
Market configs
GET /v1/rewards/config
Returns the current reward parameters for every market:
{
"configs": {
"abc123...": {
"max_spread_bps": 200,
"min_size": 100,
"daily_budget_usdc": 10000000,
"in_game_multiplier": 1.0
}
}
}
Admin-only
Set / update a market's rewards config
POST /admin/rewards/config
X-Admin-Key: <admin key>
{
"market_id": "abc123...",
"max_spread_bps": 200,
"min_size": 100,
"daily_budget_usdc": 10000000,
"in_game_multiplier": 1.0
}
Markets without a config earn no rewards. Adding a config is the switch that turns rewards on for that market.
Strategy notes
- Quote inside the gold band. The tightest 25% of
max_spreadgets a 1.5× multiplier. That's often the difference between profitable and unprofitable LP on a given market. - Ladder your depth. One 300-size quote at the best price scores less than three 100-size quotes at 10/30/60 bps — the level-decay function rewards genuine depth across the book.
- Balance your sides. Single-sided quoting gets 50% credit; balanced quoting within 20% of each other gets a 10% symmetry bonus. Skew your size down on the constrained side rather than dropping a side entirely.
- Uptime is compounding. Uptime multiplier is
uptime^0.8, so a 2-hour outage costs 8% not 8.3%. Running a hot-standby peer is cheaper than losing the multiplier. - Don't post-and-pull. Cancel-ratio > 50% in a 5-min window halves your score. If you're requoting aggressively during a move, that's fine; if you're pulling orders faster than you're getting filled, you'll lose the window.
- Caps matter for whales. Max 40% of a market's budget to any single wallet. If you're pushing the cap, splitting across two wallets only helps if both pull their weight on depth + uptime.
- Parameters change.
max_spread_bps,min_size,daily_budget, and every weight above can be tuned without notice — refreshGET /v1/rewards/configbefore each session and watch protocol announcements.
How this differs from naive quadratic distance
Simpler LP reward systems use just size × ((max_spread − distance) / max_spread)². That encourages a single tight quote and rewards wallets that only show up during sampling windows. Oracle's formula diverges on six points:
| Dimension | Naive quadratic | Oracle |
|---|---|---|
| Depth | Best order per side | All orders in band, level-decayed |
| Tightness bonus | None (smooth curve) | 1.5× inside the gold band |
| Single-sided penalty | c = 3 (33% credit) |
c = 2 (50% credit) + 10% symmetry bonus |
| Uptime | Linear | Super-linear (uptime^0.8) |
| Spoofing | Not addressed | 5-min cancel-ratio clamp (0.5× if > 50%) |
| Concentration | Pure pro-rata | 40% per-wallet cap with rollover |
Roadmap
- Public self-service
POST /v1/rewards/claim— remove the admin-key gate - Frontend leaderboard with projected payout + strategy diagnostic
- Configurable per-market
c,gold_band_mult,uptime_exponent,max_shareso markets can tune aggressiveness