Deploy an Oracle for Morpho Markets
Deploy and validate a Morpho oracle for curators, covering Chainlink Oracle V2 parameters, price feeds, conversion samples, and post-deployment checks.
Oracle deployment is a critical step when creating lending markets in Morpho, as these smart contracts provide essential price information that powers core functionalities like collateral evaluation and liquidation triggers. This guide will walk you through the entire process of configuring, testing, and deploying an oracle using the Morpho ecosystem tools.
Understanding Oracles in Morpho
Before jumping into deployment, let's review what oracles do in the Morpho ecosystem:
- Purpose: Oracles provide price data that determines what one token is worth relative to another
- Implementation: Morpho takes an oracle-agnostic approach, allowing market creators to choose appropriate price feed mechanisms
- Interface: All oracles implement the
IOracleinterface with a single standardized function:price() - Immutability: Once a market is deployed, its oracle address cannot be modified, making correct setup crucial
The Oracle Deployment Process
This guide covers the complete process of deploying a new oracle using:
- MorphoChainlinkOracleV2Factory: The contract used to create new oracles
- Oracle Tester Tool: A web interface to validate your configuration and prepare deployment
- Oracle Decoder: A tool to run additional checks on your configuration post-deployment
Step 1: Understanding the Oracle Parameters
The MorphoChainlinkOracleV2Factory requires several parameters that determine how the oracle will calculate prices. Let's break them down:
Key Parameters
| Parameter | Description |
|---|---|
baseVault | ERC4626 vault for the collateral token (zero address if not applicable) |
baseVaultConversionSample | Amount of base vault shares for conversion calculation (use 1 if no vault) |
baseFeed1 | First price feed for the collateral token (zero address if not needed) |
baseFeed2 | Second price feed for the collateral token (zero address if not needed) |
baseTokenDecimals | Decimal precision of the base/collateral token |
quoteVault | ERC4626 vault for the loan token (zero address if not applicable) |
quoteVaultConversionSample | Amount of quote vault shares for conversion calculation (use 1 if no vault) |
quoteFeed1 | First price feed for the loan token (zero address if not needed) |
quoteFeed2 | Second price feed for the loan token (zero address if not needed) |
quoteTokenDecimals | Decimal precision of the quote/loan token |
salt | 32-byte value for deterministic address creation (defaults to zero bytes32) |
Common Oracle Configurations
Different asset pairs require different oracle configurations. Here are some common patterns:
- Standard tokens (ETH/USDC): Direct price feed with no vaults
- Wrapped tokens (wstETH/ETH): Requires special exchange rate adapter
- Yield-bearing tokens (sDAI/USDC): Requires vault configuration (sDAI -> DAI -> USD -> USDC or sDAI -> DAI -> USDC)
Step 2: Using the Oracle Tester Tool
The Oracle Tester tool helps you validate your configuration before deployment, saving gas and preventing errors. It is accessible in the Curator App here: curator.morpho.org/oracles/tester.
Basic Steps
Select Network
Choose the blockchain where you'll deploy your oracle. The Oracle Tester and Decoder are limited to the chains supported by the Curator App and Morpho API. Check the network selector for the available chains. A Morpho contract deployment on a chain does not by itself mean these tools support it.
Select Assets
- Choose the Collateral token (the token that will be used as collateral).
- Choose the Loan token (the token that will be borrowed).
- Search by token name or paste its address in either selector.
Advanced Configuration
After selecting your assets, you'll need to fill in the detailed oracle parameters:
Base (Collateral) Configuration
- Base Vault: If your collateral is an ERC4626 token, enter the vault address. Otherwise, use the default zero address (
0x0000000000000000000000000000000000000000). - Base Vault Conv. Sample: Default is 1 if using zero address for Base Vault. For ERC4626 tokens, use a value like
1000000000000000000(1e18) to ensure precision. This value is used to query theconvertToAssetfunction on the Base Vault address you put thus needs enough precision.
- Base Feed 1: The primary price feed for your collateral asset. This could be a Chainlink, Redstone, Pyth, or Chronicle, ...
- Base Feed 2: If needed, a secondary price feed for route calculation. Often the zero address.
- Base Token Decimals: The decimal precision of your collateral token. In most of the case, it should match the actual collateral token decimals. If a Base Vault is put, use the underlying asset decimals. (Eg: if
sDAIis put in Base Vault, useDAIdecimals)
Quote (Loan) Configuration
- Quote Vault: If your loan token is an ERC4626 token, enter the vault address. Otherwise, use the zero address.
- Quote Vault Conv. Sample: Similar to Base Vault Conversion Sample, default is 1.
- Quote Feed 1: Primary price feed for the loan asset.
- Quote Feed 2: Secondary price feed if needed.
- Quote Token Decimals: The decimal precision of your loan token.
Salt Configuration
- Salt: A 32-byte hex value. The form defaults to
0x0000000000000000000000000000000000000000000000000000000000000000(zero bytes32). Changing the salt with the same configuration creates a different oracle address. Use Random salt when you need a new salt.
Scale Factor
Running Tests
After configuring all parameters, click Run checks. Review the results under Oracle review:
- Decimals: Verifies that the configured token decimals match the expected values.
- ERC-4626 loan asset: Checks whether the loan token is an ERC-4626 vault.
- Token behaviour: Checks for token behaviours that can affect compatibility with Morpho.
- Factory deployment: Simulates deploying the oracle and reports if the salt has already been used with these parameters.
- Price check: Compares the calculated oracle price with a USD reference price.
Each check shows its result. Review any warning, failed check, or unavailable result before deployment.
If the Tester reports that the salt has already been used with the same parameters, an oracle may already be deployed. This does not confirm that a market uses it. The Tester flags the collision but does not find the existing oracle for you.
Before deploying another oracle, check existing markets or the factory's CreateMorphoChainlinkOracleV2 events on the chain's explorer. Use the Oracle Decoder to verify the existing oracle's configuration and reuse it if it matches your requirements. Reuse an existing market when all its parameters match, rather than creating an otherwise identical market with a different oracle address. This helps avoid liquidity fragmentation.
Choose Random salt and run the checks again only if you intend to deploy a new oracle.
Generating Deployment Payload
When available, click Download Safe batch JSON to download the deployment transaction. The download is available only when Decimals and Factory deployment pass and no check has failed. Review any remaining warnings or unavailable checks before using the file.
Step 3: Deploying the Oracle
Once you've validated your configuration, you have two options for deployment:
Option A: Deploying via Etherscan
Find the Factory Contract
Navigate to the MorphoChainlinkOracleV2Factory on your chain's explorer (addresses available here).
Fill in the Parameters
- Navigate to the
createMorphoChainlinkOracleV2function - Input all the parameters you validated with the Oracle Tester
- Double-check all values against your test results
Write Contract
- Click "Write" to send the transaction
- Confirm the transaction in your wallet
- Wait for the transaction to be confirmed
Verify Deployment
- Check for the
CreateMorphoChainlinkOracleV2event in the transaction logs - Note the deployed oracle address for future reference
Option B: Deploying via Safe (Multisig)
Prepare the Safe Transaction
- Download the deployment transaction with Download Safe batch JSON in the Oracle Tester.
- Import the JSON file into the Transaction Builder in your Safe.
Review and Submit
- Review all parameters in the Safe interface
- Submit the transaction for signing by your multisig participants
- Execute the transaction once you have the required signatures
Step 4: Final Validation
After deployment, it's crucial to validate that your oracle is working correctly:
Use the Oracle Decoder Tool
- Open the Oracle Decoder in the Curator App.
- Enter your oracle address
- Verify that it returns the expected price for your asset pair
Check the Oracle Price
- Call the
price()function on your deployed oracle - Verify that the returned price is within expected ranges
Example Configurations
Here are detailed examples for common token pairs:
A. cbBTC/USDC Oracle
baseVault: "0x0000000000000000000000000000000000000000", // No Base Vault
baseVaultConversionSample: 1, // Default to 1 as no Base Vault
baseFeed1: "0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c", // BTC/USD Feed
baseFeed2: "0x0000000000000000000000000000000000000000", // - Default to Zero Address
baseTokenDecimals: 8, // BTC Decimals
quoteVault: "0x0000000000000000000000000000000000000000", // No Quote Vault
quoteVaultConversionSample: 1, // Default to 1 as no Quote Vault
quoteFeed1: "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6", // USDC/USD Feed
quoteFeed2: "0x0000000000000000000000000000000000000000", // -
quoteTokenDecimals: 6, // USDC Decimals
salt: "0x0000000000000000000000000000000000000000000000000000000000000000", // one can put any bytes 32 different than a deployed oracle with the very same configurationExplanation:
- This configuration uses a direct BTC/USD price feed for calculating the cbBTC/USD feed price.
- It also uses a USDC/USD quote feed for calculating the USDC/USD feed price.
As USDC/USD is used in the quote section, the final route is: cbBTC -> USD -> USDC.
B. DAI/USDC Oracle - USDC Hardcoded
The particularity in this example is that removing the QuoteFeed1 as it was in previous example acts as if someone was hardcoding the USDC price to 1 in the oracle of the market, because the virtual path is:
baseVault: "0x0000000000000000000000000000000000000000", // -
baseVaultConversionSample: 1, // - default
baseFeed1: "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9", // DAI/USD Feed
baseFeed2: "0x0000000000000000000000000000000000000000", // -
baseTokenDecimals: 18, // DAI Decimals (NOT sDAI decimals)
quoteVault: "0x0000000000000000000000000000000000000000", // -
quoteVaultConversionSample: 1, // -
quoteFeed1: "0x0000000000000000000000000000000000000000", // EMPTY Feed
quoteFeed2: "0x0000000000000000000000000000000000000000", // -
quoteTokenDecimals: 6, // USDC Decimals
salt: "0x0000000000000000000000000000000000000000000000000000000000000000",Explanation: This configuration is using the chainlink price feed for the DAI -> USD part, and is not pricing USDC -> USD on purpose to showcase the USDC hardcoding method.
C. sDAI/USDC Oracle
baseVault: "0x83F20F44975D03b1b09e64809B757c47f942BEeA", // sDAI Vault
baseVaultConversionSample: 1000000000000000000, // 1e18
baseFeed1: "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9", // DAI/USD Feed
baseFeed2: "0x0000000000000000000000000000000000000000", // -
baseTokenDecimals: 18, // DAI Decimals (NOT sDAI decimals)
quoteVault: "0x0000000000000000000000000000000000000000", // -
quoteVaultConversionSample: 1, // -
quoteFeed1: "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6", // USDC/USD Feed
quoteFeed2: "0x0000000000000000000000000000000000000000", // -
quoteTokenDecimals: 6, // USDC Decimals
salt: "0x0000000000000000000000000000000000000000000000000000000000000000",Explanation: This configuration handles a yield-bearing token (sDAI) by specifying its vault address and using a higher conversion sample to account for the share-to-asset conversion. The price feeds are standard Chainlink feeds for the underlying assets.
D. sDAI/USDC Oracle - USDC Hardcoded
baseVault: "0x83F20F44975D03b1b09e64809B757c47f942BEeA", // sDAI Vault
baseVaultConversionSample: 10000000000, // 1e10 - Explanation below
baseFeed1: "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9", // DAI/USD Feed
baseFeed2: "0x0000000000000000000000000000000000000000", // -
baseTokenDecimals: 18, // DAI Decimals (NOT sDAI decimals)
quoteVault: "0x0000000000000000000000000000000000000000", // -
quoteVaultConversionSample: 1, // -
quoteFeed1: "0x0000000000000000000000000000000000000000", // USDC/USD Feed
quoteFeed2: "0x0000000000000000000000000000000000000000", // -
quoteTokenDecimals: 6, // USDC Decimals
salt: "0x0000000000000000000000000000000000000000000000000000000000000000",- Explanation: This configuration handles a yield-bearing token (sDAI) by specifying its vault address and using a high conversion sample (1e10) to account for the share-to-asset conversion. The price feed used in Base Feed 1 is a standard Chainlink feed.
Why baseVaultConversionSample is 1e10 this time?
Sometimes a vault conversion sample that is too high will result in a scale factor of 0 (or even cause a revert at deployment). A solution is to find a tradeoff by reducing the vault conversion sample value (base or quote) while keeping it high enough to maintain precision.
E. wstETH/ETH Oracle
baseVault: "0x0000000000000000000000000000000000000000",
baseVaultConversionSample: 1,
baseFeed1: "0x905b7dAbCD3Ce6B792D874e303D336424Cdb1421", // wstETH/stETH adapter
baseFeed2: "0x86392dC19c0b719886221c78AB11eb8Cf5c52812", // stETH/ETH price feed
baseTokenDecimals: 18,
quoteVault: "0x0000000000000000000000000000000000000000",
quoteVaultConversionSample: 1,
quoteFeed1: "0x0000000000000000000000000000000000000000",
quoteFeed2: "0x0000000000000000000000000000000000000000",
quoteTokenDecimals: 18,
salt: "0x0000000000000000000000000000000000000000000000000000000000000000",Explanation: This configuration uses multiple feeds to establish a price path from wstETH to ETH. It requires a special adapter contract (WstEthStEthExchangeRateChainlinkAdapter) that handles the wstETH to stETH conversion, followed by a standard feed for stETH to ETH.
Troubleshooting Common Issues
Oracle Deployment Errors
| Issue | Solution |
|---|---|
| "Transaction reverted" | Double-check all addresses and ensure they are valid contract addresses |
| "Gas estimation failed" | Your configuration may be invalid or the contract cannot be executed properly |
| "Oracle with same parameters already deployed" | Use the existing oracle (check the deployment check results) |
Price Verification Issues
| Issue | Solution |
|---|---|
| Price significantly deviates from expected | Check that your feeds are correctly configured and that the decimals are accurate |
| Price is zero | Ensure that all required feeds are working and that conversion samples are appropriate |
| Price overflow/underflow | Adjust conversion samples to ensure mathematical operations don't exceed limits |
Best Practices for Oracle Deployment
- Always test before deploying - Use the Oracle Tester tool to validate your configuration.
- Understand token decimals - Incorrect decimal configuration is a common source of errors.
- Use reliable price feeds - Choose established providers like Chainlink, Redstone, Chronicle, API3, Pyth ...
- Check for existing oracles - Reuse existing oracles when possible to save gas and ensure consistency.
- Document your configuration - Keep a record of all parameters for future reference.
- Verify after deployment - Always check that the deployed oracle returns expected prices.
Security Considerations
Since oracles are immutable once deployed and attached to a market, their security is paramount:
- Verify the source code of any adapter contracts you're using
- Understand the price path and how multiple feeds work together
- Consider failure modes in your price feeds and how they could affect the oracle
- Test with extreme market conditions to ensure robustness
Community Contributions
Getting Help
If you encounter issues during the oracle deployment process:
- Get in touch via the chatbox on help.morpho.org
- For complex setups, consider reaching out to the Morpho Association or to a curator directly
By following this guide, you should be able to configure, test, and deploy oracles for your Morpho markets with confidence. Remember that careful setup is essential as oracles play a critical role in market safety and cannot be changed after market deployment.