Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.paxeer.app/llms.txt

Use this file to discover all available pages before exploring further.

Overview

x/paxoracle stores validator-submitted market prices and exposes aggregated prices to EVM contracts through the OracleAggregator precompile at 0x0000000000000000000000000000000000000903. The module supports PaxSpot, HyperPax Perps, and other protocols that need validator-consensus price data with sub-second chain finality.

EVM precompile

interface IOracleAggregator {
    function getValidatorPrice(bytes32 marketId)
        external
        view
        returns (int256 price, uint256 quorum, uint256 timestamp);

    function submitPrice(bytes32 marketId, int256 price, uint256 confidence)
        external
        returns (bool success);
}
FieldMeaning
marketIdbytes32 market identifier, commonly keccak256("BTC/USD")
pricesigned 18-decimal fixed-point price
confidencevalidator confidence value, typically 0 < confidence <= 1e18
quorumnumber of validator attestations included in the aggregate
timestampblock timestamp or block-derived timestamp for the aggregate

Read a validator price

IOracleAggregator constant VOM =
    IOracleAggregator(0x0000000000000000000000000000000000000903);

function getBtcUsd() external view returns (int256 price, uint256 quorum) {
    (price, quorum,) = VOM.getValidatorPrice(keccak256("BTC/USD"));
}

Submit a validator price

Only active validators can submit prices. Non-validator addresses should use getValidatorPrice() for reads and should not attempt to post attestations.
IOracleAggregator constant VOM =
    IOracleAggregator(0x0000000000000000000000000000000000000903);

function submitBtcUsd(int256 price) external returns (bool) {
    return VOM.submitPrice({
        marketId: keccak256("BTC/USD"),
        price: price,
        confidence: 1e18
    });
}
submit-price.ts
import { createWalletClient, http, keccak256, parseUnits, stringToBytes } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { hyperpaxeer } from './chains'

const account = privateKeyToAccount(process.env.VALIDATOR_EVM_PRIVATE_KEY as `0x${string}`)

const wallet = createWalletClient({
  account,
  chain: hyperpaxeer,
  transport: http('https://public-rpc.paxeer.app/rpc'),
})

await wallet.writeContract({
  address: '0x0000000000000000000000000000000000000903',
  abi: [{
    type: 'function',
    name: 'submitPrice',
    stateMutability: 'nonpayable',
    inputs: [
      { name: 'marketId', type: 'bytes32' },
      { name: 'price', type: 'int256' },
      { name: 'confidence', type: 'uint256' },
    ],
    outputs: [{ name: 'success', type: 'bool' }],
  }],
  functionName: 'submitPrice',
  args: [
    keccak256(stringToBytes('BTC/USD')),
    parseUnits('97250', 18),
    parseUnits('1', 18),
  ],
})

Aggregation model

x/paxoracle verifies submissions against the active validator set, filters stale submissions, and returns a confidence-weighted median for each market.
StepDescription
Validator checkThe submitter must be an active validator
Market lookupThe marketId maps to an enabled market
Staleness filterOld attestations are excluded from the aggregate
Quorum checkThe aggregate must include enough valid submissions
MedianValid submissions are aggregated into a confidence-weighted median

Common failure modes

FailureCause
Submit revertsCaller is not an active validator
No price returnedMarket has no valid recent submissions
Quorum too lowToo few validators submitted within the freshness window
Invalid confidenceConfidence is zero or outside the accepted range
Stale aggregateSubmissions are older than the configured staleness threshold