Skip to content

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_spread gets 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 — refresh GET /v1/rewards/config before 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_share so markets can tune aggressiveness