|
| 1 | +import { Callout } from "nextra/components"; |
| 2 | + |
| 3 | +# Derive Cross Rate |
| 4 | + |
| 5 | +This guide shows how to combine two price feeds to derive a cross rate. These are also known as "synthetic" price feeds. |
| 6 | +Cross rates or Synthetic Price feeds are useful for trading pairs that are not directly supported by Pyth. |
| 7 | + |
| 8 | +<Callout type="info" emoji="ℹ️"> |
| 9 | + This guide is for developers who are building applications on **EVM |
| 10 | + blockchains** using **solidity only**. |
| 11 | +</Callout> |
| 12 | + |
| 13 | +## Example |
| 14 | + |
| 15 | +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}`**. |
| 16 | + |
| 17 | +$$ |
| 18 | +\large{\text{ETH/EUR} = \text{ETH/USD} \div \text{EUR/USD}} |
| 19 | +$$ |
| 20 | + |
| 21 | +## Derive a cross rate |
| 22 | + |
| 23 | +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. |
| 24 | +This method is available in [Pyth solidity SDK](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/ethereum/sdk/solidity). |
| 25 | + |
| 26 | +This method takes the following parameters: |
| 27 | + |
| 28 | +- `price1`: The first price feed value, representing a / b (e.g., ETH/USD). Must be a signed integer (int64). |
| 29 | +- `expo1`: The exponent for price1, indicating the number of decimal places. |
| 30 | +- `price2`: The second price feed value, representing c / b (e.g., EUR/USD). |
| 31 | +- `expo2`: The exponent for price2. |
| 32 | +- `targetExponent`: The desired exponent for the output cross rate (a / c). The result will be scaled to this exponent. |
| 33 | + |
| 34 | +Returns: |
| 35 | + |
| 36 | +- `crossRate`: The computed cross rate (a / c), scaled to targetExponent. |
| 37 | + |
| 38 | +## Example |
| 39 | + |
| 40 | +```solidity copy |
| 41 | +pragma solidity ^0.8.0; |
| 42 | +
|
| 43 | +import "@pythnetwork/pyth-sdk-solidity/IPyth.sol"; |
| 44 | +import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol"; |
| 45 | +import "@pythnetwork/pyth-sdk-solidity/PythUtils.sol"; |
| 46 | +
|
| 47 | +contract ExampleCrossRate { |
| 48 | + IPyth public pyth; |
| 49 | +
|
| 50 | + constructor(address _pythContract) { |
| 51 | + pyth = IPyth(_pythContract); |
| 52 | + } |
| 53 | +
|
| 54 | + // priceUpdate should include both price feeds |
| 55 | + function getEthPerEur( |
| 56 | + bytes32 ethUsdId, |
| 57 | + bytes32 eurUsdId, |
| 58 | + bytes[] calldata priceUpdate |
| 59 | + ) external payable returns (int64 price, int32 expo) { |
| 60 | + // Update both feeds |
| 61 | + uint fee = pyth.getUpdateFee(priceUpdate); |
| 62 | + pyth.updatePriceFeeds{ value: fee }(priceUpdate); |
| 63 | +
|
| 64 | + // Fetch prices |
| 65 | + PythStructs.Price memory ethUsd = pyth.getPriceNoOlderThan(ethUsdId, 60); |
| 66 | + PythStructs.Price memory eurUsd = pyth.getPriceNoOlderThan(eurUsdId, 60); |
| 67 | +
|
| 68 | + // Derive ETH/EUR = ETH/USD / EUR/USD |
| 69 | + int32 targetExpo = -8; |
| 70 | + int64 ethPerEur = PythUtils.deriveCrossRate( |
| 71 | + ethUsd.price, |
| 72 | + ethUsd.expo, |
| 73 | + eurUsd.price, |
| 74 | + eurUsd.expo, |
| 75 | + targetExpo |
| 76 | + ); |
| 77 | +
|
| 78 | + return (ethPerEur, targetExpo); |
| 79 | + } |
| 80 | +} |
| 81 | +
|
| 82 | +``` |
| 83 | + |
| 84 | +### ⚠️ Things to Keep in Mind |
| 85 | + |
| 86 | +- The function reverts if either price is **negative**, or if any exponent is **less than -255**. |
| 87 | +- The result is rounded down. If the result is smaller than 1 in the given `targetExponent{:jsx}`, it will return 0. |
| 88 | +- Confidence intervals are not derived in this function. If needed, you have to derive them manually. |
| 89 | +- Reverts with `PythErrors.ExponentOverflow{:jsx}` if `targetExponent + expo1 - expo2{:jsx}` is outside the range **[-58, 58]**. |
| 90 | + |
| 91 | +## Additional Resources |
| 92 | + |
| 93 | +You may find these additional resources helpful. |
| 94 | + |
| 95 | +### How to use real-time data in EVM contracts |
| 96 | + |
| 97 | +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. |
| 98 | + |
| 99 | +### Price Feed IDs |
| 100 | + |
| 101 | +The [Price Feed IDs](https://www.pyth.network/developers/price-feed-ids) page lists the price feed IDs for each asset supported by Pyth. |
0 commit comments