Axiom Query Protocol

How Axiom trustlessly fulfills queries.

The Axiom V2 Query protocol consists of the following smart contracts:

  • AxiomV2Query: the primary smart contract for accepting and fulfilling user queries.

  • AxiomV2Prover: smart contract to manage permissions around who can submit ZK proofs to fulfill queries.

  • AxiomV2HeaderVerifier: smart contract for verifying the block hashes used in ZK proofs are valid against the block hash cache maintained by AxiomV2Core.

  • AxiomResultStore: smart contract that stores the results of queries into AxiomV2Query.

AxiomV2Query

AxiomV2Query uses AxiomV2Core to fulfill queries made by users into Axiom V2. AxiomV2Query follows the Axiom V2 Query Format and supports:

  • On-chain query requests with on- or off*-chain data availability for queries and on-chain payments or refunds. (*Off-chain data availability not yet supported in the testnet release.)

  • On-chain fulfillment of queries with on-chain proof verification.

For full details of the Axiom V2 Query format, see the following page:

pageAxiom Query Format

Initiating queries on-chain

Users can initiate a query on-chain with on-chain payment. Both on- and off-chain data availability are supported for the data query:

  • sendQuery: Send an on-chain query with on-chain data availability.

  • sendQueryWithIpfsData: Send an on-chain query with data availability on IPFS.

    • This is not yet supported in the testnet release.

On-chain queries are identified by queryId as specified in the Axiom V2 Query Format. For each query, AxiomQueryMetadata in queries[queryId] stores the relevant metadata, consisting of:

  • state (AxiomQueryState): One of Inactive, Active, Fulfilled, or Paid.

  • deadlineBlockNumber (uint32): The block number after which the query is eligible for a refund.

  • payee (address): Once fulfilled, the address payment is due to.

  • payment (uint256): The payment amount, in gwei, escrowed for this query.

Query fulfillment

Query fulfillment is permissioned to the PROVER_ROLE, which is initialized to an AxiomV2Prover contract to manage proving permissions for safety at the moment. There are two ways the PROVER_ROLE can fulfill queries:

  • fulfillQuery: Fulfill an existing on-chain query.

  • fulfillOffchainQuery: Fulfill a query which was initiated off-chain.

These functions take in a ZK proof verifying a query and fulfill the query by:

  • verifying the ZK proof on-chain

  • checking the block hashes used in the ZK proof (in the form of a Merkle mountain range) are validated against the cache in AxiomV2Core using AxiomV2HeaderVerifier

  • for on-chain queries: checking that the query that was just verified corresponds to query originally requested on-chain, by matching the queryHash

  • calling the desired callback

Fees and permissions

All fees are charged in ETH. User balances are maintained in the balances mapping.

  • To deposit, users can use deposit or transfer ETH together with their on-chain query.

  • To withdraw, users can use withdraw.

The fee for each query is determined by:

  • maxFeePerGas (uint64): The max fee to use in the fulfillment transaction.

  • callbackGasLimit (uint32): Gas limit allocated for use in the callback.

Each on-chain query will escrow a max payment of

maxQueryPri = maxFeePerGas * (callbackGasLimit + proofVerificationGas) + axiomQueryFee;

where

  • proofVerificationGas: Gas cost of proof verification, currently set to 500_000

  • axiomQueryFee: Fee charged by Axiom, fixed to 0.003 ether

To increase gas parameters after making a query, anyone can add funds to a query with increaseQueryGas.

Upon fulfillment, the maxQueryPri fee is released to the prover, who can call unescrow to claim payment.

  • The prover can refund the portion of maxQueryPri not used in gas or the axiomQueryFee to the original query caller.

  • If the query is not fulfilled by deadlineBlockNumber, the caller can retrieve their fees paid using refundQuery

AxiomV2Prover

AxiomV2Prover manages permissions for fulfillQuery and fulfillOffchainQuery calls into AxiomV2Query. These calls are restricted to:

  • accounts holding the PROVER_ROLE, initially anticipated to be controlled by the Axiom team

    • The PROVER_ROLE is currently limited to guard against exploits of the Axiom ZK circuits. In the event that a ZK circuit is found to be under-constrained, this prevents exploits by malicious provers who could use this to prove inaccurate results to Axiom queries. As the ZK circuit codebase matures, we intend to remove this permissioning.

  • additional accounts permissioned for each (querySchema, target) pair, tracked in the allowedProvers mapping

All calls to AxiomV2Prover are forwarded to AxiomV2Query.

AxiomV2HeaderVerifier

AxiomV2HeaderVerifier verifies that a Merkle mountain range proofMmr of block hashes is committed to by block hashes available to AxiomV2Core in verifyQueryHeaders. This happens by comparing proofMmr to:

  • the padded Merkle mountain ranges committed to in pmmrSnapshots and blockhashPmmr

  • the block hashes available in the EVM via the BLOCKHASH opcode

AxiomResultStore

AxiomResultStore stores results from queries into Axiom V2, indexed by queryHash. We store these in the mapping results, where results[queryHash] stores

resultHash = keccak(sourceChainId . dataResultsRoot . dataResultsPoseidonRoot . computeResultsHash)

Last updated