How prices are made
Every Anyperp price is a print: the median of two signed observations of an artist's monthly listeners, taken in the same round by two independent attestation roots and verified on chain. A round opens every 15 minutes. It prints only when both observations are present, valid and within 0.5% of each other.
Rounds
Each market has its own sequence of rounds in the anyperp_oracle program.
- Open. Once 15 minutes have passed since the last round opened, anyone can open the next one with
open_round. The round accepts observations until it closes 15 minutes later. - Observe. Reporters fetch the listener count from the artist's public profile page through each root and post each root's signed observation with
submit_observation. - Finalize. Anyone can call
finalize_roundonce both observations are in. The program checks them, takes the median and writes the print. Keepers run this as part of their work.
Reporters are permissionless. An observation's validity comes from the root's signature, which the program verifies; who submits it doesn't matter.
The two roots
| Root | Signer | Verified with |
|---|---|---|
| Root 1 | a Reclaim attestor, identified by its Ethereum-style address | Solana's secp256k1 signature precompile |
| Root 2 | an independent notary run by a separate operator | Solana's Ed25519 signature precompile |
Each root signs a claim that binds every field the price depends on: the oracle program, the metric and the hash of its spec, the round and its sequence number, the root, the listener count, the time it was fetched and the source's own timestamp. submit_observation accepts an observation only when:
- the signature verifies in the same transaction and comes from a key in that root's allowlisted set, valid at the fetch time;
- the fetch time and the source time both fall inside the round's 15-minute window, with the source time no later than the fetch time;
- the round has no observation from that root yet.
Root keys rotate only through the curators: three curator votes schedule a rotation, which takes effect after a 48 h timelock. Every observation keeps the signer it was made with, so past rounds remain checkable after a rotation.
Tolerance and the median
A round prints when its two observations and agree within the tolerance of 0.5% of the smaller one:
The print is their median, which for two values is their average, divided by the market's index divisor :
For example, root 1 reads 60,120,000 and root 2 reads 60,000,000. They are 120,000 apart, within 0.5% of 60,000,000 (300,000), so the round prints a median of 60,060,000 listeners; with an index divisor of 100,000 that is an index of 600.60. If root 2 had read 59,600,000 instead, the two would be 520,000 apart, more than 0.5% of 59,600,000 (298,000), and the round would not print.
Both observations must also be fetched later than those of the previous print, so a print never reuses older readings.
Round states
| State | Meaning |
|---|---|
open | accepting observations |
awaiting_roots | one root has posted; waiting for the other |
finalized | printed |
disputed | both roots posted but disagree beyond tolerance, or their times fall outside the round; no print |
out_of_band_pending | the median is beyond the circuit band; held until later rounds confirm the level |
failed | the round closed with a root missing; no print |
A round with no print, disputed or failed, pauses opens on both sides of the market until the next print, for up to 6 h after the latest such round. Closes, margin additions and claims continue.
The circuit band and side pauses
Each print is compared with the market's hourly close from 24 h earlier. A print more than 10% away from it is held as out_of_band_pending:
While the level is held, opens pause on the side of the move for up to 6 h: a move up pauses new longs, a move down pauses new shorts. The level prints once enough consecutive rounds agree on it, within tolerance and in the same direction, to meet the market's confirmation count of at least two rounds, the first included. When it prints, the pause lifts.
For example, a market whose hourly close 24 h ago was 600.00 prints anywhere from 540.00 to 660.00 at once. A median of 670.00 is held, and new longs pause, until later rounds confirm it.
Price history
Each print also updates the market's hourly close: the last print in each hour. The oracle keeps the last 168 hourly closes, a week, on chain. They are the reference for the circuit band, the chart on each market page ("Index, hourly closes for a week") and the source of the settlement price if a market halts.
Reading rounds in the app
The Recent rounds panel on each market page lists the latest rounds:
| Column | What it shows |
|---|---|
| Round | the round's sequence number |
| State | the round state |
| Root 1, Root 2 | each root's listener count |
| Apart | how far apart the two readings are |
| the index the round printed, or "pending" or "no print" | |
| Signatures | per observation: the root, the signature algorithm, its verification, the signer, the fetch time, the time the round opened and the signature |
The Data page and the attested series
The Data page publishes the attested series for every listed artist, free to read. "Compare two artists" puts any two artists side by side, each rebased to 100 at the start of the window, so a trend or a spread reads at a glance. "Every subject" lists each artist's latest attested value, when it was attested, and the share of rounds on which both roots agreed.
The same data is in the API without signing in: /v1/attested/subjects, /v1/attested/subjects/:subjectId/series for an artist's daily series, and /v1/attested/compare for two artists aligned, raw or rebased to 100 (API).