🚧 SportsPerp is currently live on devnet. Mainnet target: before Jun 12, 2026 (World Cup kickoff).
RisksOracle Manipulation

Oracle Manipulation

The oracle is the protocol’s contact point with the outside world. A manipulated oracle → manipulated mark price → manipulated PnL → manipulated liquidations. This is the single highest-impact attack surface in perpetual futures protocols, and SportsPerp has specific mitigations.

The attack

An attacker succeeds at oracle manipulation if they can cause oracle_price to deviate materially from the true OBV Index for long enough to extract value before defenses engage.

Three attack models:

  1. Key compromise. The admin keypair signing update_oracle is stolen or coerced.
  2. Data-source manipulation. The upstream data partner’s data is corrupted or the feed is spoofed.
  3. Timing attack. An attacker is not the oracle but can observe a push and front-run it with transactions that benefit from the imminent price change.

Each is handled differently.

Mitigation: layered by design

No single mitigation is sufficient. Six layers stack:

1. Composite mark ≠ raw oracle

The oracle is one of two inputs to the mark price. The vAMM contributes 50% (during live matches) to 70% (between matches). See Mark Price.

Even if an attacker controls the oracle, they must simultaneously manipulate the vAMM — which requires real open-interest imbalance backed by real USDC — to move the mark materially. The vAMM impact factor is 0.1% per full OI imbalance, so moving the mark 1% requires either:

  • 1% oracle manipulation + no vAMM manipulation (50–70% attenuated), or
  • 10× vAMM imbalance at max (economically expensive) on top of oracle manipulation.

2. 150-second EMA smoothing

Even after composite, the mark price is smoothed with a 150-second EMA. A single manipulated oracle push is blended at ~18% weight on the first crank cycle and takes ~10 minutes to fully propagate. Liquidations firing on the manipulated value must happen within a narrow window before the EMA fights back.

3. Confidence-based leverage throttling

If the oracle publishes with wide confidence (> 800 bps), max leverage automatically drops to 0.4×. At > 1000 bps, trading halts entirely. An attacker who pushes a wide-confidence value is deliberately trading their own ability to exploit it.

4. TWAP funding over the 8-hour interval

Funding rate is computed from a TWAP of premium samples accumulated over each 8-hour interval. To move the funding rate against open positions, an attacker has to sustain the dislocation across most of the interval — materially harder than a single-block attack. (Note: the on-chain math is a plain mean of accumulated samples; outlier rejection is not currently implemented and is tracked as a potential future hardening.)

6. Anti-manipulation liquidation floor

Profitable positions cannot be liquidated unless they’ve lost ≥ 18.3% of collateral vs their last margin transfer. An attacker who manipulates the oracle to briefly flip a profitable position into a margin-ratio violation still cannot liquidate it — the profitability check protects it. See Three-Layer Cascade.

This is the dedicated defense against “oracle spike → quick liquidation → revert oracle” attacks that have happened on other protocols.

Specific attack scenarios

Scenario: single admin-key push manipulates mark by 3%

  • Oracle pushed at 530 when true value is 515 (+2.9%).
  • Composite mark (between matches): 30% × 530 + 70% × vAMM. If vAMM ≈ 515, composite ≈ 519.5 — only 0.87% dislocated.
  • EMA over 150s: initial move is 18% of that delta → ~0.16% effective mark move.
  • Any attempt to open a position at the dislocated mark hits the 5% premium check (would fail only if vAMM is also dislocated, which requires real USDC).
  • Any attempt to liquidate a profitable position hits the 18.3% anti-manip floor.

Net attacker extraction: essentially zero without a coordinated vAMM manipulation that costs more than the manipulation profits.

Scenario: data-partner feed is compromised upstream

A bad actor gains access to the partner’s publishing pipeline (improbable) and publishes incorrect OBV values. The crank propagates these, the oracle pushes them, the mark follows.

Defenses:

  • The live overlay pipeline validates per-event OBV deltas against sanity ranges; outliers are rejected.
  • Multi-source oracle (built, pending deploy) uses a second data source — a different vendor or an internally-computed backup — so that a single vendor’s compromise doesn’t reach the chain.
  • Monitoring alerts fire on any single-update index move > 10%.

For mainnet, this scenario is the primary reason the multi-source oracle is a launch gate.

Scenario: front-running a price push

An attacker observes a pending update_oracle transaction in the mempool and sends a trade that benefits from the imminent change.

This is possible but limited: position opens go through at the current mark EMA (not the about-to-update mark), and closes realize PnL at the mark EMA at block time. The attacker’s open is priced at the pre-update EMA, so they haven’t yet benefited from the push. When the push lands, EMA incorporates it gradually, and the attacker has one crank cycle to close and capture the delta.

In practice, this is “normal market behavior” — the trader who sees a data update coming and trades on it is the trader who pays closer attention. It’s not exploitable unless the attacker has sustained privileged information about oracle timing, which they wouldn’t with a decentralized multi-source oracle.

Where multi-source comes in

Everything above holds for the single-source admin oracle running today. Multi-source 2-of-N weighted median consensus — already built as oracle-pusher/multi-oracle.mjs — replaces the admin-key trust point with cryptographic consensus.

Under multi-source:

  • At least 2 independent pushers must agree (within tolerance) for a price to land on-chain.
  • Each pusher has an independent key, independent host, independent data source. Compromising one doesn’t move the consensus.
  • Weighted median defaults to equal weights at launch; reputation weighting can be added post-launch based on accuracy history.

Multi-source is a mainnet launch gate. See Oracle Design and Roadmap → Devnet to Mainnet.

Residual risk

Even with all six mitigations, a coordinated attack by an adversary with:

  • Admin-key compromise AND
  • Large USDC war chest to move the vAMM AND
  • Time and patience to sustain dislocation past the TWAP window AND
  • Willingness to accept transaction costs exceeding probable gains

…is not fully defeated, only made uneconomical. Perfect oracle security is not achievable; economic security is.

How traders can observe oracle health

Every trader can check oracle state on-chain without needing to trust our monitoring:

const market = await client.getMarket(marketId);
const age = Date.now() / 1000 - market.oracleTimestamp;
 
if (age > 7200) console.log("Oracle stale — trading paused");
if (market.oracleConfidenceBps > 1000) console.log("Oracle uncertainty — trading blocked");
// Mark-vs-oracle divergence is informational only — useful for understanding
// liquidation-eligibility behaviour during fast moves. It is not an
// on-chain trade-rejection gate.
const divergencePct =
  Math.abs(market.markPriceEma - market.oraclePrice) / market.oraclePrice;
if (divergencePct > 0.05) {
  console.log(`Mark/oracle divergence ${(divergencePct * 100).toFixed(2)}%`);
}

These are public signals. The protocol doesn’t require trusting our dashboards.

Further reading