|
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