|
| 1 | +# Migrate from Chainlink to Pyth |
| 2 | + |
| 3 | +This guide explains how to migrate an EVM application that uses Chainlink price feeds to Pyth price feeds. |
| 4 | +Pyth provides a Chainlink-compatible interface for its price feeds to make this process simple. |
| 5 | +There are two main steps to the migration: |
| 6 | + |
| 7 | +1. Deploy the [`PythAggregatorV3`](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/sdk/solidity/PythAggregatorV3.sol) contract to provide a Chainlink-compatible feed interface. |
| 8 | +2. Schedule price updates for the feeds required by your app. |
| 9 | + |
| 10 | +## Install Pyth SDKs |
| 11 | + |
| 12 | +The `PythAggregatorV3` contract is provided in the [Pyth Price Feeds Solidity SDK](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/ethereum/sdk/solidity). |
| 13 | +Add this SDK to the dependencies of your EVM contract. |
| 14 | + |
| 15 | +**Truffle/Hardhat** |
| 16 | + |
| 17 | +If you are using Truffle or Hardhat, simply install the NPM package: |
| 18 | + |
| 19 | +```bash copy |
| 20 | +npm install @pythnetwork/pyth-sdk-solidity |
| 21 | +``` |
| 22 | + |
| 23 | +**Foundry** |
| 24 | + |
| 25 | +If you are using Foundry, you will need to create an NPM project if you don't already have one. |
| 26 | +From the root directory of your project, run: |
| 27 | + |
| 28 | +```bash copy |
| 29 | +npm init -y |
| 30 | +npm install @pythnetwork/pyth-sdk-solidity |
| 31 | +``` |
| 32 | + |
| 33 | +Then add the following line to your `remappings.txt` file: |
| 34 | + |
| 35 | +```text copy |
| 36 | +@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity |
| 37 | +``` |
| 38 | + |
| 39 | +## Deploy Adapter Contract |
| 40 | + |
| 41 | +First, deploy the `PythAggregatorV3` contract from `@pythnetwork/pyth-sdk-solidity` as a replacement for your application's Chainlink price feeds. |
| 42 | +`PythAggregatorV3` is an adapter contract that wraps the Pyth contract and implements Chainlink's `AggregatorV3Interface`. |
| 43 | + |
| 44 | +One important difference between Pyth and Chainlink is that the Pyth contract holds data for all price feeds; in contrast, Chainlink has separate instances of `AggregatorV3Interface` for each feed. |
| 45 | +The adapter contract resolves this discrepancy by wrapping a single Pyth price feed. |
| 46 | +Users should deploy an instance of this adapter for every required price feed, then point their existing app to the addresses of the deployed adapter contracts. |
| 47 | + |
| 48 | +The following `forge` deployment script demonstrates the expected deployment process: |
| 49 | + |
| 50 | +```solidity copy |
| 51 | +// SPDX-License-Identifier: Apache 2 |
| 52 | +pragma solidity ^0.8.0; |
| 53 | +
|
| 54 | +import "forge-std/Script.sol"; |
| 55 | +import { PythAggregatorV3 } from "@pythnetwork/pyth-sdk-solidity/PythAggregatorV3.sol"; |
| 56 | +import { ChainlinkApp } from "./ChainlinkApp.sol"; |
| 57 | +
|
| 58 | +contract PythAggregatorV3Deployment is Script { |
| 59 | + function run() external { |
| 60 | + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); |
| 61 | + vm.startBroadcast(deployerPrivateKey); |
| 62 | +
|
| 63 | + // Get the address for your ecosystem from: |
| 64 | + // https://docs.pyth.network/price-feeds/contract-addresses/evm |
| 65 | + address pythPriceFeedsContract = 0xff1a0f4744e8582DF1aE09D5611b887B6a12925C; |
| 66 | + // Get the price feed ids from: |
| 67 | + // https://docs.pyth.network/price-feeds/price-feed-ids |
| 68 | + bytes32 ethFeedId = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace; |
| 69 | + bytes32 solFeedId = 0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d; |
| 70 | +
|
| 71 | + // Deploy an instance of PythAggregatorV3 for every feed. |
| 72 | + PythAggregatorV3 ethAggregator = new PythAggregatorV3( |
| 73 | + pythPriceFeedsContract, |
| 74 | + ethFeedId |
| 75 | + ); |
| 76 | + PythAggregatorV3 solAggregator = new PythAggregatorV3( |
| 77 | + pythPriceFeedsContract, |
| 78 | + solFeedId |
| 79 | + ); |
| 80 | +
|
| 81 | + // Pass the address of the PythAggregatorV3 contract to your chainlink-compatible app. |
| 82 | + ChainlinkApp app = new ChainlinkApp( |
| 83 | + address(ethAggregator), |
| 84 | + address(solAggregator) |
| 85 | + ); |
| 86 | +
|
| 87 | + vm.stopBroadcast(); |
| 88 | + } |
| 89 | +} |
| 90 | +
|
| 91 | +``` |
| 92 | + |
| 93 | +## Schedule Updates |
| 94 | + |
| 95 | +Chainlink-compatible applications typically expect on-chain price feeds to update on a schedule. |
| 96 | +When migrating to Pyth, apps may need to schedule these price updates themselves. |
| 97 | +This step is required because Pyth is a pull oracle; see [What is a pull oracle?](/price-feeds/pull-updates.mdx) to learn more about this topic. |
| 98 | + |
| 99 | +The [Sponsored Feeds](/price-feeds/sponsored-feeds.mdx) page shows a list of feeds that have scheduled on-chain updates. |
| 100 | +If the feeds your application needs are not on this list, see [Schedule Price Updates](/price-feeds/schedule-price-updates) for several options to solve this problem. |
0 commit comments