Contract Specifications
Specifications shared by every SportsPerp market. Per-market parameters (funding interval, max leverage, fees) can be tuned via the update_market_params admin instruction; the values below are the defaults that markets ship with.
Trading
| Parameter | Value | Notes |
|---|---|---|
| Position types | Long / Short | Symmetric — no asymmetric funding |
| Collateral | USDC (SPL) | Devnet mint: B5Etber6bZGm1H5VXcoerF6eWLkBd157heJS8pBtHrNo |
| Min position size | 10 USDC | MIN_POSITION_SIZE = 10_000_000 at 10⁶ scale |
| Max position size | 50% of effective_oi (tier-5 hard cap) | Single-position concentration cap. effective_oi = max(market_total_oi, initial_capacity) |
risk_floor | Admin-set per-protocol gate on the global liquidity pool | Below it, open_position and LimitOpen revert with RiskFloorBreached. Closes / SL / TP / cancels / margin-passing collateral withdraws are not gated. Surfaced in the trader UI as “Opening paused: pool liquidity below risk floor” |
target_balance | Off-chain monitoring threshold for the global liquidity pool | [warning] Telegram alert at pool < 2× target_balance, [error] at < 1.25× target_balance. Not enforced on-chain |
initial_capacity | Admin-set per-market floor for the margin-tier denominator | Defaults: $50K teams, $10K players. Floors effective_oi so fresh markets don’t fall through to full leverage |
| Max leverage (base) | 5x | Reduced per Margin Tiers as position grows |
| Taker fee | 10 bps (0.1%) | Paid to protocol on position open/close |
| Maker fee | 5 bps (0.05%) | For future limit-book orders |
| Trigger orders per user per market | 10 max | MAX_ORDERS_PER_MARKET = 10 |
Funding
| Parameter | Value |
|---|---|
| Funding interval | 8 hours |
| Max funding rate per period | ±0.1% (10 bps) |
| TWAP sample collection | Premium sample appended on every update_oracle (typically dozens per 8h window) |
| TWAP aggregation | Plain mean of accumulated samples since last apply_funding |
| Execution | Permissionless — anyone can crank apply_funding |
Full detail: Funding Rate.
Liquidation
| Parameter | Value | Constant |
|---|---|---|
| Maintenance margin | 20% | MAINTENANCE_MARGIN_BPS = 2000 |
| Layer 1 (partial) threshold | margin ≤ 20%, > 13.33% | — |
| Layer 2 (backstop) threshold | margin ≤ 13.33% | BACKSTOP_THRESHOLD_BPS = 1333 (2/3 of maintenance) |
| Partial liquidation close size | 20% of position | PARTIAL_LIQUIDATION_FRACTION_BPS = 2000 |
| Cooldown between partials | 30 seconds | PARTIAL_LIQUIDATION_COOLDOWN = 30 |
| Layer 1 liquidator reward | 5% of closed collateral | LAYER1_REWARD_BPS = 500 |
| Layer 2 liquidator reward | 3% of closed collateral | LAYER2_REWARD_BPS = 300 |
| Insurance allocation | 50% of remaining collateral | INSURANCE_ALLOCATION_BPS = 5000 |
| Backstop unwind chunk | 10% of absorbed position per call | MAX_UNWIND_FRACTION_BPS = 1000 |
| Anti-manipulation threshold | Profitable positions protected unless lost ≥ 18.3% vs last margin transfer | 1830 bps hard-coded in partial_liquidate.rs:62 |
Full detail: Liquidations.
Mark price
| Parameter | Value | Constant |
|---|---|---|
| Oracle weight (live match) | 50% | DEFAULT_ORACLE_WEIGHT_LIVE_BPS = 5000 |
| Oracle weight (between matches) | 30% | DEFAULT_ORACLE_WEIGHT_BETWEEN_BPS = 3000 |
| vAMM impact factor | 0.1% | DEFAULT_VAMM_IMPACT_FACTOR = 1000 |
| EMA half-life | 150 seconds | EMA_HALF_LIFE = 150 |
Full detail: Mark Price.
Oracle
| Parameter | Value |
|---|---|
| Feed count | 68 (20 teams + 48 players) |
| Crank interval | 5 minutes (tightened to 0.1% threshold during live matches) |
| Staleness limit | 2 hours — trades rejected if oracle data older |
| Confidence interval — teams | 300–800 bps |
| Confidence interval — players | 400–1000 bps |
| Confidence-based leverage scaling | 1.0x / 0.8x / 0.6x / 0.4x / 0 (blocked) across confidence bands |
| Sunset trigger | Oracle stale > 72 hours — permissionless sunset_market callable |
Full detail: Oracle Design · Market Lifecycle.
Insurance Fund
| Parameter | Value |
|---|---|
| Current balance | 20,000 USDC |
| Target balance | 10,000 USDC |
| Max backstop exposure | 50,000 USDC |
| Replenishment | 50% of each liquidation’s remaining collateral |
Full detail: Insurance Fund.
Fixed-point scales
All on-chain arithmetic uses integer fixed-point — no floats, ever. The scales are:
| Quantity | Scale | Example |
|---|---|---|
| Prices (oracle, mark, entry) | 10⁶ | Index value 500 → stored as 500_000_000 |
| Collateral / size (USDC) | 10⁶ | 100 USDC → 100_000_000 |
| Leverage | 10² | 5x → 500, 2x → 200 |
| Funding accumulators | 10¹² | High precision for cumulative rate tracking |
| Basis points | 10⁴ | 100% → 10000 |
SDK math in sdk/src/math/ mirrors Rust math in programs/obv-perps/src/math/ bit-for-bit. A price or PnL computed in TypeScript will equal the one the program computes, to the last integer unit.
Instruction surface
The on-chain program exposes 30 instructions across trading, partial-close, triggers, oracle, funding, liquidation, market lifecycle, insurance administration, and liquidity-pool administration. See Program Instructions Reference for the full surface.
Further reading
- Margin — initial margin, maintenance margin, effective collateral.
- Margin Tiers — how max leverage scales with position size.
- Order Types — market, stop-loss, take-profit, limit-open.