Feed updates
Commodities.HNG7/USDwent liveEquity.US.VXF7went liveEquity.US.VXV6removedCommodities.RSN7/UScwent liveCommodities.CLLX6/USDremovedCrypto.PRL/USDwent liveCommodities.LIZ6/CNYaddedCommodities.LIX6/CNYaddedCommodities.WTIZ7/USDaddedCommodities.WTIX7/USDaddedCommodities.WTIV7/USDaddedCommodities.WTIU7/USDaddedCommodities.WTIQ7/USDaddedCommodities.WTIN7/USDadded
View all
Developer Hub

Best Practices

Learn how to integrate Pyth Pro price feeds safely and effectively

This page provides technical details and patterns for getting the most out of Pyth Pro price feeds. Please read this page before using Pyth price feeds in your application.

Fixed-Point Numeric Representation

Price feeds represent numbers in a fixed-point format. The same exponent is used for both the price and confidence interval. Multiply the integer price or confidence by 10^exponent to obtain its decimal value. For example, consider these Pyth Pro values for AAPL/USD:

FieldValue
exponent-5
confidence1500
price12276250

The confidence interval is 1500 * 10^(-5) = $0.015, and the price is 12276250 * 10^(-5) = $122.7625.

Price Availability

Pyth Pro does not guarantee a current price for a product. This situation can happen for various reasons. For example, US equity markets only trade during certain hours, and outside those hours, it's not clear what an equity's price is. Pyth Pro price availability depends on each feed's market session.
Consult Market Hours to know the market hours for each asset class.

Alternatively, a network outage (at the internet level, blockchain level, or at multiple data providers) may prevent the protocol from producing new price updates. (Such outages are unlikely, but integrators should still be prepared for the possibility.) In such cases, check Pyth Pro prices for staleness.

Integrators should be careful to avoid accidentally using a stale price. Check each feed's feedUpdateTimestamp in microseconds for the freshness of its price data. The feed's marketSession identifies its trading session: regular, preMarket, postMarket, overNight, or closed. Check that the session suits the application's trading rules.

Confidence Intervals

Pyth Pro publishes both a price and a confidence interval for each product. For example, consider a Pyth Pro bitcoin price of $50000 ± $10. Pyth Pro publishes a confidence interval because, in real markets, there is no one single price for a product. For example, at any given time, bitcoin trades at different prices at different venues around the world. While these prices are typically similar, they can diverge for a number of reasons, such as when a cryptocurrency exchange blocks withdrawals on an asset. If this happens, prices diverge because arbitrageurs can no longer bring prices across exchanges into line. Alternatively, prices on different venues can differ simply because an asset is highly volatile at a particular point in time. At such times, bid/ask spreads tend to be wider, and trades on different markets at around the same time tend to occur at a wider range of prices.

See Understanding Price Data for how Pyth Pro computes confidence.

When confidence is wide relative to the price, consider the following options:

  1. Use an average price that takes into consideration multiple data points rather than the single print with the wider confidence interval. Pyth Pro's exponential moving average provides an average price of the asset over its averaging window. The exponential moving average price is computed such that it lessens the influence of prices with wide confidence intervals. You may find more details in Understanding Price Data.
  2. Pause new activity that depends on the asset's price when confidence / price exceeds a threshold.

Pricing Futures-Based Assets

For assets like commodities, interest rates, and even volatility indices, pricing is primarily derived from futures contracts. These contracts form a series of prices for different delivery dates, collectively known as the futures curve. While the front-month contract is the most actively traded and often seen as the benchmark, it doesn't represent the current price of the asset but rather a proxy of the near-term price of the asset at the time of delivery.

This reliance on futures, in the absence of a native spot price, means that market expectations, logistical constraints, amongst other factors can heavily influence the front-month price. For example, in times of extreme market stress, the front-month contract turn negative when traders avoid delivery, distorting its usefulness as a representative market signal. This happened in the case of the 2020 oil crash, where the front-month price of WTI Crude oil turned negative due to a lack of storage capacity, making applications that rely exclusively on the front-month price unreliable.

Use a weighted strategy based on the contracts' expiration dates. As the front month approaches expiry, least weight should be allocated on this contract and the weights of the other contracts are determined proportionally. A daily re-adjusted strategy should be applied by the end user of the price feeds.

On-Chain Verification

These practices apply to integrations that verify Pyth Pro updates in contracts.

Freshness

Pyth Pro's verifyUpdate checks the signature and fee but does not check the update's age. Integrators must enforce a freshness threshold. The update's timestamp (timestampUs in JSON, Update.timestamp on EVM) uses microseconds, while block.timestamp uses seconds. Convert timestamps to the same unit before comparing them.

Adversarial Selection

Transaction submitters choose which signed Pyth Pro update to include. The integrating contract must enforce timestamp ordering and staleness limits. However, users can still choose any price update that satisfies these constraints. This ability is functionally equivalent to latency: it allows users to see the price in the future before using a price from the past.

The simplest way to guard against this attack vector is to incorporate a staleness check to ensure that the price used in a transaction is sufficiently recent.

Apply the checks in Price Availability and Freshness after verifying the signed update. Highly latency-sensitive protocols may wish to reduce the threshold to a few seconds to better suit their needs. See Latency for further mitigations.

Latency

Developers integrating Pyth Pro price feeds should account for the latency between market data sources (e.g. centralized exchanges) and on-chain use. Blockchain consensus and security add latency to on-chain use of Pyth Pro data. The threat model for integrating protocols should assume that adversaries see price changes a short time before the protocol does. In this threat model, protocol designers should avoid situations where a Pyth Pro price update must race against an adversary's transaction. Adversaries are highly likely to win these races, as they have a head start, and sophisticated adversaries can additionally optimize their network latencies or pay miners for priority blockspace.

Latency Mitigations for Derivative Protocols1

Consider the following strategies to mitigate price latency in derivative protocols:

  1. Use Delayed Settlement: Derivative protocols can introduce a delay between the time an order is created and the time it is executed. This delay gives the protocol time to observe price changes and reject trades/transactions that profit over latency. Suppose a user submits a trade transaction at a time t. Select a fixed-rate channel and round t up to a multiple of the channel's interval. For fixed_rate@200ms, round up to a multiple of 200,000 microseconds. Rounding up selects the first update at or after the order, so the trader could not have seen that price when ordering. Fetch the signed update through POST /v1/price with channel set to the selected channel, timestamp set to the rounded timestamp in microseconds, and formats set to ["evm"], then verify it on-chain with verifyUpdate. Check that the verified update's timestamp equals the rounded timestamp.

  2. Use a Spread: Pyth Pro provides a confidence interval for each price update. Derivative protocols can use this confidence interval as a range around the price. By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up.

  3. Enforce Position Holding: Enforce hold times on positions to prevent users from exploiting price latency. For example, a protocol could require users to hold an asset or a position for a certain period before they can trade or close it. This hold time gives the protocol time to observe price changes and reject trades that profit over latency.

Executable Price Risks and Mitigations

Protocols that offer executable prices should account for additional risks beyond the latency and staleness guidance described above. These risks are particularly relevant for high-frequency derivative protocols, such as perps who offer or wants to offer instant fills.

Protocols offering executable prices are encouraged to consider the following risks and mitigation strategies:

  1. Same-Block Exploitation: If your protocol allows positions to be opened and closed within the same block, stale or manipulated prices can be exploited using flash loans without inventory risk. An attacker can open a position using a favorable stale price, then immediately close it in the same transaction, profiting from the price discrepancy. To prevent this, separate the commitment to a trade from its execution. Use delayed settlement or commit-reveal schemes to ensure that positions cannot be opened and closed in the same block. Enforce a minimum holding period or require a certain number of blocks between entry and exit to prevent flash-loan round trips.

  2. Staleness in Executable Prices: Adversaries may see price updates before your protocol does, or they may select favorable historical price updates that satisfy staleness constraints. This latency advantage allows sophisticated traders to exploit price differences. Enforce strict freshness thresholds from Freshness when filling orders. For delayed execution models, follow Latency Mitigations to request a fixed-rate update at the order time rounded up to the channel's interval. Check that the verified update's timestamp equals the rounded timestamp.

  3. High Volatility and Wide Confidence Intervals: Account for slippage from large price moves during high volatility. The executable price you quote may not reflect the true market price when confidence intervals are wide. Design your pricing function to account for trade size and confidence intervals. Scale spreads and fees with notional size and confidence. Discount prices toward the adverse side of the confidence interval when quoting executable prices. When the ratio of confidence to price exceeds a threshold, widen spreads or cap the maximum trade size.

  4. Liquidity and Price Impact: Executable prices effectively provide liquidity to traders. If your pricing model treats price as size-agnostic and ignores external market depth, traders can systematically extract value by trading at sizes that would move the market price. Implement exposure limits to cap per-trade notional, per-block trading volume, and per-market open interest. Increase taker and maker fees during stressed market conditions to compensate for increased risk.

  5. Availability Gaps: Market hours or network outages can cause price feeds to freeze while trading remains active. In such cases, your protocol may continue to offer executable prices based on stale data. Respect market hours and implement availability guardrails. If price updates stall or confidence intervals widen beyond acceptable thresholds, pause new position openings or switch to conservative pricing instead of reusing stale executable prices.

Pyth Core Contracts

For integrations using Pyth Core contracts, the SDKs check staleness by default. The SDKs' getPriceNoOlderThan() returns the most recent price within a configurable age threshold. The Rust SDK returns None for stale prices, and the Solidity SDK reverts.

For delayed settlement with Pyth Core contracts, fetch the update with GET /v2/updates/price/{publish_time} and parse it with parsePriceFeedUpdates().

Footnotes

  1. The strategies and methodologies outlined in this page, including those addressing price latency mitigation, are provided solely for informational purposes and might not fully eliminate the discussed problems. Do your own research before using them.
    Refer to Terms of Use for more information.
    ↩

On this page