Please follow this procedure to add an oracle price (USD) for an asset. The team will review its content and approve/deny it. All of the entries need to map towards a USD value.
An oracle price consists of either one or multiple chained values that are multiplied together. For each new asset, the following parameters are necessary:
42 character string that represents the token/asset address. Must be checksummed.
The numerical chain id of this asset. Currently supported:
- 1 (Ethereum Mainnet)
- 8453 (Base)
See Chainlist for reference.
The following types are currently supported:
Chainlink compatible contract that emits AnswerUpdated
log.
Example for ETH/USD price feed:
{
"assetAddress": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"contractAddress": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419",
"order": 0,
"type": "chainlink_aggregator",
"data": "{\"decimals\": 8}",
"assetChainId": 1,
"contractChainId": 1
}
Chainlink compatible contract without event logs.
No example yet.
Contract that exposes a function that returns a numerical exchange rate.
Example for wstETH/stETH rate:
{
"assetAddress": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"contractAddress": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"order": 0,
"type": "exchange_rate",
"data": "{\"abi\": \"function stEthPerToken() view returns (uint256)\", \"decimals\": 18, \"function\": \"stEthPerToken\"}",
"assetChainId": 1,
"contractChainId": 1
}
or wUSDL/USDL rate
{
"assetAddress": "0x7751E2F4b8ae93EF6B79d86419d42FE3295A4559",
"contractAddress": "0x7751E2F4b8ae93EF6B79d86419d42FE3295A4559",
"order": 0,
"type": "exchange_rate",
"data": "{\"abi\": \"function convertToAssets(uint256) view returns (uint256)\", \"decimals\": 18, \"function\": \"convertToAssets\", \"args\": [{\"type\": \"bigint\", \"value\": \"1000000000000000000\"}], \"first_block_number\": 21078732}",
"assetChainId": 1,
"contractChainId": 1
}
Curve tri-crypto pool rate.
{
"assetAddress": "0xAb122ae30b3eE050F0Eb30009DEec6aCC6B06D36",
"contractAddress": "0xf5f5B97624542D72A9E06f04804Bf81baA15e2B4",
"order": 1,
"type": "tri_crypto",
"data": "{\"decimals\": 18, \"first_block_number\": 19083124}",
"assetChainId": 1,
"contractChainId": 1
}
Chronicle oracle feed.
Example:
{
"assetAddress": "0x7122985656e38BDC0302Db86685bb972b145bD3C",
"contractAddress": "0x057f30e63A69175C69A4Af5656b8C9EE647De3D0",
"order": 0,
"type": "chronicle",
"data": "{\"decimals\": 18, \"first_block_number\": 20578895}",
"assetChainId": 1,
"contractChainId": 1
}
API3 oracle feed.
Example:
{
"assetAddress": "0x4956b52aE2fF65D74CA2d61207523288e4528f96",
"contractAddress": "0xAdb2c15Fde49D1A4294740aCb650de94184E66b2",
"order": 0,
"type": "api3",
"data": "{\"decimals\": 8, \"first_block_number\": 21484157}",
"assetChainId": 1,
"contractChainId": 1
}
Pyth Network oracle feed.
{
"assetAddress": "0xeFc0CED4B3D536103e76a1c4c74F0385C8F4Bdd3",
"contractAddress": "0x9975a5C7F4FCCce40B53672F7F46B9E4a85199F7",
"order": 0,
"type": "pyth_network",
"data": "{\"decimals\": 8, \"first_block_number\": 20418093}",
"assetChainId": 1,
"contractChainId": 1
}
Redstone oracle feed without event logs.
Example:
{
"assetAddress": "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee",
"contractAddress": "0x8751F736E94F6CD167e8C5B97E245680FbD9CC36",
"order": 0,
"type": "redstone_without_logs",
"data": "{\"decimals\": 8, \"first_block_number\": 18827200}",
"assetChainId": 1,
"contractChainId": 1
}
Fixed value oracle, typically used for stablecoins.
Example:
{
"assetAddress": "0x09D4214C03D01F49544C0448DBE3A27f768F2b34",
"contractAddress": "0x09D4214C03D01F49544C0448DBE3A27f768F2b34",
"order": 0,
"type": "hardcoded",
"data": "{\"decimals\": 6, \"usd_value\": 1000000, \"first_block_number\": 20883926}",
"assetChainId": 1,
"contractChainId": 1
}
Pendle protocol asset rate. Here it is a bit particular.
One should provide, as a contract address, the market existing, linked to the PT asset.
E.g: PT-LBTC-27MAR2025.
0x70B70Ac0445C3eF04E314DFdA6caafd825428221
is the market address for PT-LBTC-27MAR2025 (0xEc5a52C685CC3Ad79a6a347aBACe330d69e0b1eD
).
Internally, we are computing the ptToAssetRate
, on this contract 0x9a9Fa8338dd5E5B2188006f1Cd2Ef26d921650C2
thanks to the market address.
{
"assetAddress": "0xEc5a52C685CC3Ad79a6a347aBACe330d69e0b1eD",
"contractAddress": "0x70B70Ac0445C3eF04E314DFdA6caafd825428221",
"order": 0,
"type": "pendle_asset_rate",
"data": "{\"decimals\": 18, \"first_block_number\": 21163666}",
"assetChainId": 1,
"contractChainId": 1
},
Hash note oracle feed.
{
"assetAddress": "0x136471a34f6ef19fE571EFFC1CA711fdb8E49f2b",
"contractAddress": "0x4c48bcb2160F8e0aDbf9D4F3B034f1e36d1f8b3e",
"order": 0,
"type": "hash_note",
"data": "{\"decimals\": 8}",
"assetChainId": 1,
"contractChainId": 1
}
The 0-starting index order of the oracle/exchange rate entry for an asset. When multiple entries exist for the same asset, they are multiplied together in order to get the final USD price.
JSON string containing configuration for the oracle:
decimals
: Required. Number between 0-18 representing the decimal precisionabi
: Optional. ABI string for function calls (required for exchange_rate type)function
: Optional. Function name to call (required for exchange_rate type)args
: Optional. Array of arguments for the function callfirst_block_number
: Optional. Block number when the oracle became activeusd_value
: Optional. Fixed USD value for hardcoded type (in base units)
- Addresses must be checksummed
- Chain IDs must be either 1 (Ethereum) or 8453 (Base)
- Orders must start from 0 and be sequential for each asset
- Data field must contain valid decimals between 0-18
- Type must be one of the supported types
To add mappings, simply add the entries to the oracle-prices.json file.
Here are the entries required to add an oracle price for wstETH
on ETH mainnet, which requires both the wstETH/stETH rate and the stETH/USD price:
[
{
"assetAddress": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"contractAddress": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"order": 0,
"type": "exchange_rate",
"data": "{\"abi\": \"function stEthPerToken() view returns (uint256)\", \"decimals\": 18, \"function\": \"stEthPerToken\"}",
"assetChainId": 1,
"contractChainId": 1
},
{
"assetAddress": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"contractAddress": "0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8",
"order": 1,
"type": "chainlink_aggregator",
"data": "{\"decimals\": 8}",
"assetChainId": 1,
"contractChainId": 1
}
]
Some assets are not supported by the current oracle types. By default the type Redstone_without_logs still allows the pricing of them, as it simply queries the latestRoundData
method.
Exhaustive list of assets that are not supported:
- 0xb4B8925c4CBce692F37C9D946883f2E330a042a9 // PT-sdeUSD-1753142406 - Spectra - Mainnet
- 0x2a8c22E3b10036f3AEF5875d04f8441d4188b656 // mBASIS - Midas - Mainnet
- 0x1C2757c1FeF1038428b5bEF062495ce94BBe92b2 // mBASIS - Midas - Base 3.2 0x40b7B4aB1E95e28DF06971581276966FDF95688E // PT-beraSTONE-10APR2025 - Pendle - Mainnet 3.3 0x50D2C7992b802Eef16c04FeADAB310f31866a545 // PT-eUSDE-29MAY2025 - Pendle - Mainnet
- 0xbB51E2a15A9158EBE2b0Ceb8678511e063AB7a55 // mEDGE - Midas - Mainnet
- 0xE15578523937ed7F08E8F7a1Fa8a021E07025a08 // LP-USR-24APR2025 - Base