Pour les développeurs / Actifs réels

Comment un prix se forme

Deux méthodes d'agrégation, un seul publieur. L'arithmétique ci-dessous rend un prix robuste au mauvais comportement d'une place ; ce n'est pas elle qui le rend digne de confiance. Cela, c'est la dernière section, et c'est celle à lire avant de liquider quoi que ce soit sur ces nombres.

D'où vient un prix

Thirteen feeds are aggregated from five public spot venues, each subscribed with that venue's own product id. The other twenty have no venue leg and come from Pyth Network's Hermes service alone.

SourceQuoi
Places au comptantCoinbase, Kraken, Bitstamp, Gemini, Bitfinexchacune abonnée avec l'identifiant de produit propre à cette place, pris dans le catalogue
Seconde sourcePyth Network, via son service Hermesla seule source pour les vingt flux sans jambe de place, et un contrôle croisé pour les treize autres

Les deux méthodes échouent différemment, et un consommateur a besoin des deux comportements. Un flux adossé à des places survit à une place qui s'éteint, parce que la médiane est prise sur cinq et que chacune porte sa propre fraîcheur. Un flux à source unique ne peut pas survivre à l'indisponibilité de sa source, et le dit plutôt que de deviner.

Quand une place compte

Chaque place est évaluée seule avant que quoi que ce soit ne soit combiné. Les règles sont appliquées dans cet ordre, et la première qui échoue retire la place de la médiane pour cette évaluation :

RègleSeuil
Connection statemust be onlinea venue whose socket is down is never fresh, whatever its last quote said
Quote age10 smeasured on a MONOTONIC receive clock, never on the exchange's timestamp or the host's wall clock
Delivery lag5 s either waya timestamp trailing its receipt means the socket is replaying a backlog; one leading it means the venue dates quotes in the future. The whole venue sits out rather than falling through to its last trade
Spread50 bpsthe mid is used when the book is uncrossed and tighter than this
Last trade60 sthe fallback when no usable mid exists, inside its own longer window
La fraîcheur est jugée sur une horloge monotone

Pas sur l'horodatage de la place, et pas sur l'horloge murale de l'hôte. Une place dont l'horloge avance ou retarde ne peut pas faire passer sa propre cotation pour fraîche, et un hôte dont l'horloge saute ne peut pas invalider toutes les places d'un coup. L'horodatage de la place ne sert qu'à une chose : le contrôle du délai de livraison, qui le compare au moment de la réception dans les deux sens.

Le meilleur bid et le meilleur ask sont préférés quand le carnet est récent, non croisé et plus serré que la limite d'écart. Sinon la dernière transaction prend le relais, dans sa propre fenêtre plus longue. Une place dont le socket rejoue un arriéré est retirée entièrement plutôt que de retomber sur sa dernière transaction, parce que cette transaction est en retard d'autant.

La médiane

  1. Evaluate every venue against the rules above and keep the fresh ones.
  2. If fewer than minSources are fresh, publish nothing and report the reason - no_sources when none is fresh, too_few_sources otherwise. Nothing thin is ever published.
  3. Take the median of what survives.
  4. If the spread between the included venues exceeds 200 bps and dropping one would still leave minSources, drop the venue furthest from the median - on a tie the older observation - and take the median again. At most one venue is dropped.
  5. Round half-even to the feed's decimals. The result is an integer, not a float.
  6. Date the aggregate with the NEWEST included quote, capped at the current wall clock so no venue with a fast clock can date a median into the future.

degraded is set when the median rested on exactly minSources venues: still published, one drop-out from silence.

Un flux trop mince ne publie rien plutôt que quelque chose

minSources est propre à chaque flux, et vaut 3 sur chaque flux adossé à des places. En dessous, il n'y a aucune réponse du tout : aucune dernière valeur connue n'est republiée sur la chaîne, le tour n'avance pas et updatedAt cesse de bouger. Le service rapporte encore la dernière bonne réponse comme lastKnown à des fins de diagnostic, et ce champ n'est explicitement pas un prix sur lequel traiter.

L'agrégat est daté de la cotation incluse la plus récente, plafonnée à l'horloge murale courante. Les deux moitiés comptent : une place dont la dernière transaction, vieille de soixante secondes, a remplacé un carnet périmé ne doit pas dater une médiane dont les autres entrées sont infra-secondes, et aucune place à l'horloge en avance ne peut pousser une heure d'observation dans le futur - où le contrat la sauterait comme raison 4.

Contrôle croisé et remplacement

An exchange-backed feed that also has a Pyth leg is cross-checked against it on every evaluation. Within 100 bps the two are recorded as agreeing; beyond it the feed is marked diverged and the dispersion flag is raised.

When the venues go stale, Pyth may stand in for them - but only if the two agreed recently and are not diverging now. A feed publishing from the stand-in is marked degraded and its source reads pyth rather than exchanges-median, so a consumer can tell. If they are diverged and Pyth is fresh, the feed publishes nothing and reports cross_check_diverged.

Deux champs l'exposent. crossCheckBps est la distance actuelle entre les deux méthodes, et source dit laquelle a produit le tour que vous détenez - 1 pour la médiane des places, 2 pour la seconde source. Un flux dont la source a changé reste un prix valide, produit autrement ; si cela compte pour votre produit, surveillez le champ plutôt que de l'inférer.

La seconde source

Chaque mise à jour de la seconde source passe ces contrôles avant d'être éligible à devenir un prix. Une mise à jour rejetée incrémente un compteur par raison, visible flux par flux sur les routes de source et d'audit du service :

ContrôleLimite
Exponentpinned on the first updateany later drift is rejected, so a silent rescaling cannot pass
Slot and publish timemust advancean update that does not move them forward is dropped
Future tolerance5 sa publish time further ahead than this is rejected
Confidence50 bps crypto and index, 30 equity, 10 commodity and fxthe reported confidence interval as a fraction of the price; wider is rejected
EMA band10 % crypto and index, 5 % elsewherea jump away from the exponential moving average needs a SECOND sample within 100 bps of the first before it is used. A lone spike is dropped
Freshness10 s since receipt, 30 s publish lagboth measured at receipt on the monotonic clock

Sans l'identifiant, vingt des trente-trois flux se taisent

The upstream needs a credential. Without one it answers unauthorised and every feed with no venue leg stays unpublished - twenty of the thirty-three, which is the whole real-world set plus XMR/USD.

The thirteen exchange-backed feeds continue: they are computed from public venues and need no credential. What they lose is the cross-check and the stand-in, since neither can be established without a Pyth price to compare against. Readiness reports this as a warning rather than a failure, so the service looks healthy while two thirds of the catalog is silent - check the per-feed status, not the service's.

Le contrôle d'exposant est le discret et le plus important. L'échelle d'une mise à jour est figée dès la première authentifiée et toute dérive ultérieure est refusée d'emblée, parce qu'un changement d'échelle silencieux est un prix faux d'une puissance de dix qui a l'air parfaitement bien formé.

Comment il atteint la chaîne

  1. The aggregating service holds no signing key at all. It computes prices and serves them on an internal port.
  2. The node's publisher polls that port, authenticates the body with a shared HMAC of the exact bytes, and re-checks every item against on-chain state before signing - mirroring the contract's own skip rules so a bad item costs a counter rather than gas.
  3. The batch is written as ONE system transaction per EVM block, signed by the publisher key, which lives in the node's process and is used by nothing else in it.
  4. The service then reads its own result back off the chain and reports it, which is what the onchain field of every FeedView is.

At most 64 feeds go into one batch by default, and the contract's own maxBatch caps it again. A batch older than 2 s is not published.

La division du travail est le point. Tout ce qui est lent ou faillible - l'interrogation, l'authentification, la lecture du catalogue, la sélection, l'encodage, la signature et l'ajout au journal d'écriture anticipée - se passe hors du chemin de scellement, qui reçoit une transaction finie et l'applique au prix de n'importe quelle autre transaction. Et parce que le publieur revérifie chaque élément contre l'état on-chain avant de signer, en reproduisant les règles de saut du contrat, un agrégateur qui envoie quelque chose de mauvais coûte un compteur plutôt qu'un tour.

Le modèle de confiance

A price is as trustworthy as the operator that produces blocks, and no more. The publisher is the block producer.

  • One party operates the node, holds the publisher key and orders transactions. A price inherits exactly the assumption that already governs ordering.
  • Nothing on chain arbitrates a price. There is no second publisher, no dispute window and no slashing: the contract checks that an item is well formed, positive, not from the future and not older than the feed's last observation, and then writes it.
  • The owner role can add a feed, change a feed's policy, rotate the publisher and adjust the batch and tolerance parameters. Ownership transfer is two-step. Those are the only write paths that are not the publisher's.
  • Splitting the key from the computation limits one failure, not the other: compromising the aggregating service lets an attacker propose prices, and every one is still re-checked and signed by the node. Compromising the node is the end of the argument.
  • If you liquidate on these prices, that is the assumption you are taking, and it is the one to state to your own users.

Rien de ce qui précède n'y change quoi que ce soit. Les règles de place, la médiane, le rejet des valeurs aberrantes et le contrôle croisé rendent un prix robuste au mauvais comportement d'une source, ce qui est un échec réel et courant. Ils ne font rien contre la partie qui signe. Lisez-les comme des contrôles de qualité, pas comme un consensus.

La conséquence pratique pour un intégrateur : ces prix conviennent à un produit dont les utilisateurs savent qui les produit, et ils portent la même hypothèse que l'ordonnancement de vos propres transactions - donc si vous acceptez déjà cette hypothèse pour utiliser la chaîne tout court, consommer les flux n'en ajoute aucune. Si votre conception a besoin d'un prix qu'aucune partie unique ne peut forger, cette couche ne le fournit pas et aucun paramètre ne l'y amènera.