PythAdapter
Inherits: AggregatorV3Interface
Title: PythAdapter
Adapts Pyth Network price feeds to Chainlink’s AggregatorV3Interface.
Pyth is pull-based: prices must be pushed on-chain before reading. This adapter reads the latest price and converts it to 8 decimals. Supports price inversion for feeds like USD/SEK → SEK/USD.
Note: security-contact: contact@plether.com
Constants
PYTH
IPyth public immutable PYTH
PRICE_ID
bytes32 public immutable PRICE_ID
MAX_STALENESS
uint256 public immutable MAX_STALENESS
MAX_CONFIDENCE_BPS
uint256 public immutable MAX_CONFIDENCE_BPS
INVERSE
bool public immutable INVERSE
DECIMALS
uint8 public constant DECIMALS = 8
State Variables
DESCRIPTION
string public DESCRIPTION
Functions
constructor
constructor(
address pyth_,
bytes32 priceId_,
uint256 maxStaleness_,
string memory description_,
bool inverse_,
uint256 maxConfidenceBps_
) ;
Parameters
| Name | Type | Description |
|---|---|---|
pyth_ | address | Pyth contract address on this chain. |
priceId_ | bytes32 | Pyth price feed ID (e.g., USD/SEK). |
maxStaleness_ | uint256 | Maximum age of price in seconds before considered stale. |
description_ | string | Human-readable description (e.g., “SEK / USD”). |
inverse_ | bool | If true, inverts the price (e.g., USD/SEK → SEK/USD). |
maxConfidenceBps_ | uint256 | Maximum confidence interval as basis points of price (e.g., 500 = 5%). |
latestRoundData
Returns the latest price data in Chainlink-compatible format.
Converts Pyth’s variable exponent to fixed 8 decimals.
Reports block.timestamp as updatedAt (self-attestation): this adapter
validates freshness internally against publishTime using MAX_STALENESS,
then attests “price valid as of now.” Downstream consumers (BasketOracle,
SyntheticSplitter) see a fresh timestamp and skip their own staleness check,
avoiding double-timeout rejection during weekend forex market closures.
function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint80 | roundId Always returns 1 (Pyth doesn’t use rounds). |
<none> | int256 | answer Price in 8 decimals. |
<none> | uint256 | startedAt Current block timestamp (adapter attestation time). |
<none> | uint256 | updatedAt Current block timestamp (adapter attestation time). |
<none> | uint80 | answeredInRound Always returns 1. |
getRoundData
Returns data for a specific round ID.
Only round ID 1 is supported (Pyth doesn’t use rounds).
function getRoundData(
uint80 _roundId
) external view returns (uint80, int256, uint256, uint256, uint80);
decimals
Returns the number of decimals (always 8 for compatibility).
function decimals() external pure returns (uint8);
description
Returns the price feed description.
function description() external view returns (string memory);
version
Returns the adapter version.
function version() external pure returns (uint256);
updatePrice
Updates the Pyth price feed with new data.
Anyone can call this to push fresh prices on-chain.
function updatePrice(
bytes[] calldata updateData
) external payable;
Parameters
| Name | Type | Description |
|---|---|---|
updateData | bytes[] | Price update data from Pyth’s Hermes API. |
getUpdateFee
Returns the fee required to update the price.
function getUpdateFee(
bytes[] calldata updateData
) external view returns (uint256 fee);
Parameters
| Name | Type | Description |
|---|---|---|
updateData | bytes[] | Price update data to calculate fee for. |
Returns
| Name | Type | Description |
|---|---|---|
fee | uint256 | Fee in wei. |
_convertTo8Decimals
Converts Pyth price to 8 decimals.
Pyth uses variable exponents (e.g., -8, -6). This normalizes to -8.
function _convertTo8Decimals(
int64 price,
int32 expo
) internal pure returns (int256);
Parameters
| Name | Type | Description |
|---|---|---|
price | int64 | Pyth price value. |
expo | int32 | Pyth exponent (negative for decimal places). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | int256 | Normalized price in 8 decimals. |
_invertTo8Decimals
Inverts Pyth price and converts to 8 decimals.
For converting USD/SEK to SEK/USD: 1 / (price * 10^expo) * 10^8
function _invertTo8Decimals(
int64 price,
int32 expo
) internal pure returns (int256);
Parameters
| Name | Type | Description |
|---|---|---|
price | int64 | Pyth price value. |
expo | int32 | Pyth exponent (negative for decimal places). |
Returns
| Name | Type | Description |
|---|---|---|
<none> | int256 | Inverted price in 8 decimals. |
Errors
PythAdapter__StalePrice
error PythAdapter__StalePrice(uint256 publishTime, uint256 maxAge);
PythAdapter__InvalidPrice
error PythAdapter__InvalidPrice();
PythAdapter__ConfidenceTooWide
error PythAdapter__ConfidenceTooWide(uint64 conf, int64 price);
PythAdapter__InvalidRoundId
error PythAdapter__InvalidRoundId();
PythAdapter__RefundFailed
error PythAdapter__RefundFailed();