개발자를 위한 문서 / 실물 자산
가격이 만들어지는 방식
집계 방법은 둘, 발표자는 하나입니다. 아래의 산술은 거래소 하나가 잘못 굴어도 가격이 견디게 만드는 것이지, 가격을 믿을 만하게 만드는 것이 아닙니다. 그것은 마지막 절이며, 이 숫자로 무엇을 청산하기 전에 읽어야 할 절입니다.
가격은 어디서 오는가
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.
| 소스 | 무엇 |
|---|---|
| 현물 거래소 | Coinbase, Kraken, Bitstamp, Gemini, Bitfinex각각 카탈로그에서 가져온 그 거래소 자신의 상품 id로 구독합니다 |
| 두 번째 소스 | Pyth Network, Hermes 서비스를 통해거래소 다리가 없는 스무 개 피드의 유일한 소스이며, 나머지 열세 개에는 교차 확인입니다 |
두 방법은 다르게 실패하며, 소비자에게는 두 동작이 모두 필요합니다. 거래소가 뒷받침하는 피드는 거래소 하나가 꺼져도 살아남습니다. 중앙값을 다섯 곳에 걸쳐 취하고 각각이 자기 신선도를 갖기 때문입니다. 단일 소스 피드는 자기 소스를 쓸 수 없게 되면 살아남지 못하며, 추측하는 대신 그렇다고 말합니다.
거래소가 세어지는 조건
각 거래소는 무엇이 합쳐지기 전에 저마다 따로 평가됩니다. 규칙은 이 순서로 적용되며, 처음 실패하는 규칙이 그 평가에서 해당 거래소를 중앙값 밖으로 밀어냅니다.
| 규칙 | 임계값 |
|---|---|
| Connection state | must be onlinea venue whose socket is down is never fresh, whatever its last quote said |
| Quote age | 10 smeasured on a MONOTONIC receive clock, never on the exchange's timestamp or the host's wall clock |
| Delivery lag | 5 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 |
| Spread | 50 bpsthe mid is used when the book is uncrossed and tighter than this |
| Last trade | 60 sthe fallback when no usable mid exists, inside its own longer window |
거래소의 타임스탬프도 아니고 호스트의 벽시계도 아닙니다. 시계가 빠르거나 느린 거래소는 자기 호가를 신선해 보이게 만들 수 없고, 시계가 튀는 호스트는 모든 거래소를 한꺼번에 무효로 만들 수 없습니다. 거래소 타임스탬프는 딱 한 가지에만 쓰입니다. 그것을 수신 시각과 양방향으로 비교하는 전달 지연 검사입니다.
호가창이 최근이고 교차하지 않았으며 스프레드 한도보다 좁을 때는 최우선 매수 호가와 매도 호가를 씁니다. 그렇지 않으면 자기만의 더 긴 창 안에서 마지막 체결이 대신 섭니다. 소켓이 밀린 것을 재생하고 있는 거래소는 마지막 체결로 떨어지는 대신 통째로 빠집니다. 그 체결도 같은 만큼 늦었기 때문입니다.
중앙값
- Evaluate every venue against the rules above and keep the fresh ones.
- 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.
- Take the median of what survives.
- 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.
- Round half-even to the feed's decimals. The result is an integer, not a float.
- 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.
얇은 피드는 무언가를 내놓는 대신 아무것도 발표하지 않습니다
minSources는 피드마다 다르며, 거래소가 뒷받침하는 모든 피드에서 3입니다. 그 아래에서는 답이 아예 없습니다. 마지막으로 알려진 값이 온체인에 다시 발표되지 않고, 라운드는 나아가지 않으며, updatedAt은 움직이기를 멈춥니다. 서비스는 진단을 위해 마지막으로 좋았던 답을 lastKnown으로 계속 보고하며, 그 필드는 명시적으로 거래에 쓸 가격이 아닙니다.
집계값에는 포함된 호가 중 가장 새로운 것의 시각이 붙고, 현재 벽시계로 잘립니다. 두 반쪽 모두 중요합니다. 낡은 호가창을 대신해 선 60초 된 마지막 체결이, 다른 입력이 1초도 되지 않은 중앙값에 시각을 붙여서는 안 됩니다. 그리고 시계가 빠른 어떤 거래소도 관측 시각을 미래로 밀 수 없어야 합니다. 그랬다면 컨트랙트가 그것을 이유 4로 건너뛸 것입니다.
교차 확인과 대체
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.
두 필드가 이것을 드러냅니다. crossCheckBps는 두 방법 사이의 현재 거리이고, source는 지금 들고 있는 라운드를 어느 쪽이 만들었는지 말해 줍니다 - 거래소 중앙값이면 1, 두 번째 소스면 2입니다. source가 바뀐 피드도 여전히 유효한 가격이며, 다른 방식으로 만들어졌을 뿐입니다. 그것이 제품에 중요하다면 추론하지 말고 그 필드를 지켜보십시오.
두 번째 소스
두 번째 소스에서 오는 모든 업데이트는 가격이 될 자격을 얻기 전에 이 검사들을 통과합니다. 거부된 업데이트는 이유별 카운터를 올리며, 서비스의 소스와 감사 라우트에서 피드별로 볼 수 있습니다.
| 검사 | 한도 |
|---|---|
| Exponent | pinned on the first updateany later drift is rejected, so a silent rescaling cannot pass |
| Slot and publish time | must advancean update that does not move them forward is dropped |
| Future tolerance | 5 sa publish time further ahead than this is rejected |
| Confidence | 50 bps crypto and index, 30 equity, 10 commodity and fxthe reported confidence interval as a fraction of the price; wider is rejected |
| EMA band | 10 % 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 |
| Freshness | 10 s since receipt, 30 s publish lagboth measured at receipt on the monotonic clock |
자격 증명이 없으면 서른세 개 중 스무 개의 피드가 침묵합니다
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.
지수 검사는 조용하면서 가장 중요한 검사입니다. 업데이트의 스케일은 처음 인증된 것에서 고정되고 이후의 어긋남은 곧바로 거부됩니다. 조용한 재스케일링은 완전히 멀쩡해 보이면서 열 배수만큼 틀린 가격이기 때문입니다.
체인에 닿는 방식
- The aggregating service holds no signing key at all. It computes prices and serves them on an internal port.
- 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.
- 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.
- 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.
분업이 핵심입니다. 느리거나 실패할 수 있는 모든 것 - 폴링, 인증, 카탈로그 읽기, 선택, 인코딩, 서명, 그리고 미리 쓰기 로그 추가 - 은 봉인 경로 바깥에서 일어나고, 봉인 경로는 완성된 트랜잭션을 받아 다른 어떤 트랜잭션과 같은 비용으로 적용합니다. 그리고 발표자가 서명하기 전에 모든 항목을 온체인 상태와 다시 대조하며 컨트랙트 자신의 건너뛰기 규칙을 그대로 따르므로, 집계자가 나쁜 것을 보내도 드는 값은 라운드가 아니라 카운터입니다.
신뢰 모델
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.
위의 어느 것도 그것을 바꾸지 않습니다. 거래소 규칙, 중앙값, 이상치 제거, 교차 확인은 소스가 잘못 구는 것에 대해 가격을 견디게 만들며, 그것은 실제로 흔한 실패입니다. 서명하는 쪽에 대해서는 아무 일도 하지 않습니다. 합의가 아니라 품질 관리로 읽으십시오.
통합하는 쪽에 주는 실질적 결론은 이렇습니다. 이 가격들은 누가 그것을 만드는지 사용자에게 알려 주는 제품에 적합하며, 여러분 자신의 트랜잭션 순서와 같은 가정을 실어 나릅니다 - 그러니 체인을 쓰기 위해 이미 그 가정을 받아들였다면 피드를 소비하는 것이 새 가정을 더하지 않습니다. 어느 한 당사자도 위조할 수 없는 가격이 설계에 필요하다면, 이 레이어는 그것을 제공하지 않으며 어떤 파라미터도 그렇게 만들어 주지 않습니다.