How Pyth Works
flowchart
- price data pushlisher submit data to pyth’s oracel program
- pyth’s oracel program combines all price data and compute the final price based on it’s own algorithm
- pyth transfer price data from pythnet to mutiple target chains eg,:evm,bnb,arbiturm
- hermes(web service) listens to price update.
- price consumer get the latest price from hermes(web service),verify the lastest price data on chain via oracel program on each chain,the program then return the price once price data is valid
Pyth Methods On EVM Table
Method | Need check publishTime | Most recent price |
---|---|---|
getPrice | ✗ | ✓ |
getPriceUnsafe | ✓ | ✗ |
getPriceNoOlderThan | ✗ | ✗ |
getEmaPrice | ✗ | ✗ |
getEmaPriceUnsafe | ✓ | ✗ |
getEmaPriceNoOlderThan | ✗ | ✗ |
getUpdateFee | ✗ | ✗ |
getValidTimePeriod | ✗ | ✗ |
parsePriceFeedUpdate | ✗ | ✗ |
parsePriceFeeUpdateUnique | ✗ | ✗ |
updatePriceFeeds | ✗ | ✓ |
updatePriceFeedsIfNecessary | ✗ | ✗ |
Pyth Methods On EVM
getPrice
arguments:
- price feed id
getPrice() revert due to the price has not been update within getValidTimePeriod() seconds which is typically 1 minute.
1 | EVM call reverted with exception: |
let’s take eth/usd as example, the return price is 291769250000
, and the price is 2917.69250000
usd.
The only argument is price feed id which is a 32-byte id written as a hexadecimal string.For eth/usd it’s 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace
. You can get the full list from https://pyth.network/developers/price-feed-ids page.
1 | EVM call succeeded with result: |
getPriceUnsafe
arguments:
- price feed id
The input arguments and return data format for getPriceUnsafe() are identical to those of the getPrice() function. However, the key distinction lies in their behavior: getPriceUnsafe() may return a price from an arbitrary point in the past, potentially outdated. Consequently, the responsibility falls on the caller or price consumer to ensure the returned data meets their recency requirements. This involves comparing the current block.timestamp with the returned publishTime to verify that the price update is sufficiently recent for their specific use case.
getPriceNoOlderThan
arguments:
- price feed id
- age
This function reverts with a PriceFeedNotFound error if the requested feed id has never received a price update. Calling updatePriceFeed to fix this issue.
getEmaPrice
arguments:
- price feed id
Get the latest exponentially-weighted moving average (EMA) price and confidence interval for the requested price feed id.
1 | EVM call succeeded with result: |
getEmaPriceUnsafe
arguments:
- price feed id
This function may return a price from arbitrarily far in the past
Get the latest exponentially-weighted moving average (EMA) price and confidence interval for the requested price feed id.
getEmaPriceNoOlderTham
arguments:
- price feed id
- age
Get the latest exponentially-weighted moving average (EMA) price and confidence interval for the requested price feed id
The caller provides an age argument that specifies how old the price can be.The call can be revert due toStalePriceError
.
getUpdateFee
arguments:
- updateData
Note that updataData
is retrieved from Hermes
REST API.
1 | EVM call succeeded with result: |
getValidTimePeriod
Get the default valid time period in seconds.
Above some getting function revert if current on-chain price is older than this period.
1 | EVM call succeeded with result: |
parsePriceFeedUpdates
arguments:
- updateData* hex[]
- priceIds* bytes32[]
- minPublishTime* uint64
- maxPublishTime* uint64
- fee* wei
Parse updateData and return the price feeds for the given priceIds within, if they are all published between minPublishTime and maxPublishTime (minPublishTime <= publishTime <= maxPublishTime).
Please note that this function not returned the most recent price,instead it returned a price for fixed time(minPublishTime <= publishTime <= maxPublishTime).
If caller need a most recent price they should call updatePriceFeeds followed by getPrice or one of its variants.
Unlike updatePriceFeeds, calling this function will not update the on-chain price
parsePriceFeedUpdatesUnique.
arguments:
- updateData* hex[]
- priceIds* bytes32[]
- minPublishTime* uint64
- maxPublishTime* uint64
- fee* wei
the price update is the earliest update after the minPublishTime.
condition:prevPublishTime < minPublishTime <= publishTime <= maxPublishTime
updatePriceFeed
arguments:
- updateData* hex[]
- fee* wei
Update the on-chain price feeds using the provided updateData
Caller first retrieve a latest price from Hermes
REST API,and then invoke this function to update the on-chain price if this price is more recent than on-chain price,otherwise the provided update will be ignored.
updatePriceFeedsIfNecessary
arguments:
- updateData* hex[]
- priceIds* bytes32[]
- publishTimes* uint64[]
- fee* wei
Update the on-chain price feeds using the provided updateData if the on-chain data is not sufficiently fresh. The caller provides two matched arrays, priceIds and publishTimes. This function applies the update if there exists an index i such that priceIds[i]’s last publishTime is before than publishTimes[i]. Callers should typically pass publishTimes[i] to be equal to the publishTime of the corresponding price id in updateData. If this condition is not satisfied, the call will revert with a NoFreshUpdate error.
Resources
PythOracle:if price.expo is less than 0, wrong prices will be recorded https://github.com/sherlock-audit/2023-07-perennial-judging/issues/56
Using stale price in Pyth Network https://solodit.xyz/issues/m-07-using-stale-price-in-pyth-network-pashov-none-astrolab-markdown