diff --git a/pages/price-feeds/_meta.json b/pages/price-feeds/_meta.json index 8c2d4ea1..218fcfc5 100644 --- a/pages/price-feeds/_meta.json +++ b/pages/price-feeds/_meta.json @@ -26,6 +26,7 @@ "use-real-time-data": "Use Real-Time Price Data", "fetch-price-updates": "Fetch Price Updates", "schedule-price-updates": "Schedule Price Updates", + "derive-cross-rate": "Derive Cross Rate", "migrate-an-app-to-pyth": "Migrate an App to Pyth", "use-pyth-for-morpho": "Use Pyth for Morpho Markets", "publish-data": "Publish Data", diff --git a/pages/price-feeds/derive-cross-rate.mdx b/pages/price-feeds/derive-cross-rate.mdx new file mode 100644 index 00000000..0a6feaff --- /dev/null +++ b/pages/price-feeds/derive-cross-rate.mdx @@ -0,0 +1,101 @@ +import { Callout } from "nextra/components"; + +# Derive Cross Rate + +This guide shows how to combine two price feeds to derive a cross rate. These are also known as "synthetic" price feeds. +Cross rates or Synthetic Price feeds are useful for trading pairs that are not directly supported by Pyth. + + + This guide is for developers who are building applications on **EVM + blockchains** using **solidity only**. + + +## Example + +For example, if you want to trade the price of **`ETH/EUR{:jsx}`**, which is not directly supported by Pyth, you can combine the price of **`ETH/USD{:jsx}`** and **`EUR/USD{:jsx}`** to derive the price of **`ETH/EUR{:jsx}`**. + +$$ +\large{\text{ETH/EUR} = \text{ETH/USD} \div \text{EUR/USD}} +$$ + +## Derive a cross rate + +The Pyth Solidity SDKprovides [`deriveCrossRate`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/sdk/solidity/PythUtils.sol#L77) function to combine two price feeds. +This method is available in [Pyth solidity SDK](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/ethereum/sdk/solidity). + +This method takes the following parameters: + +- `price1`: The first price feed value, representing a / b (e.g., ETH/USD). Must be a signed integer (int64). +- `expo1`: The exponent for price1, indicating the number of decimal places. +- `price2`: The second price feed value, representing c / b (e.g., EUR/USD). +- `expo2`: The exponent for price2. +- `targetExponent`: The desired exponent for the output cross rate (a / c). The result will be scaled to this exponent. + +Returns: + +- `crossRate`: The computed cross rate (a / c), scaled to targetExponent. + +## Example + +```solidity copy +pragma solidity ^0.8.0; + +import "@pythnetwork/pyth-sdk-solidity/IPyth.sol"; +import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol"; +import "@pythnetwork/pyth-sdk-solidity/PythUtils.sol"; + +contract ExampleCrossRate { + IPyth public pyth; + + constructor(address _pythContract) { + pyth = IPyth(_pythContract); + } + + // priceUpdate should include both price feeds + function getEthPerEur( + bytes32 ethUsdId, + bytes32 eurUsdId, + bytes[] calldata priceUpdate + ) external payable returns (int64 price, int32 expo) { + // Update both feeds + uint fee = pyth.getUpdateFee(priceUpdate); + pyth.updatePriceFeeds{ value: fee }(priceUpdate); + + // Fetch prices + PythStructs.Price memory ethUsd = pyth.getPriceNoOlderThan(ethUsdId, 60); + PythStructs.Price memory eurUsd = pyth.getPriceNoOlderThan(eurUsdId, 60); + + // Derive ETH/EUR = ETH/USD / EUR/USD + int32 targetExpo = -8; + int64 ethPerEur = PythUtils.deriveCrossRate( + ethUsd.price, + ethUsd.expo, + eurUsd.price, + eurUsd.expo, + targetExpo + ); + + return (ethPerEur, targetExpo); + } +} + +``` + +### ⚠️ Things to Keep in Mind + +- The function reverts if either price is **negative**, or if any exponent is **less than -255**. +- The result is rounded down. If the result is smaller than 1 in the given `targetExponent{:jsx}`, it will return 0. +- Confidence intervals are not derived in this function. If needed, you have to derive them manually. +- Reverts with `PythErrors.ExponentOverflow{:jsx}` if `targetExponent + expo1 - expo2{:jsx}` is outside the range **[-58, 58]**. + +## Additional Resources + +You may find these additional resources helpful. + +### How to use real-time data in EVM contracts + +The [How to use real-time data in EVM contracts](./use-real-time-data/evm) guide provides a step-by-step guide on how to use real-time data in EVM contracts. + +### Price Feed IDs + +The [Price Feed IDs](https://www.pyth.network/developers/price-feed-ids) page lists the price feed IDs for each asset supported by Pyth.