Skip to content

Protocol modules

Price oracle

EIP-712 signed price batches, freshness and market-hours checks.

AevumFiOracle is a pull oracle. An authorised set of signers signs price snapshots off-chain; whoever needs a price — a trader, a liquidator, the keeper — submits the signed batch in the same transaction that uses it. The contract verifies it before any module reads a price.

A price batch#

struct PriceBatch {
    bytes32[] ids;          // bytes32("spx"), bytes32("eth"), …
    uint256[] prices;       // index points or USD, 1e18-scaled
    uint64[]  sourceTimes;  // when the venue last traded
    uint64    publishTime;  // when the signers observed it
}

Batches are signed with EIP-712 (domain AevumFi Oracle, version 1, the chain ID and the oracle's address), so one set of signatures covers every feed in the batch.

What the contract checks#

  • Signatures — at least threshold distinct authorised signers, submitted in increasing address order. The threshold starts at one and can be raised as signers are added.
  • Freshness — a batch older than 2 minutes, or more than 15 seconds in the future, is rejected. Modules are stricter: perps need a price published in the last 60 seconds.
  • Consistency — equal-length arrays, non-zero prices, and no source time after the publish time.
  • Monotonic storage — each feed keeps its newest observation; submitting an older batch doesn't overwrite it.

Separately, each consumer checks the source time to know whether a market is open: perps require the venue to have traded in the last 20 minutes, the dark pool in the last 10.

The price service#

GET /api/prices?ids=spx,eth returns the latest quotes and a signed batch.

  • Source. Quotes come from Yahoo Finance's public chart data, one symbol per feed, each checked against published closes. The same data drives the Terminal's charts through /api/history.
  • Resilience. Quotes are cached for 3 seconds. A feed that fails to load keeps its last quote with its old source time, so it reads as closed rather than fresh.
  • Sanity guard. A single-tick move larger than 20% is treated as bad data and not signed.

The signer key (ORACLE_SIGNER_PRIVATE_KEY) lives only on the server. Its address must be registered on the oracle contract at deployment.

Feeds#

34 index feeds (see perps) plus eth (ETH/USD, used by the dark pool). The live state of every feed is on the stats page.

Trust#

Whoever controls the signer keys can publish any price the checks allow — this is the protocol's largest trust assumption. See security & trust.