|
1 | | -# Morpho Blue Oracles |
| 1 | +# Pyth Morpho Wrapper |
2 | 2 |
|
3 | | -Morpho Blue Oracles are contracts that can be used as oracles for markets on [Morpho Blue](https://github.com/morpho-org/morpho-blue). |
4 | | -The oracles implement the `IOracle` interface defined in [`IOracle.sol`](https://github.com/morpho-org/morpho-blue/blob/main/src/interfaces/IOracle.sol#L9): they return the price of 1 asset of collateral token quoted in 1 asset of loan token. |
| 3 | +Pyth Morpho Wrapper is a wrapper around the Pyth oracle that can be used as an oracle for markets on [Morpho Blue](https://github.com/morpho-org/morpho-blue). |
5 | 4 |
|
6 | | -## MorphoChainlinkOracleV2 |
| 5 | +## MorphoPythOracle |
7 | 6 |
|
8 | | -The `MorphoChainlinkOracleV2` is an oracle that uses Chainlink-interface-compliant feeds to provide price data. |
| 7 | +The `MorphoPythOracle` is an oracle that uses Pyth to provide price data. |
9 | 8 |
|
10 | 9 | This oracle handles the following cases among others (let's say that our pair is A/B): |
11 | 10 |
|
12 | | -- A/B is a feed (typically, stETH/ETH). |
13 | | -- B/A is a feed (typically, ETH/USDC). |
14 | | -- A/C and B/C are feeds (typically, stETH/ETH and USDC/ETH). |
| 11 | +- A/B is a feed (typically, WBTC/BTC). |
| 12 | +- B/A is a feed (typically, BTC/USD). |
| 13 | +- A/C and B/C are feeds (typically, WBTC/BTC and BTC/USD). |
15 | 14 | - A/C, C/D and B/D are feeds (typically, WBTC/BTC, BTC/USD, USDC/USD). |
16 | 15 | - A/D, and B/C, C/D are feeds (typically, USDC/USD, WBTC/BTC, BTC/USD). |
17 | 16 | - A/C, C/D and B/E, E/D are feeds. |
18 | 17 | - A/C and C/B are feeds (typically, WBTC/BTC and BTC/ETH). |
19 | | -- A'/C and B/C are feeds, and there is an exchange rate between A and A'. (typically A=sDAI and A'=DAI). |
20 | 18 |
|
21 | 19 | ## Deploy an Oracle |
22 | 20 |
|
23 | | -To deploy a `MorphoChainlinkOracleV2` on Ethereum, it is highly recommended to use the factory `MorphoChainlinkOracleV2Factory`. |
24 | | -To do so, call the `createMorphoChainlinkOracleV2` function with the following parameters: |
| 21 | +To deploy a `MorphoPythOracle` on Ethereum, it is highly recommended to use the factory `MorphoPythOracleFactory`. |
| 22 | +To do so, call the `createMorphoPythOracle` function with the following parameters: |
25 | 23 |
|
| 24 | +- `pyth`: The Pyth contract address. This is the address of the Pyth contract deployed on the chain. You can find the address of the Pyth contract for each chain [here](https://docs.pyth.network/price-feeds/contract-addresses/evm). |
26 | 25 | - `baseVault`: The ERC4626 token vault for the base asset. |
27 | 26 | - `baseVaultConversionSample`: A sample amount for converting base vault units. |
28 | | -- `baseFeed1`, `baseFeed2`: Chainlink-interface-compliant data feeds for the base asset. |
29 | | -- `baseTokenDecimals`: Decimal precision of the base asset. |
| 27 | +- `baseFeed1`, `baseFeed2`: Pyth price feed ids for the base asset. You can find the price feed ids for each asset [here](https://www.pyth.network/developers/price-feed-ids). |
| 28 | +- `baseTokenDecimals`: Decimal precision of the base asset. |
30 | 29 | - `quoteVault`: The ERC4626 token vault for the quote asset. |
31 | 30 | - `quoteVaultConversionSample`: A sample amount for converting quote vault units. |
32 | | -- `quoteFeed1`, `quoteFeed2`: Chainlink-interface-compliant data feeds for the quote asset. |
| 31 | +- `quoteFeed1`, `quoteFeed2`: Pyth price feed ids for the quote asset. You can find the price feed ids for each asset [here](https://www.pyth.network/developers/price-feed-ids). |
33 | 32 | - `quoteTokenDecimals`: Decimal precision of the quote asset. |
| 33 | +- `priceFeedMaxAge`: The maximum age of the price feed in seconds. *Note: This adds a extra safety net to avoid using stale prices.* |
34 | 34 | - `salt`: A unique identifier to create deterministic addresses for deployed oracles. |
35 | 35 |
|
36 | 36 | **Warning:** If there is an ERC4626-compliant vault for `baseVault` or `quoteVault`, the `baseTokenDecimals` or `quoteTokenDecimals` are still the decimals of the underlying asset of the vault, and not the decimals of the Vault itself. |
37 | 37 | E.g: for a MetaMorpho WETH vault, as `baseVault`, the `baseTokenDecimals` is 18 as WETH has 18 decimals. |
38 | 38 |
|
39 | 39 | ### Addresses |
40 | | - |
41 | | -The address on Ethereum of this factory is [0x3A7bB36Ee3f3eE32A60e9f2b33c1e5f2E83ad766](https://etherscan.io/address/0x3a7bb36ee3f3ee32a60e9f2b33c1e5f2e83ad766#code). |
| 40 | +TODO: |
| 41 | +The address on Ethereum of this factory is [](https://etherscan.io/address/#code). |
42 | 42 |
|
43 | 43 | ### Examples |
44 | 44 |
|
45 | | -Below are the arguments to fill for the creation of the WETH/USDT oracle: |
| 45 | +Below are the arguments to fill for the creation of the WBTC/USDT oracle on Base Mainnet: |
46 | 46 |
|
47 | 47 | ```json |
| 48 | +"pyth": "0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a", |
48 | 49 | "baseVault": "0x0000000000000000000000000000000000000000", |
49 | 50 | "baseVaultConversionSample": 1, |
50 | | -"baseFeed1": "0x0000000000000000000000000000000000000000", |
51 | | -"baseFeed2": "0x0000000000000000000000000000000000000000", |
52 | | -"baseTokenDecimals": 18, |
| 51 | +"baseFeed1": "0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33", |
| 52 | +"baseFeed2": "0x0000000000000000000000000000000000000000000000000000000000000000", |
| 53 | +"baseTokenDecimals": 8, |
53 | 54 | "quoteVault":"0x0000000000000000000000000000000000000000", |
54 | 55 | "quoteVaultConversionSample": 1, |
55 | | -"quoteFeed1": "0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46", |
56 | | -"quoteFeed2": "0x0000000000000000000000000000000000000000", |
| 56 | +"quoteFeed1": "0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", |
| 57 | +"quoteFeed2": "0x0000000000000000000000000000000000000000000000000000000000000000", |
57 | 58 | "quoteTokenDecimals": 6, |
| 59 | +"priceFeedMaxAge": 3600, |
58 | 60 | "salt": "<user-defined value used to make the address unique>", |
59 | 61 | ``` |
60 | 62 |
|
61 | | -and for the sDAI/USDC oracle: |
62 | | - |
63 | | -```json |
64 | | -"baseVault": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", |
65 | | -"baseVaultConversionSample": 1000000000000000000, |
66 | | -"baseFeed1": "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9", |
67 | | -"baseFeed2": "0x0000000000000000000000000000000000000000", |
68 | | -"baseTokenDecimals": 18, |
69 | | -"quoteVault": "0x0000000000000000000000000000000000000000", |
70 | | -"quoteVaultConversionSample": 1, |
71 | | -"quoteFeed1": "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6", |
72 | | -"quoteFeed2": "0x0000000000000000000000000000000000000000", |
73 | | -"quoteTokenDecimals": 6, |
74 | | -"salt": "<user-defined value used to make the address unique>", |
75 | | -``` |
76 | | - |
77 | | -and for the wstETH/ETH oracle: |
78 | | - |
79 | | -```json |
80 | | -"baseVault": "0x0000000000000000000000000000000000000000", |
81 | | -"baseVaultConversionSample": 1, |
82 | | -"baseFeed1": "0x905b7dAbCD3Ce6B792D874e303D336424Cdb1421", |
83 | | -"baseFeed2": "0x86392dC19c0b719886221c78AB11eb8Cf5c52812", |
84 | | -"baseTokenDecimals": 18, |
85 | | -"quoteVault": "0x0000000000000000000000000000000000000000", |
86 | | -"quoteVaultConversionSample": 1, |
87 | | -"quoteFeed1": "0x0000000000000000000000000000000000000000", |
88 | | -"quoteFeed2": "0x0000000000000000000000000000000000000000", |
89 | | -"quoteTokenDecimals": 18, |
90 | | -"salt": "<user-defined value used to make the address unique>", |
91 | | -``` |
92 | | - |
93 | | -## WstETH/stETH Exchange Rate Adapter |
94 | | - |
95 | | -A specific implementation, the `WstEthStEthExchangeRateChainlinkAdapter`, provides the exchange rate between wstETH and stETH as a Chainlink-interface-compliant feed. |
96 | | - |
97 | | -This adapter is deployed on the Ethereum Mainnet at the address [0x905b7dAbCD3Ce6B792D874e303D336424Cdb1421](https://etherscan.io/address/0x905b7dabcd3ce6b792d874e303d336424cdb1421#code). |
98 | 63 |
|
99 | 64 | ## Developers |
100 | 65 |
|
101 | | -> [!NOTE] |
102 | | -> `MorphoChainlinkOracleV2Factory` has been deployed on Ethereum and Base with the [metadata hash](https://docs.soliditylang.org/en/latest/metadata.html) included, which appear at two places in the bytecode as it is a factory. |
103 | | -
|
104 | 66 | Install dependencies: `forge install` |
105 | 67 |
|
106 | | -In a `.env` file, set `ETH_RPC_URL` to the URL of an Ethereum provider. |
| 68 | +Install Pyth SDK: |
| 69 | +```bash |
| 70 | +npm init -y |
| 71 | +npm install @pythnetwork/pyth-sdk-solidity |
| 72 | +``` |
107 | 73 |
|
108 | 74 | Run test: `forge test` |
109 | 75 |
|
110 | 76 | ## Audits |
111 | 77 |
|
112 | 78 | All audits are stored in the [audits](./audits/)' folder. |
113 | | - |
114 | | -## License |
115 | | - |
116 | | -Morpho Blue Oracles are licensed under `GPL-2.0-or-later`, see [`LICENSE`](./LICENSE). |
0 commit comments