From 889691341bab97a09941fd28cd6fc29aaf44b52b Mon Sep 17 00:00:00 2001 From: antoncoding Date: Thu, 4 Sep 2025 15:38:42 +0800 Subject: [PATCH 01/19] fix: quick search input --- app/markets/components/AdvancedSearchBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/markets/components/AdvancedSearchBar.tsx b/app/markets/components/AdvancedSearchBar.tsx index 380e8dd2..9335701d 100644 --- a/app/markets/components/AdvancedSearchBar.tsx +++ b/app/markets/components/AdvancedSearchBar.tsx @@ -193,8 +193,8 @@ function AdvancedSearchBar({ onFocus={handleInputFocus} endContent={} classNames={{ - inputWrapper: 'bg-surface rounded-sm w-full lg:w-[600px]', - input: 'bg-surface rounded-sm text-xs', + inputWrapper: 'bg-surface rounded-sm w-full lg:w-[600px] focus-within:outline-none', + input: 'bg-surface rounded-sm text-xs focus:outline-none', }} autoComplete="off" /> From 32bd787df99819ffaf9e3f681455737f6c273c63 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Thu, 4 Sep 2025 17:14:36 +0800 Subject: [PATCH 02/19] feat: chainlink data --- src/components/FeedInfo/OracleFeedInfo.tsx | 9 + src/constants/chainlink-data/README | 10 + src/constants/chainlink-data/base.json | 5890 ++++++++++ src/constants/chainlink-data/index.ts | 83 + src/constants/chainlink-data/mainnet.json | 11648 +++++++++++++++++++ src/constants/chainlink-data/polygon.json | 1014 ++ src/constants/chainlink-data/types.ts | 19 + 7 files changed, 18673 insertions(+) create mode 100644 src/constants/chainlink-data/README create mode 100644 src/constants/chainlink-data/base.json create mode 100644 src/constants/chainlink-data/index.ts create mode 100644 src/constants/chainlink-data/mainnet.json create mode 100644 src/constants/chainlink-data/polygon.json create mode 100644 src/constants/chainlink-data/types.ts diff --git a/src/components/FeedInfo/OracleFeedInfo.tsx b/src/components/FeedInfo/OracleFeedInfo.tsx index 8774a445..33066524 100644 --- a/src/components/FeedInfo/OracleFeedInfo.tsx +++ b/src/components/FeedInfo/OracleFeedInfo.tsx @@ -9,6 +9,8 @@ import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; import { OracleVendors, OracleVendorIcons } from '@/utils/oracle'; import { OracleFeed } from '@/utils/types'; +import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data'; +import { useMemo } from 'react'; export function OracleFeedInfo({ feed, @@ -19,6 +21,13 @@ export function OracleFeedInfo({ }): JSX.Element | null { if (!feed) return null; + const chainlinkFeedData = useMemo(() => { + if (!feed || !feed.address) return undefined; + return getChainlinkOracle(chainId, feed.address as Address); + }, [chainId, feed.address]) + + console.log('chainlinkFeedData', chainlinkFeedData); + const fromAsset = feed.pair?.[0] ?? 'Unknown'; const toAsset = feed.pair?.[1] ?? 'Unknown'; diff --git a/src/constants/chainlink-data/README b/src/constants/chainlink-data/README new file mode 100644 index 00000000..334b180d --- /dev/null +++ b/src/constants/chainlink-data/README @@ -0,0 +1,10 @@ +# Chainlink Oracle Data + +## The json files in this folder are collected by visiting [Chainlink Docs](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1), and using corresponding "apis" to get the full list based on networks: +* Mainnet: https://reference-data-directory.vercel.app/feeds-mainnet.json +* Base: https://reference-data-directory.vercel.app/feeds-ethereum-mainnet-base-1.json +* Polygon: https://reference-data-directory.vercel.app/feeds-polygon-mainnet-katana.json +* Optimism: https://reference-data-directory.vercel.app/feeds-ethereum-mainnet-optimism-1.json +* Arbitrum: https://reference-data-directory.vercel.app/feeds-ethereum-mainnet-arbitrum-1.json + + diff --git a/src/constants/chainlink-data/base.json b/src/constants/chainlink-data/base.json new file mode 100644 index 00000000..f666fb09 --- /dev/null +++ b/src/constants/chainlink-data/base.json @@ -0,0 +1,5890 @@ +[ + { + "compareOffchain": "", + "contractAddress": "0x00480f7Df64d3711940E956c2Ca0C47Cc48240eB", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "susds-usds-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "sUSDS / USDS Exchange Rate", + "pair": [ + "", + "" + ], + "path": "susds-usds-exchange-rate", + "proxyAddress": "0x906B24a339b848369B24Dc9Ed368b947fB9693bf", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "sUSDS / USDS Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "sUSDS", + "baseAssetClic": "sUSDS_CR", + "blockchainName": "Base", + "clicProductName": "sUSDS/USDS-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "sUSDS", + "quoteAssetClic": "sUSDS_CR", + "underlyingAsset": "USDS", + "underlyingAssetClic": "USDS_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x00be872906C07d6d7D0eC3968b99C4e3D6Bd552a", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ezeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ezETH / ETH", + "pair": [ + "", + "" + ], + "path": "ezeth-eth", + "proxyAddress": "0x960BDD1dFD20d7c98fa482D793C3dedD73A113a3", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Renzo Restaked ETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "EZETH", + "baseAssetClic": "EZETH_CR", + "blockchainName": "Base", + "clicProductName": "EZETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x038fa58bd4DA1c938D2783941e657164D497C4B6", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "axl-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "AXL / USD", + "pair": [ + "", + "" + ], + "path": "axl-usd", + "proxyAddress": "0x676C4C6C31D97A5581D3204C04A8125B350E2F9D", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Axelar", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AXL", + "baseAssetClic": "AXL_CR", + "blockchainName": "Base", + "clicProductName": "AXL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x04030d2F38Bc799aF9B0AaB5757ADC98000D7DeD", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wstethsteth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "wstETH-stETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "wsteth-steth exchangerate", + "proxyAddress": "0xB88BAc61a4Ca37C43a3725912B1f472c9A5bc061", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Wrapped stETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "wstETH", + "baseAssetClic": "wstETH_CR", + "blockchainName": "Base", + "clicProductName": "wstETH/stETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "stETH", + "quoteAssetClic": "stETH_CR", + "underlyingAsset": "STETH", + "underlyingAssetClic": "STETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x04d3d700150E03eD1Df763363D746F0E9dEE3BDD", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "susdz-usdz-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "sUSDz / USDz Exchange Rate", + "pair": [ + "", + "" + ], + "path": "susdz-usdz-exchange-rate", + "proxyAddress": "0xD89c7fFB39C44b17EAecd8717a75A36c19C07582", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "sUSDz / USDz Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "sUSDz", + "baseAssetClic": "sUSDz_CR", + "blockchainName": "Base", + "clicProductName": "sUSDz/USDz-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USDz", + "quoteAssetClic": "USDz_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x05acfeE2c0b4efbBCe705932239A30613aCE42f2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "woeth-oeth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "wOETH / OETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "woeth-oeth-exchange-rate", + "proxyAddress": "0xe96EB1EDa83d18cbac224233319FA5071464e1b9", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped OETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "wOETH", + "baseAssetClic": "wOETH_CR", + "blockchainName": "Base", + "clicProductName": "wOETH/OETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "OETH", + "quoteAssetClic": "OETH_CR", + "underlyingAsset": "OETH", + "underlyingAssetClic": "OETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x08F9654349B33B955133b28e35dbEcCe9950c219", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "CBETH / ETH", + "pair": [ + "", + "" + ], + "path": "cbeth-eth", + "proxyAddress": "0x806b4Ac04501c29769051e42783cF04dCE41440b", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Coinbase Wrapped Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "CBETH", + "baseAssetClic": "CBETH_CR", + "blockchainName": "Base", + "clicProductName": "CBETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x093e52c967391A87732956121509b9594B02F153", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "brl-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "BRL / USD", + "pair": [ + "", + "" + ], + "path": "brl-usd", + "proxyAddress": "0x0b0E64c05083FdF9ED7C5D3d8262c4216eFc9394", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Brazilian Real", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "BRL", + "baseAssetClic": "BRL_FX", + "blockchainName": "Base", + "clicProductName": "BRL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_BRL", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0C731e5985798B2B8374cA7e4F7AfDD174b1b74f", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "tbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TBTC / USD", + "pair": [ + "", + "" + ], + "path": "tbtc-usd", + "proxyAddress": "0x6D75BFB5A5885f841b132198C9f0bE8c872057BF", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "tBTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "tBTC", + "baseAssetClic": "tBTC_CR", + "blockchainName": "Base", + "clicProductName": "tBTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0D4D5dC9cCf0c9e3028321a777B37Aa45Bc8fe87", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "lbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LBTC / USD", + "pair": [ + "", + "" + ], + "path": "lbtc-usd", + "proxyAddress": "0x9e07546c9Fe8868855CD04B26051a26D1599E270", + "threshold": 1, + "valuePrefix": "", + "assetName": "Lombard Staked BTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LBTC", + "baseAssetClic": "LBTC_CR", + "blockchainName": "Base", + "clicProductName": "LBTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0Ee7145e1370653533e2F2E824424bE2AA95A4Aa", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "USDC / USD", + "pair": [ + "", + "" + ], + "path": "usdc-usd", + "proxyAddress": "0x7e860098F58bBFC8648a4311b374B1D669a2bc6B", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Circle USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDC", + "baseAssetClic": "USDC_CR", + "blockchainName": "Base", + "clicProductName": "USDC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0F83393dB40FC0417D8aF7A2192212C57F62Be52", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "rdnt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "RDNT / USD", + "pair": [ + "", + "" + ], + "path": "rdnt-usd", + "proxyAddress": "0xEf2E24ba6def99B5e0b71F6CDeaF294b02163094", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Radiant Capital", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RDNT", + "baseAssetClic": "RDNT_CR", + "blockchainName": "Base", + "clicProductName": "RDNT/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0FC7044a83a1Bd1c0661faf26A48D96902e2b5A5", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USR / USD", + "pair": [ + "", + "" + ], + "path": "usr-usd", + "proxyAddress": "0x4a595E0a62E50A2E5eC95A70c8E612F9746af006", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Resolv USR", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USR", + "baseAssetClic": "USR_CR", + "blockchainName": "Base", + "clicProductName": "USR/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x11884a84125eCbC089291cA85288352feC2630de", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "syrupusdcusdc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "syrupUSDC-USDC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "syrupusdc-usdc-exchange-rate", + "proxyAddress": "0x311D3A3faA1d5939c681E33C2CDAc041FF388EB2", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "syrupUSDC-USDC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "syrupUSDC", + "baseAssetClic": "syrupUSDC_CR", + "blockchainName": "Base", + "clicProductName": "syrupUSDC/USDC-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USDC", + "quoteAssetClic": "USDC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x11da1FC2BF92316931E8978A23928D058fC57f5A", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "zar-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "ZAR / USD", + "pair": [ + "", + "" + ], + "path": "zar-usd", + "proxyAddress": "0x2ecc8A8B370fC6a217166b2782a35339bEBEe98B", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "South African Rand", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "ZAR", + "baseAssetClic": "ZAR_FX", + "blockchainName": "Base", + "clicProductName": "ZAR/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x12Cc14513c923dd197139E8280852c9ed2575271", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbxrp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CBXRP / USD", + "pair": [ + "", + "" + ], + "path": "cbxrp-usd", + "proxyAddress": "0xEEe1a9D5A0C36d99972C057Cb959267e88Ab9160", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Coinbase Wrapped XRP", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CBXRP", + "baseAssetClic": "CBXRP_CR", + "blockchainName": "Base", + "clicProductName": "CBXRP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "finalto", + "compareOffchain": "", + "contractAddress": "0x12c97C24eDFf0A1693ff1eF00ee413b5B8Bbae2E", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "sgd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SGD / USD", + "pair": [ + "", + "" + ], + "path": "sgd-usd", + "proxyAddress": "0x81575495532fB311Efc5C993B612564274F0949b", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Singapore Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "SGD", + "baseAssetClic": "SGD_FX", + "blockchainName": "Base", + "clicProductName": "SGD/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x1564DF754C268d6402e1d5D55C288A83ABd9f5EC", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "teth-wsteth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "tETH / wstETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "teth-wsteth-exchange-rate", + "proxyAddress": "0x8004571d9f54dE016fc3D448e7AEe2d70947727A", + "threshold": 0.0002, + "valuePrefix": "", + "assetName": "Treehouse ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "tETH", + "baseAssetClic": "tETH_CR", + "blockchainName": "Base", + "clicProductName": "tETH/wstETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "wstETH", + "quoteAssetClic": "wstETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x1628C5a2c844ED77036Fd04e4BB8e9DA5A869801", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ineth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "inETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "ineth-eth-exchange-rate", + "proxyAddress": "0x83ac12dBb5Bd7Fa597ab2FFEc9F2F13DeDdFe163", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Inception Restaked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "INETH", + "baseAssetClic": "INETH_CR", + "blockchainName": "Base", + "clicProductName": "INETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x16f542BC40723DfE8976A334564eF0c3CfD602Fd", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbeth-eth-exchange", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "cbETH-ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "cbeth-eth-exchange", + "proxyAddress": "0x868a501e68F3D1E89CfC0D22F6b22E8dabce5F04", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "cbETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "cbETH", + "baseAssetClic": "cbETH_CR", + "blockchainName": "Base", + "clicProductName": "cbETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x19e6821Ee47a4c23E5971fEBeE29f78C2e514DC8", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "weeth-eeth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "weETH / eETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "weeth-eeth-exchange-rate", + "proxyAddress": "0x35e9D7001819Ea3B39Da906aE6b06A62cfe2c181", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped eETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "weETH", + "baseAssetClic": "weETH_CR", + "blockchainName": "Base", + "clicProductName": "weETH/eETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "eETH", + "quoteAssetClic": "eETH_CR", + "underlyingAsset": "eETH", + "underlyingAssetClic": "eETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x205B614B4cE3c56db1c8408ed54414f13185DD05", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "yneth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ynETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "yneth-eth-exchange-rate", + "proxyAddress": "0xb4482096e3cdE116C15fC0D700a73a58FEdeB8c0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "YieldNest Restaked ETH Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "ynETH", + "baseAssetClic": "ynETH_CR", + "blockchainName": "Base", + "clicProductName": "ynETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x21b1E4eA0E9AE2e79932662300eB12A0f90AbE59", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "dai-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "DAI / USD", + "pair": [ + "", + "" + ], + "path": "dai-usd", + "proxyAddress": "0x591e79239a7d679378eC8c847e5038150364C78F", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "DAI", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "DAI", + "baseAssetClic": "DAI_CR", + "blockchainName": "Base", + "clicProductName": "DAI/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x222d25e4dEacAb0eE03E0cb282Ab3F602dED6EF2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wrsetheth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "wrsETH-ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "wrseth-eth-exchange-rate", + "proxyAddress": "0xe8dD07CCf5BC4922424140E44Eb970F5950725ef", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped rsETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "wrsETH", + "baseAssetClic": "wrsETH_CR", + "blockchainName": "Base", + "clicProductName": "wrsETH/rsETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "rsETH", + "quoteAssetClic": "rsETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x233A45BF331B35440D45e9BEB1fdF2FbB7B4e3D2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ezeth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ezETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "ezeth-eth-exchange-rate", + "proxyAddress": "0xC4300B7CF0646F0Fe4C5B2ACFCCC4dCA1346f5d8", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Renzo Restaked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "EZETH", + "baseAssetClic": "EZETH_CR", + "blockchainName": "Base", + "clicProductName": "EZETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x23c463c4fB13fFC8c20a1Bdd71A928686eD3A4A2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "xdc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 14400, + "history": null, + "multiply": "100000000", + "name": "XDC / USD", + "pair": [ + "", + "" + ], + "path": "xdc-usd", + "proxyAddress": "0x237A94A589DD38DF7e50CeFDa0b8916a54d01ecC", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "XDC Network", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "XDC", + "baseAssetClic": "XDC_CR", + "blockchainName": "Base", + "clicProductName": "XDC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x23e47A253776F1Fce32e5F2D5D342ca5D6Edd226", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "op-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "OP / USD", + "pair": [ + "", + "" + ], + "path": "op-usd", + "proxyAddress": "0x3E3A6bD129A63564FE7abde85FA67c3950569060", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Optimism", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "OP", + "baseAssetClic": "OP_CR", + "blockchainName": "Base", + "clicProductName": "OP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x253Fe73DfBa6d099d081b1caf0E2B33e02F79d9b", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ngn-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "NGN / USD", + "pair": [ + "", + "" + ], + "path": "ngn-usd", + "proxyAddress": "0xdfbb5Cbc88E382de007bfe6CE99C388176ED80aD", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Nigerian Naira", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "NGN", + "baseAssetClic": "NGN_FX", + "blockchainName": "Base", + "clicProductName": "NGN/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_NGN", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x290B97eb30Af8Ed088659D6738e314069d71352b", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "link-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "LINK / ETH", + "pair": [ + "", + "" + ], + "path": "link-eth", + "proxyAddress": "0xc5E65227fe3385B88468F9A01600017cDC9F3A12", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "baseAssetClic": "LINK_CR", + "blockchainName": "Base", + "clicProductName": "LINK/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x29a0BF5D5e677d38f7AbBd4d292895a3574796C0", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usde-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDe / USD", + "pair": [ + "", + "" + ], + "path": "usde-usd", + "proxyAddress": "0x790181e93e9F4Eedb5b864860C12e4d2CffFe73B", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethena USDe", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDE", + "baseAssetClic": "USDE_CR", + "blockchainName": "Base", + "clicProductName": "USDE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "NONE", + "compareOffchain": "", + "contractAddress": "0x2Ed8E3264f82FF609bc07A1313e02aF9576d66e8", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "php-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "PHP / USD", + "pair": [ + "", + "" + ], + "path": "php-usd", + "proxyAddress": "0x0396000dc82bfAEe746A9Ac6dC69dAd3223Ca9c6", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Philippine Peso", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "PHP", + "baseAssetClic": "PHP_FX", + "blockchainName": "Base", + "clicProductName": "PHP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_PHP", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x2a87b8BC32Abf977c713785E6389F6FaB9C5b555", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "real-final-sales-to-private-domestic-purchasers-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "Real Final Sales to Private Domestic Purchasers — Level", + "pair": [ + "", + "" + ], + "path": "real-final-sales-to-private-domestic-purchasers-level", + "proxyAddress": "0x65623109aA4561AD3cfF503542083548CeD7e085", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "B of Chained 2017 USD", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0x3177D9723D68D900B3c74DaA6C484992142BF856", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usds-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDS / USD", + "pair": [ + "", + "" + ], + "path": "usds-usd", + "proxyAddress": "0x2330aaE3bca5F05169d5f4597964D44522F62930", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "USDS", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDS", + "baseAssetClic": "USDS_CR", + "blockchainName": "Base", + "clicProductName": "USDS/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x330eC3210511cC8f5A87A737A08905092e033AF3", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbeth-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 1200, + "history": false, + "multiply": "100000000", + "name": "CBETH / USD", + "pair": [ + "", + "" + ], + "path": "cbeth-usd", + "proxyAddress": "0xd7818272B9e248357d13057AAb0B417aF31E817d", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Coinbase Wrapped Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "CBETH", + "baseAssetClic": "CBETH_CR", + "blockchainName": "Base", + "clicProductName": "CBETH/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x334d43dA7dBb0a6b66A7282250Ff69dEC97B58B7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wmtx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WMTx / USD", + "pair": [ + "", + "" + ], + "path": "wmtx-usd", + "proxyAddress": "0x311681f6E0b34670Fb03e066cc08C6D09149a44c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "World Mobile Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "WMTx", + "baseAssetClic": "WMTx_CR", + "blockchainName": "Base", + "clicProductName": "WMTx/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x33CDd3f7259327E0f124398A19c25Ac143776bC1", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "inwsteth-wsteth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "inwstETH / wstETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "inwsteth-wsteth-exchange-rate", + "proxyAddress": "0xb58c5C550Ba19c4CEeE071F8CeeB58f8770e6978", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 18 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x36ef9EE769dCea734A14d0745AF7Af14969Aa5fD", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "sui-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SUI / USD", + "pair": [ + "", + "" + ], + "path": "sui-usd", + "proxyAddress": "0x491a921c41d6a97C57426E0c0108a231cd6E5f60", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Sui", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUI", + "blockchainName": "Base", + "clicProductName": "SUI/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3A6D121bF125Fc0909babC708E0Ca1fe4A02d2a4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "xau-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "XAU / USD", + "pair": [ + "", + "" + ], + "path": "xau-usd", + "proxyAddress": "0x5213eBB69743b85644dbB6E25cdF994aFBb8cF31", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Gold", + "feedCategory": "low", + "feedType": "Commodities", + "docs": { + "assetClass": "Commodity", + "assetSubClass": "Spot", + "baseAsset": "XAU", + "baseAssetClic": "XAU_CO", + "blockchainName": "Base", + "clicProductName": "XAU/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Precious_Metals", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "finalto", + "compareOffchain": "", + "contractAddress": "0x3f9925c8c5123F7d7333B447A8909eBe0dF1B6bF", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "gbp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "GBP / USD", + "pair": [ + "", + "" + ], + "path": "gbp-usd", + "proxyAddress": "0xCceA6576904C118037695eB71195a5425E69Fa15", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "British Pound", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "GBP", + "baseAssetClic": "GBP_FX", + "blockchainName": "Base", + "clicProductName": "GBP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x41414C39811D9Dce7feDda7522199Fb3410EF95a", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "yusd-usd-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "1000000000000000000", + "name": "yUSD / USD Exchange Rate", + "pair": [ + "", + "" + ], + "path": "yUSD-USD", + "proxyAddress": "0xc1a849217F3BaB97F1a46b990e369D6705B4be96", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "yUSD / USD Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "yUSD", + "baseAssetClic": "yUSD_CR", + "blockchainName": "Base", + "clicProductName": "yUSD/USD-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x41F3a42270f161Ad1b25Cdb06bAd6cFC123E5C99", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mag7ssi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MAG7.SSI / USD", + "pair": [ + "", + "" + ], + "path": "mag7.ssi-usd", + "proxyAddress": "0x2B1de6AD89847C11aF2ede14edB013AA79E94aC9", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "MAG7.ssi", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MAG7.SSI", + "baseAssetClic": "MAG7.SSI_CR", + "blockchainName": "Base", + "clicProductName": "MAG7.SSI/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x43F92e6805196FA6cd7a19F3d769957f95Baa261", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "arkb-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ARKB Reserves", + "pair": [ + "", + "" + ], + "path": "arkb-reserves", + "proxyAddress": "0xB366E8Efb9661323ff477CedF70f55F897D6cFeA", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "ARK 21Shares BTC ETF", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "ETF", + "assetSubClass": "US", + "baseAsset": "ARK_21Shares_BTC_ETF", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "21Shares", + "porAuditor": "Cross-chain / Bitcoin Network", + "porSource": "Custodian API", + "porType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x45867eb09bB39766eBCee7fF9dCDFb6f6CC6f8DA", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbbtc-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "cbBTC Reserves", + "pair": [ + "", + "" + ], + "path": "cbbtc-por", + "proxyAddress": "0x0F8E057D1D7b282EF968D26E9cB432617dF52519", + "threshold": 0.5, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "cbBTC", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "Coinbase ", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x47c2FE5038bD59A3a80DA6026201F07b0eD76575", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdm-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDM / USD", + "pair": [ + "", + "" + ], + "path": "usdm-usd", + "proxyAddress": "0xF7742A6f36e9936CeA0E976bF6CD3930C1178775", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Mountain Protocol USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDM", + "baseAssetClic": "USDM_CR", + "blockchainName": "Base", + "clicProductName": "USDM/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x484Cc23Fee336291E3C8803cF27e16B9BEe68744", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "reth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "RETH / ETH", + "pair": [ + "", + "" + ], + "path": "reth-eth", + "proxyAddress": "0xf397bF97280B488cA19ee3093E81C0a77F02e9a5", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Rocket Pool ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RETH", + "baseAssetClic": "RETH_CR", + "blockchainName": "Base", + "clicProductName": "RETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x4C83489A62d52eE68a800Dd09410f790A14A5d95", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "weth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "wstETH-ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "weth-eth", + "proxyAddress": "0xa669E5272E60f78299F4824495cE01a3923f4380", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped stETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WSTETH", + "baseAssetClic": "WSTETH_CR", + "blockchainName": "Base", + "clicProductName": "WSTETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x4D1d9223B5d6806815506b9Ba034dD35390Aad68", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "weeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "weETH / ETH", + "pair": [ + "", + "" + ], + "path": "weeth-eth", + "proxyAddress": "0xFC1415403EbB0c693f9a7844b92aD2Ff24775C65", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped eETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "weETH", + "baseAssetClic": "weETH_CR", + "blockchainName": "Base", + "clicProductName": "weETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x4a61dB12d0Cb4293d799ecdD82e5994B5746f850", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "rseth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "RSETH / ETH", + "pair": [ + "", + "" + ], + "path": "rseth-eth", + "proxyAddress": "0xd7221b10FBBC1e1ba95Fd0B4D031C15f7F365296", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Kelp DAO Restaked ETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RSETH", + "blockchainName": "Base", + "clicProductName": "RSETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x4b08a30c6208681eFF2980981057ce4C8bCB2310", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "eur-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "EUR / USD", + "pair": [ + "", + "" + ], + "path": "eur-usd", + "proxyAddress": "0xc91D87E81faB8f93699ECf7Ee9B44D11e1D53F0F", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Euro", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "EUR", + "baseAssetClic": "EUR_FX", + "blockchainName": "Base", + "clicProductName": "EUR/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4d07037b0cFeebb796e54D88F6304675FD30EB6d", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wstusr-stusr-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "wstUSR / stUSR Exchange Rate", + "pair": [ + "", + "" + ], + "path": "wstusr-stusr-exchange-rate", + "proxyAddress": "0x0594c1a01375c1151c2ca78BE4870836EbFA9846", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Resolv wstUSR", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "wstUSR", + "baseAssetClic": "wstUSR_CR", + "blockchainName": "Base", + "clicProductName": "wstUSR/stUSR-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "stUSR", + "quoteAssetClic": "stUSR_CR", + "underlyingAsset": "USR", + "underlyingAssetClic": "USR_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x52A12E019826C53B1f7Fd3E6D9546c0935377B95", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 1200, + "history": null, + "multiply": "100000000", + "name": "cbBTC / USD", + "pair": [ + "", + "" + ], + "path": "cbbtc-usd", + "proxyAddress": "0x07DA0E54543a844a80ABE69c8A12F22B3aA59f9D", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Coinbase Wrapped Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "CBBTC", + "baseAssetClic": "CBBTC_CR", + "blockchainName": "Base", + "clicProductName": "CBBTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x52baE0b6d130E1F10d48c1675AF852F28E653418", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pce-price-index-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "PCE Price Index — Level", + "pair": [ + "", + "" + ], + "path": "pce-price-index-level", + "proxyAddress": "0x18A3fcA54FaC5B05837205bA4b823fc56191F793", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0x52d743436F6bA414050bD8869C8bF6537C355A00", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "dlcbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "dlcBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "dlcbtc-por", + "proxyAddress": "0x30A76F4E688Cf52f4A06D7AAd987A7037f3Ae6f7", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "dlcBTC", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "DLC.LINK", + "hidden": true, + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x5387a1EA9361BD8A2AA1BE68E1e10bd566eECFa4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "xrp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "XRP / USD", + "pair": [ + "", + "" + ], + "path": "xrp-usd", + "proxyAddress": "0x9f0C1dD78C4CBdF5b9cf923a549A201EdC676D34", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "XRP", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "XRP", + "baseAssetClic": "XRP_CR", + "blockchainName": "Base", + "clicProductName": "XRP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x55012EF027ae9b4E2bb5a5f529E5a1184Bcc998D", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ogn-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "OGN / USD", + "pair": [ + "", + "" + ], + "path": "ogn-usd", + "proxyAddress": "0x91D7AEd72bF772A0DA30199B925aCB866ACD3D9e", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Origin Protocol", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "OGN", + "baseAssetClic": "OGN_CR", + "blockchainName": "Base", + "clicProductName": "OGN/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5526525178A842eB07e54cAE0d30c967d74bd0b7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "reth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "rETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "reth-eth-exchange-rate", + "proxyAddress": "0x1E6A29666288a310326B37d823Fe4Ea3937424D2", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "rETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "rETH", + "baseAssetClic": "rETH_CR", + "blockchainName": "Base", + "clicProductName": "rETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x57d2d46Fc7ff2A7142d479F2f59e1E3F95447077", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "eth-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 1200, + "history": false, + "multiply": "100000000", + "name": "ETH / USD", + "pair": [ + "", + "" + ], + "path": "eth-usd", + "proxyAddress": "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Base", + "clicProductName": "ETH/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x59B13FabB34DD4BC398B896b5018c8714BEF7b6d", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "idr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "IDR / USD", + "pair": [ + "", + "" + ], + "path": "idr-usd", + "proxyAddress": "0x05A6cF213EcC5501A11a08EBefA4A8a60313ef97", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Indonesian Rupiah", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "IDR", + "baseAssetClic": "IDR_FX", + "blockchainName": "Base", + "clicProductName": "IDR/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Forex_IDR", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x59F798E5999c65702a417F9485863698ee1678a4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "try-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "TRY / USD", + "pair": [ + "", + "" + ], + "path": "try-usd", + "proxyAddress": "0x29413773e7CD4Dfd6Ad89a50887877b88a6C592C", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Turkish Lira", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "TRY", + "baseAssetClic": "TRY_FX", + "blockchainName": "Base", + "clicProductName": "TRY/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5d427E797C665Ad7413a4e0fF4ceB3E31959C4C5", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "sfrxeth-frxeth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "sfrxETH-frxETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "sfrxETH-frxETH", + "proxyAddress": "0x1Eba1d6941088c8FCE2CbcaC80754C77871aD093", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Staked Frax Ether", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "sfrxETH", + "baseAssetClic": "sfrxETH_CR", + "blockchainName": "Base", + "clicProductName": "sfrxETH/frxETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "frxETH", + "quoteAssetClic": "frxETH_CR", + "underlyingAsset": "FRXETH", + "underlyingAssetClic": "FRXETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x606c6ecBD272E2174F6710b5974F23fE9899602e", + "contractType": "", + "contractVersion": 100, + "decimalPlaces": 9, + "ens": "l2-sequencer-uptime-status-feed", + "formatDecimalPlaces": 0, + "healthPrice": "", + "history": false, + "multiply": "1", + "name": "L2 Sequencer Uptime Status Feed", + "pair": [ + "", + "" + ], + "path": "l2-sequencer-uptime-status-feed", + "proxyAddress": "0xBCF85224fc0756B9Fa45aA7892530B47e10b6433", + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "hidden": true, + "productSubType": "Health Check", + "productType": "Blockchain", + "productTypeCode": "Health" + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x6135E62caFDCcFA9bAcA39b4C9Cbf8bb69908B5a", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "avail-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AVAIL / USD", + "pair": [ + "", + "" + ], + "path": "avail-usd", + "proxyAddress": "0x947eD6A3664fCE27a365b720286c01074d3782E0", + "threshold": 2, + "valuePrefix": "", + "assetName": "Avail", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AVAIL", + "baseAssetClic": "AVAIL_CR", + "blockchainName": "Base", + "clicProductName": "AVAIL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6228A44Cd0Ec29c3373C9742e4bBAF6f2E536B9A", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "comp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "COMP / USD", + "pair": [ + "", + "" + ], + "path": "comp-usd", + "proxyAddress": "0x9DDa783DE64A9d1A60c49ca761EbE528C35BA428", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Compound", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "COMP", + "baseAssetClic": "COMP_CR", + "blockchainName": "Base", + "clicProductName": "COMP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x62c9CB9Dd648d9ed28C4C243d062093571b934D7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ltc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LTC / USD", + "pair": [ + "", + "" + ], + "path": "ltc-usd", + "proxyAddress": "0x206a34e47093125fbf4C75b7c7E88b84c6A77a69", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Litecoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LTC", + "baseAssetClic": "LTC_CR", + "blockchainName": "Base", + "clicProductName": "LTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x638708d73A0Eea5dAef10155083399D24a2c92C7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "vyusdusd-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "1000000000000000000", + "name": "vyUSD-USD Exchange Rate", + "pair": [ + "", + "" + ], + "path": "vyusd-usd-exchange-rate", + "proxyAddress": "0x99C098FA069B120dd81E56c0f2178093cc7a851f", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "vyUSD / USD Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "vyUSD", + "baseAssetClic": "vyUSD_CR", + "blockchainName": "Base", + "clicProductName": "vyUSD/USD-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x63a3b4E2aeea2d1Cc883987AEc22E9Aa88323b3c", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "susde-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "sUSDe / USD", + "pair": [ + "", + "" + ], + "path": "susde-usd", + "proxyAddress": "0x79cf4a31B29D69191f0b6E97916eB93FEB81E533", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethena Staked USDe", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUSDE", + "baseAssetClic": "SUSDE_CR", + "blockchainName": "Base", + "clicProductName": "SUSDE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "finalto", + "compareOffchain": "", + "contractAddress": "0x69c6dcBaeBAa2A82Ca02350ceD0694697D21A3f1", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "aud-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AUD / USD", + "pair": [ + "", + "" + ], + "path": "aud-usd", + "proxyAddress": "0x46e51B8cA41d709928EdA9Ae43e42193E6CDf229", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Australian Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "AUD", + "baseAssetClic": "AUD_FX", + "blockchainName": "Base", + "clicProductName": "AUD/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6adE13EeacDd21e96FE2A6F4E2a5C6cf4FD30C00", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wif-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WIF / USD", + "pair": [ + "", + "" + ], + "path": "wif-usd", + "proxyAddress": "0x674940e1dBf7FD841b33156DA9A88afbD95AaFBa", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "dogwifhat", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "WIF", + "blockchainName": "Base", + "clicProductName": "WIF/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6f22C6925b27bCf9713fAE2Ab6f4397549D684b8", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "stg-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "STG / USD", + "pair": [ + "", + "" + ], + "path": "stg-usd", + "proxyAddress": "0x63Af8341b62E683B87bB540896bF283D96B4D385", + "threshold": 2, + "valuePrefix": "", + "assetName": "Stargate Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "STG", + "baseAssetClic": "STG_CR", + "blockchainName": "Base", + "clicProductName": "STG/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6f9829A2278A5b017b6e997E2BafCDbCb8d6Bc04", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "total-market-cap-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "Total Market Cap USD", + "pair": [ + "", + "" + ], + "path": "mcap-usd", + "proxyAddress": "0x962C0Df8Ca7f7C682B3872ccA31Ea9c8999ab23c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x721860ef887896c19003886349a785749845e38d", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "aave-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AAVE / USD", + "pair": [ + "", + "" + ], + "path": "aave-usd", + "proxyAddress": "0x3d6774EF702A10b20FCa8Ed40FC022f7E4938e07", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Aave", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AAVE", + "baseAssetClic": "AAVE_CR", + "blockchainName": "Base", + "clicProductName": "AAVE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x72FC7950A832396720736e7e08D6F74C84C6909a", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "link-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "LINK / USD", + "pair": [ + "", + "" + ], + "path": "link-usd", + "proxyAddress": "0x17CAb8FE31E32f08326e5E27412894e49B0f9D65", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "baseAssetClic": "LINK_CR", + "blockchainName": "Base", + "clicProductName": "LINK/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x72c2E05dC38b2AE47d8F87C9B99c264D9fD46A10", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "xsolvbtc-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "xSolvBTC NAV", + "pair": [ + "", + "" + ], + "path": "xsolvbtc-nav", + "proxyAddress": "0x17738F7dacFc1De7d06f22cC52211EBf68744dBA", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Crypto", + "baseAsset": "xSolvBTC", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "Solv", + "porAuditor": "Solv", + "porSource": "Asset Issuer", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x735326Bcc0479e3F23eD65DC83310d63eBA6250D", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "snx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "SNX / USD", + "pair": [ + "", + "" + ], + "path": "snx-usd", + "proxyAddress": "0xe3971Ed6F1A5903321479Ef3148B5950c0612075", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Synthetix Network", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SNX", + "baseAssetClic": "SNX_CR", + "blockchainName": "Base", + "clicProductName": "SNX/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x74E60B98A3FCaBcDDC66C5727Ab4bCccbad10ce7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "vvv-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "VVV / USD", + "pair": [ + "", + "" + ], + "path": "vvv-usd", + "proxyAddress": "0x8eC6a128a430f7A850165bcF18facc9520a9873F", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Venice Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "VVV", + "baseAssetClic": "VVV_CR", + "blockchainName": "Base", + "clicProductName": "VVV/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x74f70D08c92f1cd4Ed70B9aa3F8edC0bA5496a01", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "POL / USD", + "pair": [ + "", + "" + ], + "path": "pol-usd", + "proxyAddress": "0x5E988c11a4f92155C30D9fb69Ed75597f712B113", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "POL", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "POL", + "baseAssetClic": "POL_CR", + "blockchainName": "Base", + "clicProductName": "POL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x75d0797767dC2F767fE50660FD4C6FeC9a110463", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "amp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AMP / USD", + "pair": [ + "", + "" + ], + "path": "amp-usd", + "proxyAddress": "0x1688e4B274a4CC9fD398EbA6Ae4dfb6528A9D2bc", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Amp", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AMP", + "baseAssetClic": "AMP_CR", + "blockchainName": "Base", + "clicProductName": "AMP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x79b0e87fF1C40D27a0F941296D70a91cD1553482", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "steth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "1000000000000000000", + "name": "STETH / ETH", + "pair": [ + "", + "" + ], + "path": "steth-eth", + "proxyAddress": "0xf586d0728a47229e747d824a939000Cf21dEF5A0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Lido Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "STETH", + "baseAssetClic": "STETH_CR", + "blockchainName": "Base", + "clicProductName": "STETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x7F98C05C5ed1A07B39E78f7876BC343daa30233f", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ultraeths-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ultraETHs / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "ultraeths-eth-exchange-rate", + "proxyAddress": "0xbb9786e37D54251477EbC1325b04ACdCA18C2254", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "ultraETHs / ETH Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "ultraETHs", + "baseAssetClic": "ultraETHs_CR", + "blockchainName": "Base", + "clicProductName": "ultraETHs/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x801B6E7d186370EeE854F76481643c22c7d1da99", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "susde-usde-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "sUSDe / USDe Exchange Rate", + "pair": [ + "", + "" + ], + "path": "susde-usde-exchange-rate", + "proxyAddress": "0xdEd37FC1400B8022968441356f771639ad1B23aA", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethena Staked USDe", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUSDE", + "baseAssetClic": "SUSDE_CR", + "blockchainName": "Base", + "clicProductName": "SUSDE/USDE-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USDE", + "quoteAssetClic": "USDE_CR", + "underlyingAsset": "USDE", + "underlyingAssetClic": "USDE_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x814d854de623bA3F846e97895ebC3b9aCfAAEBBc", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pepe-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "PEPE / USD", + "pair": [ + "", + "" + ], + "path": "pepe-usd", + "proxyAddress": "0xB48ac6409C0c3718b956089b0fFE295A10ACDdad", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "PEPE", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "PEPE", + "blockchainName": "Base", + "clicProductName": "PEPE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x820E799eD8754e007E9901531b8Ac7D283d9a1A2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cad-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "CAD / USD", + "pair": [ + "", + "" + ], + "path": "cad-usd", + "proxyAddress": "0xA840145F87572E82519d578b1F36340368a25D5d", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Canadian Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "CAD", + "baseAssetClic": "CAD_FX", + "blockchainName": "Base", + "clicProductName": "CAD/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x834CE448A994CA9F4cfe2Bf0C6BB5Ab7F24B8920", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mew-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "MEW / USD", + "pair": [ + "", + "" + ], + "path": "mew-usd", + "proxyAddress": "0x9FB8b5A4b3FE655564f0c76616ae79DE90Cc7382", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "cat in a dogs world", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MEW", + "baseAssetClic": "MEW_CR", + "blockchainName": "Base", + "clicProductName": "MEW/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x84efF9466d371ccAB94728e8bdFcd9Bc095D7Ca6", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "avax-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AVAX / USD", + "pair": [ + "", + "" + ], + "path": "avax-usd", + "proxyAddress": "0xE70f2D34Fd04046aaEC26a198A35dD8F2dF5cd92", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Avalanche", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AVAX", + "baseAssetClic": "AVAX_CR", + "blockchainName": "Base", + "clicProductName": "AVAX/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x851a369f1c7e3F82a2AE8D75Ee94eaBfd9781805", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "matic-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MATIC / USD", + "pair": [ + "", + "" + ], + "path": "matic-usd", + "proxyAddress": "0x12129aAC52D6B0f0125677D4E1435633E61fD25f", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Polygon (MATIC)", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MATIC", + "baseAssetClic": "MATIC_CR", + "blockchainName": "Base", + "clicProductName": "MATIC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x852aE0B1Af1aAeDB0fC4428B4B24420780976ca8", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "btc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 1200, + "history": null, + "multiply": "100000000", + "name": "BTC / USD", + "pair": [ + "", + "" + ], + "path": "btc-usd", + "proxyAddress": "0x64c911996D3c6aC71f9b455B1E8E7266BcbD848F", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "baseAssetClic": "BTC_CR", + "blockchainName": "Base", + "clicProductName": "BTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x89406394615978c0FB4A969574edA675595553C4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "home-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "HOME / USD", + "pair": [ + "", + "" + ], + "path": "home-usd", + "proxyAddress": "0x121934C415937863d64ef93436169444633EE0d8", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "HOME", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "HOME", + "baseAssetClic": "HOME_CR", + "blockchainName": "Base", + "clicProductName": "HOME/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x89B734B0f34c4697857C07CedB58afeb482F5596", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "insteth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "instETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "insteth-eth-exchange-rate", + "proxyAddress": "0x9C6BF4884Ff0c7873652F7d5142FA3b9859a526D", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Inception stETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "INSTETH", + "baseAssetClic": "INSTETH_CR", + "blockchainName": "Base", + "clicProductName": "INSTETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x8E6ec3E7d1E50db38D5690dF501530D5B2d0b58A", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ctx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CTX / USD", + "pair": [ + "", + "" + ], + "path": "ctx-usd", + "proxyAddress": "0x90F3676B40F6dc2C1E074985D0544Bb8e1815B00", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Cryptex Finance", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CTX", + "baseAssetClic": "CTX_CR", + "blockchainName": "Base", + "clicProductName": "CTX/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x8b535cC811c4E4c9CFf85b823479B1616CB5C7B5", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "lbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LBTC / BTC", + "pair": [ + "", + "" + ], + "path": "lbtc-btc", + "proxyAddress": "0x1E6c22AAA11F507af12034A5Dc4126A6A25DC8d2", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "LBTC / BTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "LBTC", + "baseAssetClic": "LBTC_CR", + "blockchainName": "Base", + "clicProductName": "LBTC/BTC-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x8edA55983EcbeB28ab02959AA9E7203e24bA8c19", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pufeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "pufETH / ETH", + "pair": [ + "", + "" + ], + "path": "pufeth-eth", + "proxyAddress": "0x9452Ca03474C6B704B4e102339B451D640f57f07", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "pufETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PUFETH", + "baseAssetClic": "PUFETH_CR", + "blockchainName": "Base", + "clicProductName": "PUFETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9120eFBD64713BB6Ebb5c8e560e8e56aFE712eD2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDX / USD", + "pair": [ + "", + "" + ], + "path": "usdx-usd", + "proxyAddress": "0xC342785EE44b9F8a40a564200CDF14dFCefd36C3", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9189882B85D37f117dC125Fbcce7B61C653Fa30c", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "gho-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "GHO / USD", + "pair": [ + "", + "" + ], + "path": "gho-usd", + "proxyAddress": "0x42868EFcee13C0E71af89c04fF7d96f5bec479b0", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "GHO", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "GHO", + "baseAssetClic": "GHO_CR", + "blockchainName": "Base", + "clicProductName": "GHO/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "GHO", + "quoteAssetClic": "GHO_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x91e936921Df850Cc8714527EBE6C45ECbD2CAd31", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ada-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ADA / USD", + "pair": [ + "", + "" + ], + "path": "ada-usd", + "proxyAddress": "0x34cD971a092d5411bD69C10a5F0A7EEF72C69041", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Cardano", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ADA", + "baseAssetClic": "ADA_CR", + "blockchainName": "Base", + "clicProductName": "ADA/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9465CF4b4032080434E397F42fB99A8446c35376", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdplus-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USD+ / USD", + "pair": [ + "", + "" + ], + "path": "usd+-usd", + "proxyAddress": "0xd5Ec94430eF4170D819E0996BC53ed40d31638d8", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "USD+", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USD+", + "baseAssetClic": "USD+_CR", + "blockchainName": "Base", + "clicProductName": "USD+/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x97100bac08Ef1532401041b5F864B4De999ab6D4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "shib-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SHIB / USD", + "pair": [ + "", + "" + ], + "path": "shib-usd", + "proxyAddress": "0xC8D5D660bb585b68fa0263EeD7B4224a5FC99669", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Shiba Inu", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SHIB", + "baseAssetClic": "SHIB_CR", + "blockchainName": "Base", + "clicProductName": "SHIB/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x98608b1AEEbFE5b3d05E14Ecd2C74AC613A3C0D7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ousdt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "OUSDT / USD", + "pair": [ + "", + "" + ], + "path": "ousdt-usd", + "proxyAddress": "0x0E230b1077c663f8Fb5e68d84A8e3e33D97d7436", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "OpenUSDT", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "OUSDT", + "baseAssetClic": "OUSDT_CR", + "blockchainName": "Base", + "clicProductName": "OUSDT/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9FE139104eef5B113e93859F185aa3C6E04e102B", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mavia-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MAVIA / USD", + "pair": [ + "", + "" + ], + "path": "mavia-usd", + "proxyAddress": "0x979447581b39caCA33EF0CA8208592393D16cc13", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Heroes of Mavia", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MAVIA", + "baseAssetClic": "MAVIA_CR", + "blockchainName": "Base", + "clicProductName": "MAVIA/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9eb524dA226328d8ff69440F0F4bAE7DC0BFf34C", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "rsweth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "rswETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "rsweth-eth-exchange-rate", + "proxyAddress": "0x97b770B0200CCe161907a9cbe0C6B177679f8F7C", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Restaked Swell ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RSWETH", + "baseAssetClic": "RSWETH_CR", + "blockchainName": "Base", + "clicProductName": "RSWETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xA1062b63D4097D2506650dCa3Ea442ce41BcEF8b", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "virtual-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "VIRTUAL / USD", + "pair": [ + "", + "" + ], + "path": "virtual-usd", + "proxyAddress": "0xEaf310161c9eF7c813A14f8FEF6Fb271434019F7", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Virtuals Protocol", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "VIRTUAL", + "baseAssetClic": "VIRTUAL_CR", + "blockchainName": "Base", + "clicProductName": "VIRTUAL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA31289604833866940BD063d54e31b312b223b24", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "zro-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ZRO / USD", + "pair": [ + "", + "" + ], + "path": "zro-usd", + "proxyAddress": "0xdc31a4CCfCA039BeC6222e20BE7770E12581bfEB", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "LayerZero", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ZRO", + "blockchainName": "Base", + "clicProductName": "ZRO/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA54DF8Ba7212667152aBa0D21d7c3221d14126F9", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "zbu-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ZBU / USD", + "pair": [ + "", + "" + ], + "path": "zbu-usd", + "proxyAddress": "0x19c6501ee6FF5Faf36346031A92C46AF128807d3", + "threshold": 1, + "valuePrefix": "", + "assetName": "Zeebu", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ZBU", + "baseAssetClic": "ZBU_CR", + "blockchainName": "Base", + "clicProductName": "ZBU/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA5925A27D3281198c0ae60a5eFcD6C44A5e47526", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wsteth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "WSTETH / ETH", + "pair": [ + "", + "" + ], + "path": "wsteth-eth", + "proxyAddress": "0x43a5C292A453A3bF3606fa856197f09D7B74251a", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped stETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WSTETH", + "baseAssetClic": "WSTETH_CR", + "blockchainName": "Base", + "clicProductName": "WSTETH/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "STETH", + "underlyingAssetClic": "STETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xA59b0A11fC48250F980120a8489bf9E95e687185", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "superoethb-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SUPEROETHB / ETH", + "pair": [ + "", + "" + ], + "path": "superoethb-eth", + "proxyAddress": "0x39C6E14CdE46D4FFD9F04Ff159e7ce8eC20E10B4", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Super OETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SUPEROETHB", + "baseAssetClic": "SUPEROETHB_CR", + "blockchainName": "Base", + "clicProductName": "SUPEROETHB/ETH-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xA9BDecf007120EBb013E223d2a4EEa4C8C35e7f1", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "unibtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "uniBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "unibtc-btc-exchange-rate", + "proxyAddress": "0xbC7c5023eE571e4D9C4890C90a16be05c1EEf410", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "uniBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "uniBTC", + "baseAssetClic": "uniBTC_CR", + "blockchainName": "Base", + "clicProductName": "uniBTC/BTC-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xAa1399A25AB0f9a5464f44963BA77626937D1523", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "apt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "APT / USD", + "pair": [ + "", + "" + ], + "path": "apt-usd", + "proxyAddress": "0x88a98431C25329AA422B21D147c1518b34dD36F4", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Aptos", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "APT", + "baseAssetClic": "APT_CR", + "blockchainName": "Base", + "clicProductName": "APT/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xB76EecECe7A7Cbf10a55Dc4284fb762577EE9e3D", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "solvbtcbbn-solvbtc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SolvBTC.BBN / SolvBTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "solvbtc.bbn-solvbtc-exchange-rate", + "proxyAddress": "0x67283A47E470afbCcc4aC74ccC32401a81027691", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "SolvBTC.BBN / SolvBTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SolvBTC.BBN", + "baseAssetClic": "SolvBTC.BBN_CR", + "blockchainName": "Base", + "clicProductName": "SolvBTC.BBN/SolvBTC-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "SolvBTC", + "quoteAssetClic": "SolvBTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xB9b5C92b596F36eDfB5d510A45ABDC160c427DE6", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mln-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MLN / USD", + "pair": [ + "", + "" + ], + "path": "mln-usd", + "proxyAddress": "0x122b5334A8b55861dBc6729c294451471FbF318D", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Enzyme", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MLN", + "baseAssetClic": "MLN_CR", + "blockchainName": "Base", + "clicProductName": "MLN/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC18cC9B106A50D945024F0a25EfF16B6dC56D4B9", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "aero-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AERO / USD", + "pair": [ + "", + "" + ], + "path": "aero-usd", + "proxyAddress": "0x4EC5970fC728C5f65ba413992CD5fF6FD70fcfF0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Aerodrome Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AERO", + "baseAssetClic": "AERO_CR", + "blockchainName": "Base", + "clicProductName": "AERO/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC2b36eEBE261eEEC502dFE761BA8cDB0E9bC057b", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ceth-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "CETH Reserves", + "pair": [ + "", + "" + ], + "path": "ceth-reserves", + "proxyAddress": "0x0b68ac37a1668DAaab1882543368E076C38C40e9", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "ETH", + "assetName": "21Shares Core Ethereum ETF", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "ETF", + "assetSubClass": "US", + "baseAsset": "21Shares_Core_Ethereum_ETF", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "21Shares", + "porAuditor": "Cross-chain / Ethereum Network", + "porSource": "Custodian API", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Ethereum Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 18 + }, + { + "benchmark": "finalto", + "compareOffchain": "", + "contractAddress": "0xC83D70E2a016AA3C51f8047EfB2329d9c7Ed6ed7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "chf-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CHF / USD", + "pair": [ + "", + "" + ], + "path": "chf-usd", + "proxyAddress": "0x3A1d6444fb6a402470098E23DaD0B7E86E14252F", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Swiss Franc", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "CHF", + "baseAssetClic": "CHF_FX", + "blockchainName": "Base", + "clicProductName": "CHF/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC87569d17C0640f9F921C91351C832833ad26Cef", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "real-gdp-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "Real GDP — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "real-gdp-percentage", + "proxyAddress": "0xe0eda54fC1362C0d7d0ff855E4fCEA79916Fe094", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0xCa1a4BdF7f9f8F8F281E311028dEa7e472a7A194", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ynethx-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ynETHx / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "ynethx-eth-exchange-rate", + "proxyAddress": "0x4e7dB2f9a28348AB48a968dd4217D565D1F15Ba4", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "ynETH MAX", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "ynETHx", + "baseAssetClic": "ynETHx_CR", + "blockchainName": "Base", + "clicProductName": "ynETHx/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ynETHx", + "quoteAssetClic": "ynETHx_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xCb374B34B6b74a0b6d0d4Ef6B73E07F299387957", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "real-gdp-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "Real GDP — Level", + "pair": [ + "", + "" + ], + "path": "real-gdp-level", + "proxyAddress": "0x0df397aFE00085C138a99eFB39C498e08eB95aD1", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "B of Chained 2017 USD", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0xCd867f3962c108ea2F90828a58f22D202dEAf913", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pce-price-index-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "PCE Price Index — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "pce-price-index-percentage", + "proxyAddress": "0x2a18E2d46Cb067b69e0759dB39b16597fC42D962", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0xD0407a6524C7d9075E0b040dCEf4696129B2C3B4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "lseth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "LSETH / ETH", + "pair": [ + "", + "" + ], + "path": "lseth-eth", + "proxyAddress": "0xeDC243c7E3c1A9dAf067C90641D2346d2694d2e5", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "high", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xD27766C20dF630a7D7e1e5885ae581FB0e61828A", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdz-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDz / USD", + "pair": [ + "", + "" + ], + "path": "usdz-usd", + "proxyAddress": "0xe25969e2Fa633a0C027fAB8F30Fc9C6A90D60B48", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Anzen USDz", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDz", + "baseAssetClic": "USDz_CR", + "blockchainName": "Base", + "clicProductName": "USDz/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xD41A2B9575eD27D38EC9B75B4d0DD9632a72e45b", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdo-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "USDO Reserves", + "pair": [ + "", + "" + ], + "path": "usdo-por", + "proxyAddress": "0x5218Ebeb96bD2bAFe21F9b143f5672552629ba79", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "OpenEden OpenDollar", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDO", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "OpenEden", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "U.S. Treasury Bills", + "underlyingAsset": "U.S. Treasury Bills" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xD8341Fd0F84d0E5755CD419969BbD3Bf73e6Ab43", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "morpho-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MORPHO / USD", + "pair": [ + "", + "" + ], + "path": "morpho-usd", + "proxyAddress": "0xe95e258bb6615d47515Fc849f8542dA651f12bF6", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Morpho", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MORPHO", + "baseAssetClic": "MORPHO_CR", + "blockchainName": "Base", + "clicProductName": "MORPHO/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xDC2D2fA8E7b824A2c16128446E288280dcB12844", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "usdt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "USDT / USD", + "pair": [ + "", + "" + ], + "path": "usdt-usd", + "proxyAddress": "0xf19d560eB8d2ADf07BD6D13ed03e1D11215721F9", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Tether USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDT", + "baseAssetClic": "USDT_CR", + "blockchainName": "Base", + "clicProductName": "USDT/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xE186722b9d5C063625C49a4BF6Bb3d669F66A8b5", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "wbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 1200, + "history": false, + "multiply": "100000000", + "name": "WBTC / USD", + "pair": [ + "", + "" + ], + "path": "wbtc-usd", + "proxyAddress": "0xCCADC697c55bbB68dc5bCdf8d3CBe83CdD4E071E", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Wrapped Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Crypto", + "baseAsset": "WBTC", + "baseAssetClic": "WBTC_CR", + "blockchainName": "Base", + "clicProductName": "WBTC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xEA990BCCb5b4dA5023B6dc88480297405Fd222c3", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "sol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "SOL / USD", + "pair": [ + "", + "" + ], + "path": "sol-usd", + "proxyAddress": "0x975043adBb80fc32276CbF9Bbcfd4A601a12462D", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Solana", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SOL", + "baseAssetClic": "SOL_CR", + "blockchainName": "Base", + "clicProductName": "SOL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xEC1b27BAF5cc164DD8407562A0C13A7b5b931B36", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "pufeth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "pufETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "pufeth-eth-exchange-rate", + "proxyAddress": "0x69a1d14a4e58e97EDE8337DE61eEB2e4a55886E0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "pufETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PUFETH", + "baseAssetClic": "PUFETH_CR", + "blockchainName": "Base", + "clicProductName": "PUFETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xEC509C1f0791504667972D5FF705AE4Bd2dB500F", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "trump-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TRUMP / USD", + "pair": [ + "", + "" + ], + "path": "trump-usd", + "proxyAddress": "0x7bAfa1Af54f17cC0775a1Cf813B9fF5dED2C51E5", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Official Trump", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "TRUMP", + "baseAssetClic": "TRUMP_CR", + "blockchainName": "Base", + "clicProductName": "TRUMP/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xF4f6843A8003417b04EAbDd7a1bAe2cAFCBF0aCC", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "moobifi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "mooBIFI / USD", + "pair": [ + "", + "" + ], + "path": "moobifi-usd", + "proxyAddress": "0x721F1B4dc604AEA0661Aa9982AB624e5756B31f2", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xFa7fafD062112455EBF576cFDf4005F5324b97E0", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "doge-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "DOGE / USD", + "pair": [ + "", + "" + ], + "path": "doge-usd", + "proxyAddress": "0x8422f3d3CAFf15Ca682939310d6A5e619AE08e57", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Dogecoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "DOGE", + "baseAssetClic": "DOGE_CR", + "blockchainName": "Base", + "clicProductName": "DOGE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xFf9D38D4a93EE585c0545635683d19ADC2Df6Ab7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "anon-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ANON / USD", + "pair": [ + "", + "" + ], + "path": "anon-usd", + "proxyAddress": "0x674e028B95330E77F5cF89834254a6Bfa806f3a2", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Hey Anon", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ANON", + "baseAssetClic": "ANON_CR", + "blockchainName": "Base", + "clicProductName": "ANON/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xa1923f93B032BF2dFEDcdFD0dA93037D32C39F4D", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "melania-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MELANIA / USD", + "pair": [ + "", + "" + ], + "path": "melania-usd", + "proxyAddress": "0xFAf372CaBc765b63f6fabD436c845D965eDA1CA5", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Official Melania Meme", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MELANIA", + "baseAssetClic": "MELANIA_CR", + "blockchainName": "Base", + "clicProductName": "MELANIA/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xa24AAfb9d49d0cF43dcd8A5f2442a30391F494D2", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "ibtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "iBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "ibtc-por", + "proxyAddress": "0x7FCED5198e43ec93Ef2179DFC70a8dcf494DcB80", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "iBTC", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "issuer": "iBTC", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xa47344071B503F4B3B34d768e7bAAB0631990825", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "solvbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "solvBTC / BTC", + "pair": [ + "", + "" + ], + "path": "solvbtc-btc", + "proxyAddress": "0xB4a1a7f260C9FF7fEd6A6fbb9fe5a9acFa725DBf", + "threshold": 1, + "valuePrefix": "", + "assetName": "Solv Protocol SolvBTC", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "solvBTC", + "baseAssetClic": "solvBTC_CR", + "blockchainName": "Base", + "clicProductName": "solvBTC/BTC-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xaE4602716079C0Be7948c0b84553dEE0e6564a3d", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "degen-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "DEGEN / USD", + "pair": [ + "", + "" + ], + "path": "degen-usd", + "proxyAddress": "0xE62BcE5D7CB9d16AB8b4D622538bc0A50A5799c2", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Degen (Base)", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "DEGEN", + "baseAssetClic": "DEGEN_CR", + "blockchainName": "Base", + "clicProductName": "DEGEN/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xb9b743D02D173e4529051eC9dda06a0C5cb4A2a4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mxn-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "MXN / USD", + "pair": [ + "", + "" + ], + "path": "mxn-usd", + "proxyAddress": "0x9e8Ee77c76d4fa41306056D1C3196AF5da1600bd", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Mexican Peso", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "MXN", + "baseAssetClic": "MXN_FX", + "blockchainName": "Base", + "clicProductName": "MXN/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xbF477e69a0adF91b6e3d6e70cb67E5D1A27e88e3", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "bnb-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BNB / USD", + "pair": [ + "", + "" + ], + "path": "bnb-usd", + "proxyAddress": "0x4b7836916781CAAfbb7Bd1E5FDd20ED544B453b1", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "BNB", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BNB", + "baseAssetClic": "BNB_CR", + "blockchainName": "Base", + "clicProductName": "BNB/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc73B7635630A94a3E9a595741cbb8A3845C27826", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "rseth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "rsETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "rseth-eth-exchange-rate", + "proxyAddress": "0x99DAf760d2CFB770cc17e883dF45454FE421616b", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Kelp DAO Restaked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RSETH", + "baseAssetClic": "RSETH_CR", + "blockchainName": "Base", + "clicProductName": "RSETH/ETH-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xc934f510966De1940706eA6c73B054089d2525c7", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cbdoge-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CBDOGE / USD", + "pair": [ + "", + "" + ], + "path": "cbdoge-usd", + "proxyAddress": "0x95051De9Db5Cac61682f64505006f2991dEaB3c2", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Coinbase Wrapped DOGE", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CBDOGE", + "baseAssetClic": "CBDOGE_CR", + "blockchainName": "Base", + "clicProductName": "CBDOGE/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc95cd3490be4af06F0A25435e21C2c91B988C482", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "eurc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "EURC / USD", + "pair": [ + "", + "" + ], + "path": "eurc-usd", + "proxyAddress": "0xDAe398520e2B67cd3f27aeF9Cf14D93D927f8250", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Circle EUR", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "EURC", + "baseAssetClic": "EURC_CR", + "blockchainName": "Base", + "clicProductName": "EURC/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xcAd16df709bFe62D02cde5d4039684fA47Dc216c", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "well-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WELL / USD", + "pair": [ + "", + "" + ], + "path": "well-usd", + "proxyAddress": "0xc15d9944dAefE2dB03e53bef8DDA25a56832C5fe", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Moonwell", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "WELL", + "baseAssetClic": "WELL_CR", + "blockchainName": "Base", + "clicProductName": "WELL/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xd7640cCAda34152220662780493E310DDA6e0d3D", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "cusdo-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CUSDO / USD", + "pair": [ + "", + "" + ], + "path": "cusdo-usd", + "proxyAddress": "0xBbdA526258856c06f167399097e13D79E8f88ba8", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Compounding OpenDollar", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "CUSDO", + "baseAssetClic": "CUSDO_CR", + "blockchainName": "Base", + "clicProductName": "CUSDO/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xdB793acA8bE40a123c34300Bb21b02F21F8ef501", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "yfi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "YFI / USD", + "pair": [ + "", + "" + ], + "path": "yfi-usd", + "proxyAddress": "0xD40e758b5eC80820B68DFC302fc5Ce1239083548", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Yearn Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "YFI", + "baseAssetClic": "YFI_CR", + "blockchainName": "Base", + "clicProductName": "YFI/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xdD24Cd0F5243800a7b29Decd58736cbEa92AbBc0", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "real-final-sales-to-private-domestic-purchasers-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "Real Final Sales to Private Domestic Purchasers — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "real-final-sales-to-private-domestic-purchasers-percentage", + "proxyAddress": "0xe2b3688371130f333443428Cf03f27Ce0378F9dC", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Base", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0xe09bE26CF556F7211c16B75BE9fB4DB433A0d37E", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "nzd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "NZD / USD", + "pair": [ + "", + "" + ], + "path": "nzd-usd", + "proxyAddress": "0x06bdFe07E71C476157FC025d3cCD4BBe08e83EF9", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "New Zealand Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "NZD", + "baseAssetClic": "NZD_FX", + "blockchainName": "Base", + "clicProductName": "NZD/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xeCA1EBFb5CA472C76328f5DdE011c6CcCF2a66F4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "mog-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "MOG / USD", + "pair": [ + "", + "" + ], + "path": "mog-usd", + "proxyAddress": "0x4aeb6D15769EaD32D0c5Be2940F40c7CFf53801d", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Mog Coin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MOG", + "baseAssetClic": "MOG_CR", + "blockchainName": "Base", + "clicProductName": "MOG/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xf2d85ee7CD9e75f3FFFF4B44ADE48581d2dbDFDd", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "swbtc-wbtc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "swBTC / WBTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "swbtc-wbtc-exchange-rate", + "proxyAddress": "0xBD867487712ADeC5A59b9Ae475Ee942f652B4C91", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "swBTC / WBTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "swBTC", + "baseAssetClic": "swBTC_CR", + "blockchainName": "Base", + "clicProductName": "swBTC/WBTC-ExRate-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "WBTC", + "quoteAssetClic": "WBTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xf3764B1fc0Ab831f75D3edd7435ABFE4Af675c9A", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "rsr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": false, + "multiply": "100000000", + "name": "RSR / USD", + "pair": [ + "", + "" + ], + "path": "rsr-usd", + "proxyAddress": "0xAa98aE504658766Dfe11F31c5D95a0bdcABDe0b1", + "threshold": 2, + "valuePrefix": "", + "assetName": "Reserve Rights", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RSR", + "baseAssetClic": "RSR_CR", + "blockchainName": "Base", + "clicProductName": "RSR/USD-RefPrice-DF-Base-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xf45821111c1Ef3e116Ca108c0F06014216Ed39c4", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "lseth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "LsETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "lseth-eth-exchange-rate", + "proxyAddress": "0x2621897C993fdE08873Ef58dA1453aEE49a70144", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 18 + } + ] \ No newline at end of file diff --git a/src/constants/chainlink-data/index.ts b/src/constants/chainlink-data/index.ts new file mode 100644 index 00000000..db3c846a --- /dev/null +++ b/src/constants/chainlink-data/index.ts @@ -0,0 +1,83 @@ +import { ChainlinkOracleEntry } from './types' +import mainnetRawData from './mainnet.json' +import baseRawData from './base.json' +import polygonRawData from './polygon.json' +import { isSupportedChain, SupportedNetworks } from '@/utils/networks' + +type RawOracleEntry = { + contractAddress: string + contractVersion: number + ens: string + heartbeat: number + multiply: string + name: string + path: string + proxyAddress: string + threshold: number + valuePrefix: string + assetName: string + feedCategory: 'low' | 'medium' | 'high' | 'custom' + feedType: string + decimals: number + docs: { + baseAsset?: string + quoteAsset?: string + [key: string]: any + } + [key: string]: any +} + +const transformOracleData = (rawData: RawOracleEntry[]): ChainlinkOracleEntry[] => { + return rawData.map((entry) => ({ + contractAddress: entry.contractAddress, + contractVersion: entry.contractVersion, + ens: entry.ens, + heartbeat: entry.heartbeat, + multiply: entry.multiply, + name: entry.name, + path: entry.path, + proxyAddress: entry.proxyAddress ?? '', + threshold: entry.threshold, + valuePrefix: entry.valuePrefix, + assetName: entry.assetName, + feedCategory: entry.feedCategory, + feedType: entry.feedType, + decimals: entry.decimals, + baseAsset: entry.docs?.baseAsset ?? '', + quoteAsset: entry.docs?.quoteAsset ?? '', + isSVR: entry.path.endsWith('-svr'), + })) +} + +export const CHAINLINK_ORACLES = { + [SupportedNetworks.Mainnet]: transformOracleData(mainnetRawData as RawOracleEntry[]), + [SupportedNetworks.Base]: transformOracleData(baseRawData as RawOracleEntry[]), + [SupportedNetworks.Polygon]: transformOracleData(polygonRawData as RawOracleEntry[]), + [SupportedNetworks.Unichain]: [] as ChainlinkOracleEntry[], +} as const + +export const getAllOracles = (): Record => CHAINLINK_ORACLES + +export const getOracleByPath = ( + chain: keyof typeof CHAINLINK_ORACLES, + path: string +): ChainlinkOracleEntry | undefined => { + return CHAINLINK_ORACLES[chain].find((oracle) => oracle.path === path) +} + +export const isChainlinkOracle = (chainId: number, address: string): boolean => { + if (!isSupportedChain(chainId) || !address) return false + const network = chainId as SupportedNetworks + return CHAINLINK_ORACLES[network].some((oracle) => oracle.proxyAddress.toLowerCase() === address.toLowerCase()) +} + +export const getChainlinkOracle = (chainId: number, address: string): ChainlinkOracleEntry | undefined => { + + if (!isSupportedChain(chainId) || !address) return undefined + const network = chainId as SupportedNetworks + return CHAINLINK_ORACLES[network].find((oracle) => oracle.proxyAddress.toLowerCase() === address.toLowerCase()) + + +} + +export * from './types' \ No newline at end of file diff --git a/src/constants/chainlink-data/mainnet.json b/src/constants/chainlink-data/mainnet.json new file mode 100644 index 00000000..52c9276d --- /dev/null +++ b/src/constants/chainlink-data/mainnet.json @@ -0,0 +1,11648 @@ +[ + { + "compareOffchain": "", + "contractAddress": "0x00f0eFB3d9dBe7fE91fee44aE09DAe5DFA65c382", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "FBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "fbtc-por", + "proxyAddress": "0x75A0d3264a949C2C920d7F25Df174af1FaF73399", + "threshold": 0.5, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "FBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Ignition", + "marketHours": "Crypto", + "porAuditor": "BlockSec", + "porSource": "Third-party", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x019699e5b12331cf77DF9E39818c2E15C8B06215", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rai-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "RAI / ETH", + "pair": [ + "", + "" + ], + "path": "rai-eth", + "proxyAddress": "0x4ad7B025127e89263242aB68F0f9c4E5C033B489", + "threshold": 2, + "valuePrefix": "", + "assetName": "RAI Reflex Index", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RAI", + "baseAssetClic": "RAI_CR", + "blockchainName": "Ethereum", + "clicProductName": "RAI/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x01b435a26dc8547e6837E3189d734E38ecEb7128", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rsweth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "rswETH / ETH", + "pair": [ + "", + "" + ], + "path": "rsweth-eth", + "proxyAddress": "0xb613CfebD0b6e95abDDe02677d6bC42394FdB857", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Restaked Swell ETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "rswETH", + "baseAssetClic": "RSWETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "RSWETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0260343eB7bEf134b8892Ee66712fd3D5a3f6274", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fil-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "FIL / ETH", + "pair": [ + "", + "" + ], + "path": "fil-eth", + "proxyAddress": "0x0606Be69451B1C9861Ac6b3626b99093b713E801", + "threshold": 2, + "valuePrefix": "", + "assetName": "Filecoin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "FIL", + "baseAssetClic": "FIL_CR", + "blockchainName": "Ethereum", + "clicProductName": "FIL/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x04397A4F83256E7aEd344D974B70D8A120C67EcE", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ethfi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ETHFI / USD", + "pair": [ + "", + "" + ], + "path": "ethfi-usd", + "proxyAddress": "0x19678515847d8DE85034dAD0390e09c3048d31cd", + "threshold": 2, + "valuePrefix": "", + "assetName": "ether.fi", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETHFI", + "baseAssetClic": "ETHFI", + "blockchainName": "Ethereum", + "clicProductName": "ETHFI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x05581918Dad3F026169593863F7A52bBBE08Ef5E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdf-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDf / USD", + "pair": [ + "", + "" + ], + "path": "usdf-usd", + "proxyAddress": "0xb177857a1799aA5F7fEb5799Fdf12CbE8fdF78B1", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Falcon USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDf", + "baseAssetClic": "USDf_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDf/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x06f277De95041c15e15270A144AfcF572a2F636E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "deusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "deUSD / USD", + "pair": [ + "", + "" + ], + "path": "deusd-usd", + "proxyAddress": "0x471a6299C027Bd81ed4D66069dc510Bd0569f4F8", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Elixir deUSD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "DEUSD", + "baseAssetClic": "DEUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "DEUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x072eC2295E72815f4D0c6B378D67De0be9781100", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fdusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "FDUSD / USD", + "pair": [ + "", + "" + ], + "path": "fdusd-usd", + "proxyAddress": "0xfAA9147190c2C2cc5B8387B4f49016bDB3380572", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "First Digital USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "FDUSD", + "baseAssetClic": "FDUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "FDUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x079a0E672b5FCCB93ba1f837184F19eB5497128E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rseth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "rsETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "rseth-eth-exchange-rate", + "proxyAddress": "0x9d2F2f96B24C444ee32E57c04F7d944bcb8c8549", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Kelp DAO Restaked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RSETH", + "baseAssetClic": "RSETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "RSETH/ETH-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x08B383db68EE48Cef76d3A48c4E0dE9B558704f5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "uni-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "UNI / ETH", + "pair": [ + "", + "" + ], + "path": "uni-eth", + "proxyAddress": "0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e", + "threshold": 2, + "valuePrefix": "", + "assetName": "Uniswap", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "UNI", + "baseAssetClic": "UNI_CR", + "blockchainName": "Ethereum", + "clicProductName": "UNI/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x09C711d45998AB5d9235AEcAa8bF909Df066e45e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "neiro-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "NEIRO / USD", + "pair": [ + "", + "" + ], + "path": "neiro-usd", + "proxyAddress": "0x771cf56aE75bC907193177237b423A9DA831280A", + "threshold": 2, + "valuePrefix": "", + "assetName": "Neiro", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Crypto", + "baseAsset": "NEIRO", + "baseAssetClic": "NEIRO_CR", + "blockchainName": "Ethereum", + "clicProductName": "NEIRO/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0B539d864C16398DcC7353521C62186380dE6B56", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdt-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "USDT / ETH", + "pair": [ + "", + "" + ], + "path": "usdt-eth", + "proxyAddress": "0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46", + "threshold": 1, + "valuePrefix": "", + "assetName": "Tether", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDT", + "baseAssetClic": "USDT_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDT/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0BC77EA00a329138be72CCe1D70B8d1e7CDE9bc4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ezeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ezETH / ETH", + "pair": [ + "", + "" + ], + "path": "ezeth-eth", + "proxyAddress": "0x636A000262F6aA9e1F094ABF0aD8f645C44f641C", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Renzo Restaked ETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "EZETH", + "baseAssetClic": "EZETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "EZETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0C87311F99972A523C191e50d372FBD98E92ADb2", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "scroll-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Scroll Healthcheck", + "pair": [ + "", + "" + ], + "path": "scroll-hc", + "proxyAddress": "0x7fb9B4a05e7B4F0c1Ac0B0046784cc0aCE8CbBC5", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x0DB37D53870E903481C47b144F425C89284e00Cd", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cspx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CSPX / USD", + "pair": [ + "", + "" + ], + "path": "cspx-usd", + "proxyAddress": "0xF4E1B57FB228879D057ac5AE33973e8C53e4A0e0", + "threshold": 2, + "valuePrefix": "", + "assetName": "iShares Core S&P 500 UCITS ETF", + "feedCategory": "low", + "feedType": "Equities", + "docs": { + "assetClass": "ETF", + "assetSubClass": "UK", + "baseAsset": "CSPX", + "baseAssetClic": "CSPX_EQ", + "blockchainName": "Ethereum", + "clicProductName": "CSPX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "LSE", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0F316F6b0c2e2eBE3C3a8b23F6c61009238D51fD", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "weeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "weETH / ETH", + "pair": [ + "", + "" + ], + "path": "weeth-eth", + "proxyAddress": "0x5c9C449BbC9a6075A2c061dF312a35fd1E05fF22", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped eETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "weETH", + "baseAssetClic": "weETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "weETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0a11E4A9bc9bc81B5D98951e770B558D9cAA63B1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "jaaa-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000", + "name": "JAAA NAV - Aave LlamaRisk", + "pair": [ + "", + "" + ], + "path": "jaaa-nav-aave-llamarisk", + "proxyAddress": "0x1E41Ef40AC148706c114534E8192Ca608f80fC48", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Janus Henderson AAA CLO Fund", + "feedCategory": "custom", + "feedType": "Tokenized Asset", + "docs": { + "assetClass": "Corporate Bonds", + "baseAsset": "JAAA", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Anemoy", + "hidden": true, + "porAuditor": "Anemoy", + "porSource": "Asset Manager", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0x0b83B36bDb49E5010c2AeE53b3cbD131Fd24261C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bat-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "BAT / ETH", + "pair": [ + "", + "" + ], + "path": "bat-eth", + "proxyAddress": "0x0d16d4528239e9ee52fa531af613AcdB23D88c94", + "threshold": 2, + "valuePrefix": "", + "assetName": "Basic Attention Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BAT", + "baseAssetClic": "BAT_CR", + "blockchainName": "Ethereum", + "clicProductName": "BAT/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0bb1203d3Df75752723290EFB116a91a1a9196D1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "stbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "stBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "stbtc-por", + "proxyAddress": "0x7Eaa6f116Ab9E57f58d9A9Ce88cc3f1c2476ECfA", + "threshold": 1, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "stBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Lorenzo", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x0c5781B3d5E2F7c00bC286E910cB9D28a86D94b6", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "synthetix-aggregator-debt-ratio", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000000000000", + "name": "Synthetix Aggregator Debt Ratio", + "pair": [ + "", + "" + ], + "path": "synthetix-aggregator-debt-ratio", + "proxyAddress": "0x0981af0C002345c9C5AD5efd26242D0cBe5aCA99", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true + }, + "decimals": 27 + }, + { + "compareOffchain": "", + "contractAddress": "0x0d5F4aADf3fde31BBB55dB5F42C080F18aD54Df5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDT / USD", + "pair": [ + "", + "" + ], + "path": "usdt-usd", + "proxyAddress": "0x3E7d1eAB13ad0104d2750B8863b489D65364e32D", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "Tether USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDT", + "baseAssetClic": "USDT_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0e3dd634FFbF7EA89BbDCF09Ccc463302FD5f903", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "xau-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "XAU / USD", + "pair": [ + "", + "" + ], + "path": "xau-usd", + "proxyAddress": "0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Gold", + "feedCategory": "low", + "feedType": "Commodities", + "docs": { + "assetClass": "Commodity", + "assetSubClass": "Spot", + "baseAsset": "XAU", + "baseAssetClic": "XAU_CO", + "blockchainName": "Ethereum", + "clicProductName": "XAU/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Precious_Metals", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x0e6d6293B6D4801Ef491BD762988CFdabc0Ecb09", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sushi-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SUSHI / ETH", + "pair": [ + "", + "" + ], + "path": "sushi-eth", + "proxyAddress": "0xe572CeF69f43c2E488b33924AF04BDacE19079cf", + "threshold": 2, + "valuePrefix": "", + "assetName": "Sushi", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUSHI", + "baseAssetClic": "SUSHI_CR", + "blockchainName": "Ethereum", + "clicProductName": "SUSHI/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x15D8Aac71A442ece966576c85438B0DFa7FcAbe1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "knc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "KNC / USD", + "pair": [ + "", + "" + ], + "path": "knc-usd", + "proxyAddress": "0xf8fF43E991A81e6eC886a3D281A2C6cC19aE70Fc", + "threshold": 1, + "valuePrefix": "", + "assetName": "Kyber Network", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "KNC", + "baseAssetClic": "KNC_CR", + "blockchainName": "Ethereum", + "clicProductName": "KNC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x1669A35DA4e5a4E0e55d30B728E66bE508E11DE8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tusd-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "TUSD Reserves", + "pair": [ + "", + "" + ], + "path": "tusd-por", + "proxyAddress": "0xBE456fd14720C3aCCc30A2013Bffd782c9Cb75D5", + "threshold": 5, + "valuePrefix": "$", + "assetName": "US Dollar (USD) total reserves", + "feedCategory": "custom", + "feedType": "Fiat", + "docs": { + "assetClass": "Fiat", + "baseAsset": "TUSD", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "TrueUSD", + "porAuditor": "MooreHK", + "porSource": "Third-party", + "porType": "Off-chain", + "productSubType": "Off-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "USD", + "reserveAssetClic": "USD_FX", + "ripcordApi": "https://api.real-time-reserves.verinumus.io/v1/chainlink/proof-of-reserves/TrueUSD" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x1Af88ebE66a229A47d8Ca283fBcCc8C92CD4fb26", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "real-gdp-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "Real GDP — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "real-gdp-percentage", + "proxyAddress": "0x1e9cb00c0AC8d2a171f44E63bE7532AD7224F6D1", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0x1DA1DdED0eFEB6eB7A5955502B892f8979af65DF", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "avax-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AVAX / USD", + "pair": [ + "", + "" + ], + "path": "avax-usd", + "proxyAddress": "0xFF3EEb22B5E3dE6e705b44749C2559d704923FD7", + "threshold": 2, + "valuePrefix": "", + "assetName": "Avalanche", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AVAX", + "baseAssetClic": "AVAX_CR", + "blockchainName": "Ethereum", + "clicProductName": "AVAX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x1Dc7331672694934f1831d5083022b0e5336F12d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "c3m-eur", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "C3M / EUR", + "pair": [ + "", + "" + ], + "path": "c3m-eur", + "proxyAddress": "0xD41390267Afec3fA5b4c0B3aA6c706556CCE75ec", + "threshold": 2, + "valuePrefix": "", + "assetName": "Amundi ETF Govies 0-6 Months Euro Investment Grade UCITS ETF", + "feedCategory": "custom", + "feedType": "Equities", + "docs": { + "assetClass": "ETF", + "assetSubClass": "MI", + "baseAsset": "C3M", + "baseAssetClic": "C3M_EQ", + "blockchainName": "Ethereum", + "clicProductName": "C3M/EUR-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Euronext_Milan", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "EUR", + "quoteAssetClic": "EUR_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x1E37adeFCfF644B69E717ce536D2dE407879D809", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "perp-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "PERP / ETH", + "pair": [ + "", + "" + ], + "path": "perp-eth", + "proxyAddress": "0x3b41D5571468904D4e53b6a8d93A6BaC43f02dC9", + "threshold": 2, + "valuePrefix": "", + "assetName": "Perpetual Protocol", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "PERP", + "baseAssetClic": "PERP_CR", + "blockchainName": "Ethereum", + "clicProductName": "PERP/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x1E726556244D772d1d50cacb19B87E7205fA509E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cbeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "CBETH / ETH", + "pair": [ + "", + "" + ], + "path": "cbeth-eth", + "proxyAddress": "0xF017fcB346A1885194689bA23Eff2fE6fA5C483b", + "threshold": 1, + "valuePrefix": "", + "assetName": "Coinbase Wrapped Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "CBETH", + "baseAssetClic": "CBETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "CBETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x1c9049C48C24111A3546a73C67FD2A4Fc6C86Fdc", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bat-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BAT / USD", + "pair": [ + "", + "" + ], + "path": "bat-usd", + "proxyAddress": "0x9441D7556e7820B5ca42082cfa99487D56AcA958", + "threshold": 1, + "valuePrefix": "", + "assetName": "Basic Attention Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BAT", + "blockchainName": "Ethereum", + "clicProductName": "BAT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "shutdownDate": "September 22nd, 2023" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x1f27EE4809c74422E0A165BcA3c8480623918EC4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "comp-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "COMP / ETH", + "pair": [ + "", + "" + ], + "path": "comp-eth", + "proxyAddress": "0x1B39Ee86Ec5979ba5C322b826B3ECb8C79991699", + "threshold": 2, + "valuePrefix": "", + "assetName": "Compound", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "COMP", + "baseAssetClic": "COMP_CR", + "blockchainName": "Ethereum", + "clicProductName": "COMP/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x206f1712629c23D107AFc4744622D9d815cBB645", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pce-price-index-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "PCE Price Index — Level", + "pair": [ + "", + "" + ], + "path": "pce-price-index-level", + "proxyAddress": "0x2F1494543bffb3022bf8Cb18C251D2286C98A85F", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0x20938e1f96DD1908c4B7eFB6D84F3b81808F4827", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "synthetix-aggregator-issued-synths", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "Synthetix Aggregator Issued Synths", + "pair": [ + "", + "" + ], + "path": "synthetix-aggregator-issued-synths", + "proxyAddress": "0xbCF5792575bA3A875D8C406F4E7270f51a902539", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x20EA5A0033B4C9e1Bec9E3F89D2056C4a40F7110", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "optimism-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "Optimism Healthcheck", + "pair": [ + "", + "" + ], + "path": "optimism-hc", + "proxyAddress": "0x59c2287c8E848310c809C061a1Be0d1556eFF4e2", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true, + "productSubType": "Health Check", + "productType": "Blockchain", + "productTypeCode": "Health" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x24e3c657c27DfC7ea6f9f58e86387D846b3BaA59", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "comp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "COMP / USD", + "pair": [ + "", + "" + ], + "path": "comp-usd", + "proxyAddress": "0xdbd020CAeF83eFd542f4De03e3cF0C28A4428bd5", + "threshold": 1, + "valuePrefix": "", + "assetName": "Compound", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "COMP", + "blockchainName": "Ethereum", + "clicProductName": "COMP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x265BaabD1d98D3dc405a142ed987eDb1fEf8be32", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "krw-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "KRW / USD", + "pair": [ + "", + "" + ], + "path": "krw-usd", + "proxyAddress": "0x01435677FB11763550905594A16B645847C1d0F3", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Korean Won", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "KRW", + "baseAssetClic": "KRW_FX", + "blockchainName": "Ethereum", + "clicProductName": "KRW/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_KRW", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x26ae9b951F84e6c28f58a92133C30e312D42e0Fe", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdc-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "USDC / ETH", + "pair": [ + "", + "" + ], + "path": "usdc-eth", + "proxyAddress": "0x986b5E1e1755e3C2440e960477f25201B0a8bbD4", + "threshold": 1, + "valuePrefix": "", + "assetName": "Circle USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDC", + "baseAssetClic": "USDC_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDC/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x26f196806f43E88FD27798C9e3fb8fdF4618240f", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "steth-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "STETH / USD", + "pair": [ + "", + "" + ], + "path": "steth-usd", + "proxyAddress": "0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8", + "threshold": 1, + "valuePrefix": "", + "assetName": "Lido Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "STETH", + "baseAssetClic": "STETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "STETH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x2878E76c12dAD8DFfDcCeb52588e091aa3858d26", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "dpi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "DPI / USD", + "pair": [ + "", + "" + ], + "path": "dpi-usd", + "proxyAddress": "0xD2A593BF7594aCE1faD597adb697b5645d5edDB2", + "threshold": 1, + "valuePrefix": "", + "assetName": "DefiPulse Index", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Index", + "assetSubClass": "Crypto", + "baseAsset": "DPI", + "baseAssetClic": "DPI_IX", + "blockchainName": "Ethereum", + "clicProductName": "DPI/USD-CalcInidex-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Calculated", + "productType": "Index", + "productTypeCode": "CalcInidex", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x2a29c3696dD424d3e703F5F3f2D6Af86598e9303", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bal-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BAL / USD", + "pair": [ + "", + "" + ], + "path": "bal-usd", + "proxyAddress": "0xdF2917806E30300537aEB49A7663062F4d1F2b5F", + "threshold": 2, + "valuePrefix": "", + "assetName": "Balancer", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BAL", + "baseAssetClic": "BAL_CR", + "blockchainName": "Ethereum", + "clicProductName": "BAL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x2b16C345E0558458E919E3351C62EcAD57cA7F36", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "1inch-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "1INCH / ETH", + "pair": [ + "", + "" + ], + "path": "1inch-eth", + "proxyAddress": "0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8", + "threshold": 2, + "valuePrefix": "", + "assetName": "1inch", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "1INCH", + "baseAssetClic": "1INCH_CR", + "blockchainName": "Ethereum", + "clicProductName": "1INCH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x2f28300Feef2Fe3F279E2A1cBb1f8be69e06Be85", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "calculated-xsushi-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "Calculated XSUSHI / ETH", + "pair": [ + "", + "" + ], + "path": "calc-xsushi-eth", + "proxyAddress": "0xF05D9B6C08757EAcb1fbec18e36A1B7566a13DEB", + "threshold": 2, + "valuePrefix": "", + "assetName": "Calculated xSushi", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "XSUSHI", + "baseAssetClic": "XSUSHI_CR", + "blockchainName": "Ethereum", + "clicProductName": "XSUSHI/USD-CalcPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Calculated", + "productType": "Price", + "productTypeCode": "CalcPrice", + "quoteAsset": "USD", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "SUSHI", + "underlyingAssetClic": "SUSHI_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x31EAf29E8F179E0877617c4A8b9A7fA51694efE5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mavia-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MAVIA / USD", + "pair": [ + "", + "" + ], + "path": "mavia-usd", + "proxyAddress": "0x29d26C008e8f201eD0D864b1Fd9392D29d0C8e96", + "threshold": 2, + "valuePrefix": "", + "assetName": "Heroes of Mavia", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MAVIA", + "baseAssetClic": "MAVIA_CR", + "blockchainName": "Ethereum", + "clicProductName": "MAVIA/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3357974B41466c9Adb453Dc9D8A5a07278887174", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "link-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 21600, + "history": null, + "multiply": "1000000000000000000", + "name": "LINK / ETH", + "pair": [ + "", + "" + ], + "path": "link-eth", + "proxyAddress": "0xDC530D9457755926550b59e8ECcdaE7624181557", + "threshold": 1, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "baseAssetClic": "LINK_CR", + "blockchainName": "Ethereum", + "clicProductName": "LINK/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x347b3886BdC7242Ae7f5f00398e801c8bfA8F52C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "aave-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "AAVE / ETH", + "pair": [ + "", + "" + ], + "path": "aave-eth", + "proxyAddress": "0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012", + "threshold": 2, + "valuePrefix": "", + "assetName": "Aave", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AAVE", + "baseAssetClic": "AAVE_CR", + "blockchainName": "Ethereum", + "clicProductName": "AAVE/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x3547473DA7deB396ACF07D57340a8ef931d7414E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "zrx-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ZRX / ETH", + "pair": [ + "", + "" + ], + "path": "zrx-eth", + "proxyAddress": "0x2Da4983a622a8498bb1a21FaE9D8F6C664939962", + "threshold": 2, + "valuePrefix": "", + "assetName": "0x", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ZRX", + "baseAssetClic": "ZRX_CR", + "blockchainName": "Ethereum", + "clicProductName": "ZRX/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x36A0448c46AaE145dD5BC320D5153426a2a586F5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LUSD / USD", + "pair": [ + "", + "" + ], + "path": "lusd-usd", + "proxyAddress": "0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0", + "threshold": 1, + "valuePrefix": "", + "assetName": "Liquity USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "LUSD", + "baseAssetClic": "LUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "LUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3737f955897310f7cAcbc5Cc5da9362aaD18B38c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "teth-wsteth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "tETH / wstETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "teth-wsteth-exchange-rate", + "proxyAddress": "0x7B2Fb2c667af80Bccc0B2556378352dFDE2be914", + "threshold": 0.0002, + "valuePrefix": "", + "assetName": "Treehouse ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "tETH", + "baseAssetClic": "tETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "tETH/wstETH-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "wstETH", + "quoteAssetClic": "wstETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x37DbB228A8BB97fC811913F305f2fAa01013b69C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tao-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TAO / USD", + "pair": [ + "", + "" + ], + "path": "tao-usd", + "proxyAddress": "0x1c88503c9A52aE6aaE1f9bb99b3b7e9b8Ab35459", + "threshold": 2, + "valuePrefix": "", + "assetName": "Bittensor", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "TAO", + "blockchainName": "Ethereum", + "clicProductName": "TAO/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3917430B7D6e8132b7E90Bfd7370ca02620F5454", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "aud-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AUD / USD", + "pair": [ + "", + "" + ], + "path": "aud-usd", + "proxyAddress": "0x77F9710E7d0A19669A13c055F62cd80d313dF022", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Australian Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "AUD", + "baseAssetClic": "AUD_FX", + "blockchainName": "Ethereum", + "clicProductName": "AUD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x39E31761911b9aaBAEF5fb81B18Fd1C24a60E884", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pyusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "PYUSD / USD", + "pair": [ + "", + "" + ], + "path": "pyusd-usd", + "proxyAddress": "0x8f1dF6D7F2db73eECE86a18b4381F4707b918FB1", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "PayPal USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "PYUSD", + "baseAssetClic": "PYUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "PYUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3B7f4DAd497F87eEC3417CBfBd592DE2340A9e8C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "uscc-nav-aave-llamarisk", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "1000000", + "name": "USCC NAV - Aave LlamaRisk", + "pair": [ + "", + "" + ], + "path": "uscc-nav-aave-llamarisk", + "proxyAddress": "0x19e2d716288751c5A59deaB61af012D5DF895962", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Superstate Crypto Carry Fund (USCC)", + "feedCategory": "custom", + "feedType": "Tokenized Asset", + "docs": { + "assetClass": "Tokenized Fund", + "baseAsset": "USCC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Superstate", + "hidden": true, + "marketHours": "NYSE", + "porAuditor": "Superstate", + "porSource": "Asset Manager API", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0x3D01b1956d6745Bd77Fb432F448E802145E4aeF1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "real-gdp-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "Real GDP - Level", + "pair": [ + "", + "" + ], + "path": "real-gdp-level", + "proxyAddress": "0x2b94a8B3E478a2984A0b50a4bB0F19827Ad0cef3", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "B of Chained 2017 USD", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0x3E9348C8a83549B594C51D5539f0Db4E3B0B5D90", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "xcn-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "XCN / USD", + "pair": [ + "", + "" + ], + "path": "xcn-usd", + "proxyAddress": "0xeb988B77b94C186053282BfcD8B7ED55142D3cAB", + "threshold": 2, + "valuePrefix": "", + "assetName": "Chain", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "XCN", + "baseAssetClic": "XCN_CR", + "blockchainName": "Ethereum", + "clicProductName": "XCN/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3F6047b77131ce78Ab4775feE2d38b7339471a01", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LBTC / BTC", + "pair": [ + "", + "" + ], + "path": "lbtc-btc", + "proxyAddress": "0x5c29868C58b6e15e2b962943278969Ab6a7D3212", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "LBTC / BTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "LBTC", + "baseAssetClic": "LBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "LBTC/BTC-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x3eC38C31bD2b83C6749b09D61a1C4e53748AEeF4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "zbu-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ZBU / USD", + "pair": [ + "", + "" + ], + "path": "zbu-usd", + "proxyAddress": "0x617689cAB8329d57fEa64f4C086190E6797b8B5e", + "threshold": 1.5, + "valuePrefix": "", + "assetName": "Zeebu", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ZBU", + "baseAssetClic": "ZBU_CR", + "blockchainName": "Ethereum", + "clicProductName": "ZBU/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4014F1F654a454785A6a97B9125FECFa88868192", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cbbtc-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "cbBTC Reserves", + "pair": [ + "", + "" + ], + "path": "cbbtc-por", + "proxyAddress": "0xcBe87Dc0Cf9d807848a3E703B01A90B28eCFb2a7", + "threshold": 0.5, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "cbBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Coinbase ", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x42C8Cb3565254006eFE97D60EdD2093d8f4ba35E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "solvbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "solvBTC / BTC", + "pair": [ + "", + "" + ], + "path": "solvbtc-btc", + "proxyAddress": "0x936B31C428C29713343E05D631e69304f5cF5f49", + "threshold": 1, + "valuePrefix": "", + "assetName": "Solv Protocol SolvBTC", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "solvBTC", + "baseAssetClic": "solvBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "solvBTC/BTC-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x42f871D7c4c0628033A9202aF1A08b3d4B56B4fd", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mantle-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Mantle Healthcheck", + "pair": [ + "", + "" + ], + "path": "mantle-hc", + "proxyAddress": "0x88E588b2f3C2224fBd9441C49eeF61761a3449e0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x4394595b7381A001fAA6a76CF47f4b9a04bF31A0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rsr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "RSR / USD", + "pair": [ + "", + "" + ], + "path": "rsr-usd", + "proxyAddress": "0x759bBC1be8F90eE6457C44abc7d443842a976d02", + "threshold": 2, + "valuePrefix": "", + "assetName": "Reserve Rights", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RSR", + "baseAssetClic": "RSR_CR", + "blockchainName": "Ethereum", + "clicProductName": "RSR/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x458138Fc0D67027E9A6778ef40a6ffC318c69061", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "COMP / USD", + "pair": [ + "", + "" + ], + "path": "comp-usd-shared-svr", + "proxyAddress": "0x203e994f3908cF886C6155c31742557D82c9B4a2", + "secondaryProxyAddress": "0x69B50fF403E995d9c4441a303438D9049dAC8cCD", + "threshold": 1, + "valuePrefix": "", + "assetName": "Compound", + "feedCategory": "new", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "COMP", + "baseAssetClic": "COMP_CR", + "blockchainName": "Ethereum", + "clicProductName": "COMP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x48ac3CD812680C39879A1Fd1666639dBC9B978C0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "avail-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AVAIL / USD", + "pair": [ + "", + "" + ], + "path": "avail-usd", + "proxyAddress": "0xEBca574f1cE4d17cd02c20F47Ef8210C08Cc4255", + "threshold": 2, + "valuePrefix": "", + "assetName": "Avail", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AVAIL", + "baseAssetClic": "AVAIL_CR", + "blockchainName": "Ethereum", + "clicProductName": "AVAIL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x48afBeDF849449b7B9eea101EdAbdc81417b04c8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "alcx-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ALCX / ETH", + "pair": [ + "", + "" + ], + "path": "alcx-eth", + "proxyAddress": "0x194a9AaF2e0b67c35915cD01101585A33Fe25CAa", + "threshold": 2, + "valuePrefix": "", + "assetName": "Alchemix", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ALCX", + "baseAssetClic": "ALCX_CR", + "blockchainName": "Ethereum", + "clicProductName": "ALCX/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x49048fe8df3db736699c1C8313E47E8e6dD221BB", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CRCLon / USD", + "pair": [ + "", + "" + ], + "path": "crclon-usd-shared-svr", + "proxyAddress": "0xC0457F67cac4eb0567A208955C332897a597A207", + "secondaryProxyAddress": "0x393899FeF73E3C08100BF9b8a78bA84769Fa5B96", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Circle Internet Group (Ondo Tokenized Stock)", + "feedCategory": "custom", + "feedType": "Equities", + "docs": { + "assetClass": "Equities", + "baseAsset": "CRCLon", + "baseAssetClic": "CRCLon_CR", + "blockchainName": "Ethereum", + "clicProductName": "CRCLon/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "US", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4D3aDF7F00e68C53C7FeEa132493dcEc5822f59A", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TSLAon / USD", + "pair": [ + "", + "" + ], + "path": "tslaon-usd-shared-svr", + "proxyAddress": "0x737401E0D1299D8A85b653Fd52823501f4FE0be0", + "secondaryProxyAddress": "0xED4E679adAFA9aBC97a3fA797dEE000d7b0ed247", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Tesla (Ondo Tokenized Stock)", + "feedCategory": "custom", + "feedType": "Equities", + "docs": { + "assetClass": "Equities", + "baseAsset": "TSLAon", + "baseAssetClic": "TSLAon_CR", + "blockchainName": "Ethereum", + "clicProductName": "TSLAon/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "US", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4F3EBf190f8889734424aE71Ac0B00e1A8013f3C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "LINK / USD", + "pair": [ + "", + "" + ], + "path": "link-usd-shared-svr", + "proxyAddress": "0xE5fa3A4e4208858ADdf2CDb4e12651E89f1f1A70", + "secondaryProxyAddress": "0x83B34662f65532e611A87EBed38063Dec889D5A7", + "threshold": 1, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "blockchainName": "Ethereum", + "clicProductName": "LINK/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4a3411ac2948B33c69666B35cc6d055B27Ea84f1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "btc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "BTC / USD", + "pair": [ + "", + "" + ], + "path": "btc-usd", + "proxyAddress": "0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "blockchainName": "Ethereum", + "clicProductName": "BTC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x4cf78A2083608153313e1D341Efb595fAFdF4CF8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sweth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SWETH / ETH", + "pair": [ + "", + "" + ], + "path": "sweth-eth", + "proxyAddress": "0xec21B3e882CE09928cb397DcfF31B15cBBD1e1C3", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Swell Ethereum", + "feedCategory": "hidden", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SWETH", + "blockchainName": "Ethereum", + "clicProductName": "SWETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x4ebCB4E84b15688316BbaA10B89b59505A989315", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "grt-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "GRT / ETH", + "pair": [ + "", + "" + ], + "path": "grt-eth", + "proxyAddress": "0x17D054eCac33D91F7340645341eFB5DE9009F1C1", + "threshold": 2, + "valuePrefix": "", + "assetName": "The Graph", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "GRT", + "baseAssetClic": "GRT_CR", + "blockchainName": "Ethereum", + "clicProductName": "GRT/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x506F678C8E426BA87427674f814AD2166c17981D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lrc-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "LRC / ETH", + "pair": [ + "", + "" + ], + "path": "lrc-eth", + "proxyAddress": "0x160AC928A16C93eD4895C2De6f81ECcE9a7eB7b4", + "threshold": 1, + "valuePrefix": "", + "assetName": "Loopring", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LRC", + "baseAssetClic": "LRC_CR", + "blockchainName": "Ethereum", + "clicProductName": "LRC/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "shutdownDate": "November 29th, 2023" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x50Fe0290c8ad3566f17b57A0ED382C948937781b", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pufeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "pufETH / ETH", + "pair": [ + "", + "" + ], + "path": "pufeth-eth", + "proxyAddress": "0xDe3f7Dd92C4701BCf59F47235bCb61e727c45f80", + "threshold": 1, + "valuePrefix": "", + "assetName": "pufETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PUFETH", + "baseAssetClic": "PUFETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "PUFETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x50e1007404025e412F13eD1e1C1e6F57957F6A6F", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pumpbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "PumpBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "pumpbtc-por", + "proxyAddress": "0xe80baC615c38D01c101B0B1b943b05E20C8c2f76", + "threshold": 5, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PumpBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "PumpBTC", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x51766d8b44551740eFd8A34AA569D15aA0A13eCe", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "total-marketcap-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "Total Marketcap / USD", + "pair": [ + "", + "" + ], + "path": "mcap-usd", + "proxyAddress": "0xEC8761a0A73c34329CA5B1D3Dc7eD07F30e836e2", + "threshold": 2, + "valuePrefix": "", + "assetName": "Total cryptocurrency market cap", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "Total_Marketcap", + "blockchainName": "Ethereum", + "clicProductName": "Total_Marketcap/USD-MCap-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Marketcap", + "productType": "Price", + "productTypeCode": "MCap", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x525B031c1eE01502c113500a2d1A999cD3F9C98F", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "yfi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "YFI / USD", + "pair": [ + "", + "" + ], + "path": "yfi-usd", + "proxyAddress": "0xA027702dbb89fbd58938e4324ac03B58d812b0E1", + "threshold": 1, + "valuePrefix": "", + "assetName": "Yearn Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "YFI", + "blockchainName": "Ethereum", + "clicProductName": "YFI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5406F7bfF74320e7EEB9ebf720E812599F71800c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mim-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MIM / USD", + "pair": [ + "", + "" + ], + "path": "mim-usd", + "proxyAddress": "0x7A364e8770418566e3eb2001A96116E6138Eb32F", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Magic Internet Money", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "MIM", + "baseAssetClic": "MIM_CR", + "blockchainName": "Ethereum", + "clicProductName": "MIM/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x556355Ab35b05F0d254378d3e5cbdFbE9Cdec891", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "metis-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "Metis Healthcheck", + "pair": [ + "", + "" + ], + "path": "metis-hc", + "proxyAddress": "0x3425455fe737cdaE8564640df27bbF2eCD56E584", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true, + "productSubType": "Health Check", + "productType": "Blockchain", + "productTypeCode": "Health" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x55A5f1E833e9412925502459e7AB3656a596591e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tusd-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "TUSD / ETH", + "pair": [ + "", + "" + ], + "path": "tusd-eth", + "proxyAddress": "0x3886BA987236181D98F2401c507Fb8BeA7871dF2", + "threshold": 1, + "valuePrefix": "", + "assetName": "TrueUSD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "TUSD", + "baseAssetClic": "TUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "TUSD/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x55fbFB9F8D4d03BEc3c466eaFBf35F973704661E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdtb-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDtb / USD", + "pair": [ + "", + "" + ], + "path": "usdtb-usd", + "proxyAddress": "0x66704DAD467A7cA508B3be15865D9B9F3E186c90", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "high", + "feedType": "", + "docs": {}, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x561bd2c4a9f8a360e4A0cA341A36533EA5227689", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "dolo-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "DOLO / USD", + "pair": [ + "", + "" + ], + "path": "dolo-usd", + "proxyAddress": "0x5c7a079dbf188dAbc66e389482849b05ACB17421", + "threshold": 2, + "valuePrefix": "", + "assetName": "Dolomite", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "DOLO", + "baseAssetClic": "DOLO_CR", + "blockchainName": "Ethereum", + "clicProductName": "DOLO/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x563F9b302aF72aeeb8A411228CDc65b30cA1CB75", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "gbp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "GBP / USD", + "pair": [ + "", + "" + ], + "path": "gbp-usd", + "proxyAddress": "0x5c0Ab2d9b5a7ed9f470386e82BB36A3613cDd4b5", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Pound Sterling", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "GBP", + "baseAssetClic": "GBP_FX", + "blockchainName": "Ethereum", + "clicProductName": "GBP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5763Fc5FaBca9080Ad12bCAFae7a335023b1F9B4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "chf-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CHF / USD", + "pair": [ + "", + "" + ], + "path": "chf-usd", + "proxyAddress": "0x449d117117838fFA61263B61dA6301AA2a88B13A", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Swiss Franc", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "CHF", + "baseAssetClic": "CHF_FX", + "blockchainName": "Ethereum", + "clicProductName": "CHF/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x592700e4FcDd674dC54d2681DED3B63f54F63f9A", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usds-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 82800, + "history": null, + "multiply": "100000000", + "name": "USDS / USD", + "pair": [ + "", + "" + ], + "path": "usds-usd", + "proxyAddress": "0xfF30586cD0F29eD462364C7e81375FC0C71219b1", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "USDS", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDS", + "baseAssetClic": "USDS_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDS/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5B4728BA4F1A210b3545959A4E0fB6c3a16FE8f7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eigen-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "EIGEN / USD", + "pair": [ + "", + "" + ], + "path": "eigen-usd", + "proxyAddress": "0xf2917e602C2dCa458937fad715bb1E465305A4A1", + "threshold": 2, + "valuePrefix": "", + "assetName": "Eigenlayer", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Crypto", + "baseAsset": "EIGEN", + "baseAssetClic": "EIGEN_CR", + "blockchainName": "Ethereum", + "clicProductName": "EIGEN/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5C00518D3d423EC59D553Af123Be8a63B11078CF", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "uscc-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 95400, + "history": null, + "multiply": "1000000", + "name": "USCC NAV per Share", + "pair": [ + "", + "" + ], + "path": "uscc-nav", + "proxyAddress": "0xAfFd8F5578E8590665de561bdE9E7BAdb99300d9", + "threshold": 1e-7, + "valuePrefix": "$", + "assetName": "Superstate Crypto Carry Fund (USCC)", + "feedCategory": "custom", + "feedType": "Tokenized Asset", + "docs": { + "assetClass": "Tokenized Fund", + "baseAsset": "USCC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Superstate", + "marketHours": "NYSE", + "porAuditor": "Superstate", + "porSource": "Asset Manager API", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0x5EFFB9e0D6B472E48C542842B0306a1C12c9627c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eeth-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "eETH Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "eeth-por", + "proxyAddress": "0xC8cd82067eA907EA4af81b625d2bB653E21b5156", + "threshold": 2, + "valuePrefix": "", + "valueSuffix": "ETH", + "assetName": "eETH", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "eETH", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "ether.fi", + "marketHours": "Crypto", + "porAuditor": "Beacon Chain / Cross-chain", + "porSource": "Wallet Address", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "ETH", + "reserveAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x5Eb719ab8afd65b35195A8C3FD343aD86C2044A3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bgbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BGBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "bgbtc-por", + "proxyAddress": "0xADcc914F882965Ef1B2f1043522b3B81ED081491", + "threshold": 0.5, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitget Wrapped Bitcoin (BGBTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "BGBTC", + "blockchainName": "Arbitrum", + "deliveryChannelCode": "DF", + "issuer": "Bitget", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x5a0efD6D1a058A46D3Ac4511861adB8F3540BD49", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": null, + "ens": "consumer-price-index", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": false, + "multiply": "1000000000000000000", + "name": "Consumer Price Index", + "pair": [ + "", + "" + ], + "path": "consumer-price-index", + "proxyAddress": "0x9a51192e065ECC6BDEafE5e194ce54702DE4f1f5", + "threshold": 1000, + "valuePrefix": "", + "assetName": "Personal Consumption Expenditures (PCE) US Monthly Index", + "feedCategory": "custom", + "feedType": "Economic index", + "docs": { + "assetClass": "Index", + "assetSubClass": "Tradfi", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Market", + "productType": "Index", + "productTypeCode": "MktIndex" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x5b7544c54E78777AFdD09620912AdBa36503BF91", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "soneium-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Soneium Healthcheck", + "pair": [ + "", + "" + ], + "path": "soneium-hc", + "proxyAddress": "0x498b4e83001acc364b2a73f827e9aB4B034ea215", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x5e2420cACE3650622f62B2713B2B3727FC8bCDd1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cbbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "cbBTC / USD", + "pair": [ + "", + "" + ], + "path": "cbbtc-usd", + "proxyAddress": "0x2665701293fCbEB223D11A08D826563EDcCE423A", + "threshold": 2, + "valuePrefix": "", + "assetName": "Coinbase Wrapped Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "CBBTC", + "baseAssetClic": "CBBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "CBBTC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x601009229b0215e4FC90C10c8145E066aE03d5F9", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "xsolvbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "xSolvBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "xsolvbtc-por", + "proxyAddress": "0x461790bDAF5aeD3df6a88cB97Dec42DD0EFA73c0", + "threshold": 2, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "xSolvBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Solv Protocol", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x62a897c3e81d809c7444BB63D7D51E1F2EbB6C3D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "frxusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "frxUSD / USD", + "pair": [ + "", + "" + ], + "path": "frxusd-usd", + "proxyAddress": "0x9B4a96210bc8D9D55b1908B465D8B0de68B7fF83", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Frax USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "FRXUSD", + "baseAssetClic": "FRXUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "FRXUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x63f71CB5c29c33656dCd5dcA144e12532A361bEF", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "enj-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ENJ / ETH", + "pair": [ + "", + "" + ], + "path": "enj-eth", + "proxyAddress": "0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B", + "threshold": 2, + "valuePrefix": "", + "assetName": "Enjin Coin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ENJ", + "baseAssetClic": "ENJ_CR", + "blockchainName": "Ethereum", + "clicProductName": "ENJ/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x6418Bb052FbB827A6022F4EC3F2d6A20444304EC", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sky-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SKY / USD", + "pair": [ + "", + "" + ], + "path": "sky-usd", + "proxyAddress": "0xee10fE5E7aa92dd7b136597449c3d5813cFC5F18", + "threshold": 2, + "valuePrefix": "", + "assetName": "Sky", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SKY", + "baseAssetClic": "SKY_CR", + "blockchainName": "Ethereum", + "clicProductName": "SKY/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x646772c691b2a84CA889f55253C560D38E3766e1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usd1-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USD1 / USD", + "pair": [ + "", + "" + ], + "path": "usd1-usd", + "proxyAddress": "0xF0d9bb015Cd7BfAb877B7156146dc09Bf461370d", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "World Liberty Financial USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USD1", + "baseAssetClic": "USD1_CR", + "blockchainName": "Ethereum", + "clicProductName": "USD1/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x64DEE1Bc46e817ed93dEA4815F071B20eD218E39", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WBTC Proof of Reserves", + "pair": [ + "WBTC", + "PoR" + ], + "path": "wbtc-por", + "proxyAddress": "0xa81FE04086865e63E12dD3776978E49DEEa2ea4e", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "BitGo", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet address", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x64c67984A458513C6BAb23a815916B1b1075cf3a", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "LINK / USD", + "pair": [ + "", + "" + ], + "path": "link-usd-svr", + "proxyAddress": "0x76F8C9E423C228E83DCB11d17F0Bd8aEB0Ca01bb", + "secondaryProxyAddress": "0xC7e9b623ed51F033b32AE7f1282b1AD62C28C183", + "threshold": 1, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "blockchainName": "Ethereum", + "clicProductName": "LINK/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x658Aa21601C8c0bB511C21999F7cad35B6A15192", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sushi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SUSHI / USD", + "pair": [ + "", + "" + ], + "path": "sushi-usd", + "proxyAddress": "0xCc70F09A6CC17553b2E31954cD36E4A2d89501f7", + "threshold": 1, + "valuePrefix": "", + "assetName": "Sushi", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUSHI", + "blockchainName": "Ethereum", + "clicProductName": "SUSHI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6795D4A47c9c8F4117b409D966259CdCf6A9Eb6E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "paxg-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "PAXG / USD", + "pair": [ + "", + "" + ], + "path": "paxg-usd", + "proxyAddress": "0x9944D86CEB9160aF5C5feB251FD671923323f8C3", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Pax Gold", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PAXG", + "baseAssetClic": "PAXG_CR", + "blockchainName": "Ethereum", + "clicProductName": "PAXG/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "XAU", + "underlyingAssetClic": "XAU_CO" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6AD3961c0348906504ff4125722e4Aa5146ff529", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "1inch-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "1INCH / USD", + "pair": [ + "", + "" + ], + "path": "1inch-usd", + "proxyAddress": "0xc929ad75B72593967DE83E7F7Cda0493458261D9", + "threshold": 1, + "valuePrefix": "", + "assetName": "1inch", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "1INCH", + "baseAssetClic": "1INCH_CR", + "blockchainName": "Ethereum", + "clicProductName": "1INCH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6AeA2D551798f32c7cd39469211197b58f608a7C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sand-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SAND / USD", + "pair": [ + "", + "" + ], + "path": "sand-usd", + "proxyAddress": "0x35E3f7E558C04cE7eEE1629258EcbbA03B36Ec56", + "threshold": 2, + "valuePrefix": "", + "assetName": "The Sandbox", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SAND", + "baseAssetClic": "SAND_CR", + "blockchainName": "Ethereum", + "clicProductName": "SAND/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6B3A1CFFD3136cfF5C49F3379A4Da721Bc4f5d68", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "buidl-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "100", + "name": "BUIDL NAV", + "pair": [ + "", + "" + ], + "path": "buidl-nav", + "proxyAddress": "0x6029F53A5Df21E5e70C460F5E4c9Aad20427B090", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 2 + }, + { + "compareOffchain": "", + "contractAddress": "0x6Cc5173Ffd8d674C64f2DC7237730Ff021829865", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ens-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ENS / USD", + "pair": [ + "", + "" + ], + "path": "ens-usd", + "proxyAddress": "0x5C00128d4d1c2F4f652C267d7bcdD7aC99C16E16", + "threshold": 2, + "valuePrefix": "", + "assetName": "Ethereum Name Service", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ENS", + "baseAssetClic": "ENS_CR", + "blockchainName": "Ethereum", + "clicProductName": "ENS/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x6D68A0636246d1dE3EbE972AD8bEE886B10610Ee", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mkr-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "MKR / ETH", + "pair": [ + "", + "" + ], + "path": "mkr-eth", + "proxyAddress": "0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2", + "threshold": 1, + "valuePrefix": "", + "assetName": "Maker", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MKR", + "baseAssetClic": "MKR_CR", + "blockchainName": "Ethereum", + "clicProductName": "MKR/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x6dFF3fE0bF312f54551788f843F06177fE89C4bd", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rseth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "RSETH / ETH", + "pair": [ + "", + "" + ], + "path": "rseth-eth", + "proxyAddress": "0x03c68933f7a3F76875C0bc670a58e69294cDFD01", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Kelp DAO Restaked ETH", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RSETH", + "blockchainName": "Ethereum", + "clicProductName": "RSETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x6f3F8d82694d52E6B6171A7b26A88c9554e7999b", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "BTC / USD", + "pair": [ + "", + "" + ], + "path": "btc-usd-shared-svr", + "proxyAddress": "0x8adE2c8d55F7ee2C9234ad868D44a60Eb9C07f8c", + "secondaryProxyAddress": "0x91D32e6f01d6473b596f54c6E304e06d774f86b2", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "blockchainName": "Ethereum", + "clicProductName": "BTC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x709783ab12b65fD6cd948214EEe6448f3BdD72A3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "dai-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "DAI / USD", + "pair": [ + "", + "" + ], + "path": "dai-usd", + "proxyAddress": "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "DAI", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "DAI", + "baseAssetClic": "DAI_CR", + "blockchainName": "Ethereum", + "clicProductName": "DAI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x714FF6b6Fc99c2Ee37BAC73aB41c8E4ae30508a5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "knc-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "KNC / ETH", + "pair": [ + "", + "" + ], + "path": "knc-eth", + "proxyAddress": "0x656c0544eF4C98A6a98491833A89204Abb045d6b", + "threshold": 2, + "valuePrefix": "", + "assetName": "Kyber Network Crystal", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "KNC", + "baseAssetClic": "KNC_CR", + "blockchainName": "Ethereum", + "clicProductName": "KNC/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x73dD57b09dDE3eb26Be8A1C93Bb9991Aa3Bc103C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "jtrsy-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "1000000", + "name": "JTRSY NAV - Aave LlamaRisk", + "pair": [ + "", + "" + ], + "path": "jtrsy-nav-aave-llamarisk", + "proxyAddress": "0x23adce82907D20c509101E2Af0723A9e16224EFb", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Janus Henderson Treasury Fund", + "feedCategory": "custom", + "feedType": "Fixed Income", + "docs": { + "assetClass": "U.S. Treasuries", + "baseAsset": "JTRSY", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Anemoy", + "hidden": true, + "porAuditor": "Anemoy", + "porSource": "Asset Manager", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0x75c4B587EC408A4B5877f69F532221A0991d8e09", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USR / USD", + "pair": [ + "", + "" + ], + "path": "usr-usd", + "proxyAddress": "0x34ad75691e25A8E9b681AAA85dbeB7ef6561B42c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Resolv USR", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USR", + "baseAssetClic": "USR_CR", + "blockchainName": "Ethereum", + "clicProductName": "USR/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x78281937B869bAaDedDdA3d62fC4b6Fc0a196b61", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sxt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SXT / USD", + "pair": [ + "", + "" + ], + "path": "sxt-usd", + "proxyAddress": "0x2D27d9e1b74936D8E83c4BA118F09A4c4a897f62", + "threshold": 2, + "valuePrefix": "", + "assetName": "Space and Time", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SXT", + "baseAssetClic": "SXT_CR", + "blockchainName": "Ethereum", + "clicProductName": "SXT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x786ba26Ee47097E6A5086E742aEf5Efbc6A93447", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ink-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Ink Healthcheck", + "pair": [ + "", + "" + ], + "path": "ink-hc", + "proxyAddress": "0x9656D3A00402bD9c18EeF89b29ca6810734ABCAd", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x793f1aEf27F38e93116725Ac26959E3E9a03704c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "busd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BUSD / USD", + "pair": [ + "", + "" + ], + "path": "busd-usd", + "proxyAddress": "0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Binance USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "BUSD", + "baseAssetClic": "BUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "BUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x7A5dc0C6A59e76B3A65c73224316C110663CEd1B", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eth-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "ETH / BTC", + "pair": [ + "", + "" + ], + "path": "eth-btc", + "proxyAddress": "0xAc559F25B1619171CbC396a50854A3240b6A4e99", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "ETH/BTC-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x7c7FdFCa295a787ded12Bb5c1A49A8D2cC20E3F8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "ETH / USD", + "pair": [ + "", + "" + ], + "path": "eth-usd-svr", + "proxyAddress": "0x5147eA642CAEF7BD9c1265AadcA78f997AbB9649", + "secondaryProxyAddress": "0x5424384B256154046E9667dDFaaa5e550145215e", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "ETH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x7d4E742018fb52E48b08BE73d041C18B21de6Fb5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eth-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "ETH / USD", + "pair": [ + "", + "" + ], + "path": "eth-usd", + "proxyAddress": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "ETH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x7d95b7bf7bB7750d818F42Df114739B6C88CF9bC", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rlusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "RLUSD / USD", + "pair": [ + "", + "" + ], + "path": "rlusd-usd", + "proxyAddress": "0x26C46B7aD0012cA71F2298ada567dC9Af14E7f2A", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Ripple USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "RLUSD", + "baseAssetClic": "RLUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "RLUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x80C1B1EE029F05889E3A693fD8c5f76f9b9fe194", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "susdf-usdf-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "sUSDf / USDf Exchange Rate", + "pair": [ + "", + "" + ], + "path": "susdf-usdf-exchange-rate", + "proxyAddress": "0xe471bc940AA9831a0AeA21E6F40C1A1236EB4BB3", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "Staked Falcon USD", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "sUSDf", + "baseAssetClic": "sUSDf_CR", + "blockchainName": "Ethereum", + "clicProductName": "sUSDf/USDf-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USDf", + "quoteAssetClic": "USDf_CR", + "underlyingAsset": "USDf", + "underlyingAssetClic": "USDf_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x80e1Cd5489a144ac6e0A9D1d69EBec9076b4d21c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "swell-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SWELL / ETH", + "pair": [ + "", + "" + ], + "path": "swell-eth", + "proxyAddress": "0x2a638b1203a3B62FF003598B7165Fc5cd5b13B00", + "threshold": 2, + "valuePrefix": "", + "assetName": "Swell", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SWELL", + "baseAssetClic": "SWELL_CR", + "blockchainName": "Ethereum", + "clicProductName": "SWELL/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x816F26DB1086548881217694cfC8A1F915B62D11", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ftm-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "FTM / ETH", + "pair": [ + "", + "" + ], + "path": "ftm-eth", + "proxyAddress": "0x2DE7E4a9488488e0058B95854CC2f7955B35dC9b", + "threshold": 3, + "valuePrefix": "", + "assetName": "Fantom", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "FTM", + "baseAssetClic": "FTM_CR", + "blockchainName": "Ethereum", + "clicProductName": "FTM/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x81Fa0A005D9b9d5Bdf7e71b05EBA57B1c1fE3756", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "susde-usd-calculated", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "sUSDe / USD Calculated", + "pair": [ + "", + "" + ], + "path": "susde-usd-calculated", + "proxyAddress": "0xeD9960f685C3c4d6aa937E56169a41C19D0aC9c6", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x829590E9A8C9AD528E39A8c5E0dd692aFa1bcae7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "dpi-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "DPI / ETH", + "pair": [ + "", + "" + ], + "path": "dpi-eth", + "proxyAddress": "0x029849bbc0b1d93b85a8b6190e979fd38F5760E2", + "threshold": 2, + "valuePrefix": "", + "assetName": "DeFi Pulse Index", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Index", + "assetSubClass": "Crypto", + "baseAsset": "DPI", + "baseAssetClic": "DPI_IX", + "blockchainName": "Ethereum", + "clicProductName": "DPI/ETH-CalcInidex-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Calculated", + "productType": "Index", + "productTypeCode": "CalcInidex", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x82Cd6b814Cf9cC8E4164480F7e1347ca38BcB4Fa", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lseth-eth-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "LsETH / ETH Exchange Rate", + "pair": [ + "", + "" + ], + "path": "lseth-eth-exchange-rate", + "proxyAddress": "0xE858728eB31a25C4AcCcE17d01B68dCFC3A0ED2C", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "Liquid Staked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "LSETH", + "baseAssetClic": "LSETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "LSETH/ETH-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x83cE6dbda88D4b59b370d765567d2CaB460bBdc9", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "21btc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "21BTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "21btc-por", + "proxyAddress": "0x43921Ca0eca1EA69722c048A6afbc2CAd0BB80e9", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "21BTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "21.co", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet address", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Bitcoin Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x841385263b2192A6f4b14353574C02bf0577473d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "shv-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SHV / USD", + "pair": [ + "", + "" + ], + "path": "shv-usd", + "proxyAddress": "0xc04611C43842220fd941515F86d1DDdB15F04e46", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "iShares Short Treasury Bond ETF", + "feedCategory": "low", + "feedType": "Equities", + "docs": { + "assetClass": "ETF", + "assetSubClass": "US", + "baseAsset": "SHV", + "baseAssetClic": "SHV_EQ", + "blockchainName": "Ethereum", + "clicProductName": "SHV/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "NYSE", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x84455DeB8f606b83E7C4E6bCBbF18AC050C780F9", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "solvbtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SOLVBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "solvbtc-btc-exchange-rate", + "proxyAddress": "0x4e25cfdc5f53c2CdeD13c1472E628eFd35c99C83", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "Solv Protocol SolvBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "solvBTC", + "baseAssetClic": "solvBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "solvBTC/BTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x8476b81b4dE6eD493383fA2A2851Ec590207ebAC", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cny-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CNY / USD", + "pair": [ + "", + "" + ], + "path": "cny-usd", + "proxyAddress": "0xeF8A4aF35cd47424672E3C590aBD37FBB7A7759a", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Chinese Yuan", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "CNY", + "baseAssetClic": "CNY_FX", + "blockchainName": "Ethereum", + "clicProductName": "CNY/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_CNY", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x84BB206a5B39DBB5Ea378074c9cBEde397F575dD", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bal-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "BAL / ETH", + "pair": [ + "", + "" + ], + "path": "bal-eth", + "proxyAddress": "0xC1438AA3823A6Ba0C159CfA8D98dF5A994bA120b", + "threshold": 2, + "valuePrefix": "", + "assetName": "Balancer", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BAL", + "baseAssetClic": "BAL_CR", + "blockchainName": "Ethereum", + "clicProductName": "BAL/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x84Cf90cfF80828dD32c69A2f25a09FC1ccbB7fc3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "snx-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SNX / ETH", + "pair": [ + "", + "" + ], + "path": "snx-eth", + "proxyAddress": "0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c", + "threshold": 2, + "valuePrefix": "", + "assetName": "Synthetix Network", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SNX", + "baseAssetClic": "SNX_CR", + "blockchainName": "Ethereum", + "clicProductName": "SNX/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x84e32Ab7a70be2bE619eBcB06D2C725f8b7Fb839", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "dai-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "DAI / ETH", + "pair": [ + "", + "" + ], + "path": "dai-eth", + "proxyAddress": "0x773616E4d11A78F511299002da57A0a94577F1f4", + "threshold": 1, + "valuePrefix": "", + "assetName": "DAI", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "DAI", + "baseAssetClic": "DAI_CR", + "blockchainName": "Ethereum", + "clicProductName": "DAI/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x87999204aB5596A39EB748E58b38Ed4154609B2E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ustb-aum", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 93600, + "history": null, + "multiply": "100000000", + "name": "USTB AUM", + "pair": [ + "", + "" + ], + "path": "ustb-aum", + "proxyAddress": "0xf3Ab3e54DE3b4BCaEbef6C66Cec0a3a88f262757", + "threshold": 1e-7, + "valuePrefix": "$", + "assetName": "Superstate Short Duration US Government Securities Fund (USTB)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Tokenized Asset", + "baseAsset": "USTB", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Superstate", + "marketHours": "NYSE", + "porSource": "Asset Manager API", + "porType": "Off-Chain", + "productType": "SmartAUM", + "productTypeCode": "AUM", + "reserveAsset": "U.S. Treasury Bills", + "underlyingAsset": "U.S. Treasury Bills" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x88cedA42c33fd19D58E161964190377b9eE01500", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "real-final-sales-to-private-domestic-purchasers-level", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "1000", + "name": "Real Final Sales to Private Domestic Purchasers — Level", + "pair": [ + "", + "" + ], + "path": "real-final-sales-to-private-domestic-purchasers-level", + "proxyAddress": "0xA5265f5B54D0AdD0D48BE88BC3CB0Cdb1a54B816", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "B of Chained 2017 USD", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 3 + }, + { + "compareOffchain": "", + "contractAddress": "0x88db96ca551e0A0a2D8646999410b60197979311", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ape-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "APE / USD", + "pair": [ + "", + "" + ], + "path": "ape-usd", + "proxyAddress": "0xD10aBbC76679a20055E167BB80A24ac851b37056", + "threshold": 2, + "valuePrefix": "", + "assetName": "APECoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "APE", + "baseAssetClic": "APE_CR", + "blockchainName": "Ethereum", + "clicProductName": "APE/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x8F73090a7c58B8BDcC9A93cBB6816e5cC4f01E8c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "frax-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "FRAX / USD", + "pair": [ + "", + "" + ], + "path": "frax-usd", + "proxyAddress": "0xB9E1E3A9feFf48998E45Fa90847ed4D467E8BcfD", + "threshold": 1, + "valuePrefix": "", + "assetName": "FRAX", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "FRAX", + "baseAssetClic": "FRAX_CR", + "blockchainName": "Ethereum", + "clicProductName": "FRAX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x8a43cc06554Ab042FFBf07e64cfb8FeE4E673422", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "steth-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 21600, + "history": null, + "multiply": "1000000000000000000", + "name": "stETH Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "steth-por", + "proxyAddress": "0xAd410E655C0fE4741F573152592eeb766e686CE7", + "threshold": 0.2, + "valuePrefix": "", + "assetName": "Ethereum (ETH)", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "stETH", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Lido", + "marketHours": "Crypto", + "porAuditor": "Beacon Chain / Cross-chain", + "porSource": "Wallet Address", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "ETH", + "reserveAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x8c944f66a996b5399F51dc3d8d023E07Bb0767fD", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "high-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "HIGH / USD", + "pair": [ + "", + "" + ], + "path": "high-usd", + "proxyAddress": "0x5C8D8AaB4ffa4652753Df94f299330Bb4479bF85", + "threshold": 2, + "valuePrefix": "", + "assetName": "Highstreet", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "HIGH", + "baseAssetClic": "HIGH_CR", + "blockchainName": "Ethereum", + "clicProductName": "HIGH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x8fEe58B0F1a9d47A4EAa2eCD6b020f6F1be31d35", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "yfi-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "YFI / ETH", + "pair": [ + "", + "" + ], + "path": "yfi-eth", + "proxyAddress": "0x7c5d4F8345e66f68099581Db340cd65B078C41f4", + "threshold": 1, + "valuePrefix": "", + "assetName": "Yearn Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "YFI", + "baseAssetClic": "YFI_CR", + "blockchainName": "Ethereum", + "clicProductName": "YFI/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x90902B68e5049d56954bDfE4C3b235a805C8f153", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mana-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "MANA / ETH", + "pair": [ + "", + "" + ], + "path": "mana-eth", + "proxyAddress": "0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9", + "threshold": 2, + "valuePrefix": "", + "assetName": "Decentraland", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MANA", + "baseAssetClic": "MANA_CR", + "blockchainName": "Ethereum", + "clicProductName": "MANA/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x90DC245bbF0a441651c23437F95705EBBF2498bd", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rdnt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "RDNT / USD", + "pair": [ + "", + "" + ], + "path": "rdnt-usd", + "proxyAddress": "0x393CC05baD439c9B36489384F11487d9C8410471", + "threshold": 2, + "valuePrefix": "", + "assetName": "Radiant Capital", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RDNT", + "blockchainName": "Ethereum", + "clicProductName": "RDNT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x90Fb891e7EE51972f7D9309a6B812D04ED2643c7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usd0-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USD0 / USD", + "pair": [ + "", + "" + ], + "path": "usd0-usd", + "proxyAddress": "0x7e891DEbD8FA0A4Cf6BE58Ddff5a8ca174FebDCB", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Usual USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USD0", + "baseAssetClic": "USD0_CR", + "blockchainName": "Ethereum", + "clicProductName": "USD0/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x918C6cDE1CDd940934820B8FA3a2C8B26a60736C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pumpbtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "PumpBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "pumpbtc-btc-exchange-rate", + "proxyAddress": "0x6CE4Ef3689F26edD40ed3ccbE3Cc29dab62C915f", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "PumpBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "PumpBTC", + "baseAssetClic": "PumpBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "PumpBTC/BTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x92455F206F6433f161c09a31B0E02A195AFcf23c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "rpl-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "RPL / USD", + "pair": [ + "", + "" + ], + "path": "rpl-usd", + "proxyAddress": "0x4E155eD98aFE9034b7A5962f6C84c86d869daA9d", + "threshold": 2, + "valuePrefix": "", + "assetName": "Rocket Pool", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "RPL", + "blockchainName": "Ethereum", + "clicProductName": "RPL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x92615843016d046678ED9176d02287db083faC62", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdl-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDL / USD", + "pair": [ + "", + "" + ], + "path": "usdl-usd", + "proxyAddress": "0x8697D23509F328F90135933de0Dde38Eb86d4893", + "threshold": 1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "high", + "feedType": "", + "docs": {}, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x931f90Ee9515B4b842A34A0c1f7047CBF10d1138", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "unichain-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Unichain Healthcheck", + "pair": [ + "", + "" + ], + "path": "unichain-hc", + "proxyAddress": "0x5d8017CDC949AA0a6c00999B970892456d4f5fF3", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x94Ac91B209043162e6761942563A9f1F8dd75209", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "solvbtcbbn-solvbtc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SolvBTC.BBN / SolvBTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "solvbtc.bbn-solvbtc-exchange-rate", + "proxyAddress": "0x1f34794A16D644b9810477EbF3f0b3870141E2e3", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "SolvBTC.BBN / SolvBTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SolvBTC.BBN", + "baseAssetClic": "SolvBTC.BBN_CR", + "blockchainName": "Ethereum", + "clicProductName": "SolvBTC.BBN/SolvBTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "SolvBTC", + "quoteAssetClic": "SolvBTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x95A0D99507e9b248C18C4Dc111Af9EB66681992e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "grt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "GRT / USD", + "pair": [ + "", + "" + ], + "path": "grt-usd", + "proxyAddress": "0x86cF33a451dE9dc61a2862FD94FF4ad4Bd65A5d2", + "threshold": 2, + "valuePrefix": "", + "assetName": "The Graph", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "GRT", + "baseAssetClic": "GRT_CR", + "blockchainName": "Ethereum", + "clicProductName": "GRT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x961e0E0f63e4E1eF2F8e93579195371af39A4f2D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ust-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "UST / ETH", + "pair": [ + "", + "" + ], + "path": "ust-eth", + "proxyAddress": "0xa20623070413d42a5C01Db2c8111640DD7A5A03a", + "threshold": 3, + "valuePrefix": "", + "assetName": "Terra USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "UST", + "baseAssetClic": "UST_CR", + "blockchainName": "Ethereum", + "clicProductName": "UST/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x966Dad3B93C207A9EE3a79C336145e013C5cD3fc", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eur-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "EUR / USD", + "pair": [ + "", + "" + ], + "path": "eur-usd", + "proxyAddress": "0xb49f677943BC038e9857d61E7d053CaA2C1734C1", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Euro", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "EUR", + "baseAssetClic": "EUR_FX", + "blockchainName": "Ethereum", + "clicProductName": "EUR/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x96Ff8D481512C606B4d90297eF49667314888a70", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "zksync-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "ZKsync Healthcheck", + "pair": [ + "", + "" + ], + "path": "zksync-hc", + "proxyAddress": "0x987517b50230De2042750570D8fE3783ee115975", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0x96d6e33B411dc1f4E3F1e894A5A5d9CE0F96738D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "link-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "LINK / USD", + "pair": [ + "", + "" + ], + "path": "link-usd", + "proxyAddress": "0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "blockchainName": "Ethereum", + "clicProductName": "LINK/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x980c372084158c9132135728c4Dbf40F5E683E31", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mln-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "MLN / ETH", + "pair": [ + "", + "" + ], + "path": "mln-eth", + "proxyAddress": "0xDaeA8386611A157B08829ED4997A8A62B557014C", + "threshold": 2, + "valuePrefix": "", + "assetName": "Melon", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MLN", + "baseAssetClic": "MLN_CR", + "blockchainName": "Ethereum", + "clicProductName": "MLN/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9929624Dab8665DdcAa1Acf888D9e770859c5a63", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "susd-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SUSD / ETH", + "pair": [ + "", + "" + ], + "path": "susd-eth", + "proxyAddress": "0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757", + "threshold": 1, + "valuePrefix": "", + "assetName": "sUSD (Synthetix)", + "feedCategory": "hidden", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "SUSD", + "baseAssetClic": "SUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "SUSD/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x99528E2d228e322AEAEF24Dd763348a98A50c385", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "oeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "OETH / ETH", + "pair": [ + "", + "" + ], + "path": "oeth-eth", + "proxyAddress": "0x703118C4CbccCBF2AB31913e0f8075fbbb15f563", + "threshold": 1, + "valuePrefix": "", + "assetName": "Origin Ether", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "OETH", + "baseAssetClic": "OETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "OETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9959F0691dEE3Af699728977C37ee1E348E99202", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "spell-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SPELL / USD", + "pair": [ + "", + "" + ], + "path": "spell-usd", + "proxyAddress": "0x8c110B94C5f1d347fAcF5E1E938AB2db60E3c9a8", + "threshold": 1, + "valuePrefix": "", + "assetName": "Spell Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SPELL", + "baseAssetClic": "SPELL_CR", + "blockchainName": "Ethereum", + "clicProductName": "SPELL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x997A883dC034ae61d44B19A9f3Ce06ff341a8821", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "real-final-sales-to-private-domestic-purchasers-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "Real Final Sales to Private Domestic Purchasers — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "real-final-sales-to-private-domestic-purchasers-percentage", + "proxyAddress": "0xB06A26DF4Ab5853AaCCF2d21FAa00B82362684C3", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0x99BC071f317BEF648E5e84f7E0600423360C0Cd1", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "stbt-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "STBT Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "stbt-por", + "proxyAddress": "0xad4A9bED9a5E2c1c9a6E43D35Db53c83873dd901", + "threshold": 0.001, + "valuePrefix": "$", + "assetName": "US Treasury Bills and Repurchase Agreements (Repo)", + "feedCategory": "custom", + "feedType": "US Treasuries", + "docs": { + "assetClass": "US Treasuries", + "baseAsset": "STBT", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Matrixdock", + "porAuditor": "Harris & Trotter", + "porSource": "Third-party", + "porType": "Off-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "ripcordApi": "https://api.harrisandtrotter.co.uk/api/balances?client_name=matrixport" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9Bc91f0E55b0d6509F65fd8C4b34b89F23AEfA35", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ftt-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "FTT / ETH", + "pair": [ + "", + "" + ], + "path": "ftt-eth", + "proxyAddress": "0xF0985f7E2CaBFf22CecC5a71282a89582c382EFE", + "threshold": 2, + "valuePrefix": "", + "assetName": "FTX Token", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "FTT", + "baseAssetClic": "FTT_CR", + "blockchainName": "Ethereum", + "clicProductName": "FTT/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9C838bE86802377A2847EDB416755f79c7CaE8D8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usyc-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "100000000", + "name": "USYC NAV - Aave LlamaRisk", + "pair": [ + "", + "" + ], + "path": "usyc-nav-aave-llamarisk", + "proxyAddress": "0xE8E65Fb9116875012F5990Ecaab290B3531DbeB9", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Circle USYC", + "feedCategory": "custom", + "feedType": "Fixed Income", + "docs": { + "assetClass": "U.S. Treasuries", + "baseAsset": "USYC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Circle", + "hidden": true, + "marketHours": "NYSE", + "porAuditor": "Circle", + "porSource": "Asset Manager API", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x9E3AABA3B04264DD009437F48eBFD70713dd0667", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wampl-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WAMPL / USD", + "pair": [ + "", + "" + ], + "path": "wampl-usd", + "proxyAddress": "0xAcFCF155a0de611414C510D43446c27a4EE6a758", + "threshold": 2, + "valuePrefix": "", + "assetName": "Wrapped Ampleforth", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "wAMPL", + "baseAssetClic": "wAMPL_CR", + "blockchainName": "Ethereum", + "clicProductName": "wAMPL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9c7CF045f964B45FFC6AA0Ffbffd7bb6d1b470A3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "php-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "PHP / USD", + "pair": [ + "", + "" + ], + "path": "php-usd", + "proxyAddress": "0x3C7dB4D25deAb7c89660512C5494Dc9A3FC40f78", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Philippines Peso", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "PHP", + "baseAssetClic": "PHP_FX", + "blockchainName": "Ethereum", + "clicProductName": "PHP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex_PHP", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0x9d5dcBFe48C516A1De7A2Be7981F70545Fc118Dd", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ustb-nav-aave-llamarisk", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "1000000", + "name": "USTB NAV - Aave LlamaRisk", + "pair": [ + "", + "" + ], + "path": "ustb-nav-aave-llamarisk", + "proxyAddress": "0xde49c7B5C0E54b1624ED21C7D88bA6593d444Aa0", + "threshold": 0.0001, + "valuePrefix": "", + "assetName": "Superstate Short Duration US Government Securities Fund (USTB)", + "feedCategory": "custom", + "feedType": "Fixed Income", + "docs": { + "assetClass": "U.S. Treasuries", + "baseAsset": "USTB", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Superstate", + "hidden": true, + "marketHours": "NYSE", + "porAuditor": "Superstate", + "porSource": "Asset Manager API", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0x9df238BE059572d7211F1a1a5fEe609F979AAD2d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDT / USD", + "pair": [ + "", + "" + ], + "path": "usdt-usd-svr", + "proxyAddress": "0x7bB7bF4ca536DbC49545704BFAcaa13633D18718", + "secondaryProxyAddress": "0x62c2ab773B7324ad9e030D777989B3b5d5c54c0A", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "Tether USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDT", + "baseAssetClic": "USDT_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x9e6e40dC0A35D6eD96BB09D928261EB598523645", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "badger-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "BADGER / ETH", + "pair": [ + "", + "" + ], + "path": "badger-eth", + "proxyAddress": "0x58921Ac140522867bf50b9E009599Da0CA4A2379", + "threshold": 2, + "valuePrefix": "", + "assetName": "Badger DAO", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BADGER", + "baseAssetClic": "BADGER_CR", + "blockchainName": "Ethereum", + "clicProductName": "BADGER/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xA0B5260BDfD1011C4bcdc7A099C75BFf6340B38C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "jpy-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "JPY / USD", + "pair": [ + "", + "" + ], + "path": "jpy-usd", + "proxyAddress": "0xBcE206caE7f0ec07b545EddE332A47C2F75bbeb3", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Japanese Yen", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "JPY", + "baseAssetClic": "JPY_FX", + "blockchainName": "Ethereum", + "clicProductName": "JPY/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA216602297953BDE22582E7B2D5633d2F404d798", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "trump-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TRUMP / USD", + "pair": [ + "", + "" + ], + "path": "trump-usd", + "proxyAddress": "0x7f0347903F413a6C4c540f39145E2a2249639931", + "threshold": 5, + "valuePrefix": "", + "assetName": "Official Trump", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "TRUMP", + "baseAssetClic": "TRUMP_CR", + "blockchainName": "Ethereum", + "clicProductName": "TRUMP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA3c0D69CedFf5b173Bc496074003dCe9C503e861", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cvx-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "CVX / ETH", + "pair": [ + "", + "" + ], + "path": "cvx-eth", + "proxyAddress": "0xC9CbF687f43176B302F03f5e58470b77D07c61c6", + "threshold": 2, + "valuePrefix": "", + "assetName": "Convex Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CVX", + "baseAssetClic": "CVX_CR", + "blockchainName": "Ethereum", + "clicProductName": "CVX/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xA5e3A55cEa42B86560a5215094981c300899199D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WBTC / BTC", + "pair": [ + "", + "" + ], + "path": "wbtc-btc", + "proxyAddress": "0xfdFD9C85aD200c506Cf9e21F1FD8dd01932FBB23", + "threshold": 2, + "valuePrefix": "", + "assetName": "Wrapped Bitcoin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WBTC", + "baseAssetClic": "WBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "WBTC/BTC-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1", + "name": "sUSDe-USDe Exchange Rate", + "pair": [ + "", + "" + ], + "path": "susde-usde-exchange-rate-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 0, + "feedId": "0x00030b04d917b020da9373073eebdf46a804972050dc1c28f6fb4e9975e84b69", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "10000000000", + "name": "truAPT-APT Exchange Rate - Production Mainnet", + "pair": [ + "", + "" + ], + "path": "truapt-apt-exchange-rate-df-stream-eth-production-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 10, + "feedId": "0x00030b04d917b020da9373073eebdf46a804972050dc1c28f6fb4e9975e84e67", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + }, + { + "operator": "keystone-asset-linkPool" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000", + "name": "eAPT-APT Exchange Rate - Production Mainnet", + "pair": [ + "", + "" + ], + "path": "eapt-apt-exchange-rate-df-stream-eth-production-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 12, + "feedId": "0x00030b04d917b020da9373073eebdf46a804972050dc1c28f6fb4e9975e84e74", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + }, + { + "operator": "keystone-asset-linkPool" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "100000000", + "name": "aBTC PoR Production Mainnet", + "pair": [ + "", + "" + ], + "path": "abtc-por-df-stream-eth-production-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 8, + "feedId": "0x00030b04d917b020da9373073eebdf46a804972050dc1c28f6fb4e9975e84e96", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + }, + { + "operator": "keystone-asset-linkPool" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "METIS/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "metis-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x00031f515c01d7f69717484e21ebf07dcce86b93045560d0ff25e79c32234118", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "DAI/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "dai-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x00032bbb6127fc18fc6356830e4737c03ae93bfb5220875b6ee544798895bac2", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "APT/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "apt-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x00032ca4215132a8285b1bcf74d321ae35d18e58eeb27b41c7cd25afd317c63d", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "USDT/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "usdt-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x000337a410669bfc9853476b132109a76d8843ba74ef6316d67b20c45c4aa306", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "WEMIX/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "wemix-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x00033aa27e0f4dd0247c49bf3ce5a0d6040e922ecdacfef75237b0ca604d22a8", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "CELO/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "celo-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x00036a2fa865eff09cdd90b81d90c9c97e0a84dd7367c3c9ff8b141d60b87197", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "CAKE/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "cake-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 18, + "feedId": "0x00036ee47faf9e1fa0f51c6569639435f033907be7953671a87c625a6ad44897", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "USD1/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "USD1-usd-ref-price-df-stream-eth-production-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 18, + "feedId": "0x00036ee47faf9e1fa0f51c6569639435f033907be7953671a87c625a6ad44e89", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + }, + { + "operator": "keystone-asset-linkPool" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "USDE/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "usde-usd-ref-price-df-stream-eth-production-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "feedType": "Crypto" + }, + "decimals": 18, + "feedId": "0x00036ee47faf9e1fa0f51c6569639435f033907be7953671a87c625a6ad55edc", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + }, + { + "operator": "keystone-asset-linkPool" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "AVAX/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "avax-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x000393bb1ac43bee8457414978676c7d54d485decf629a9a8222c81e50d2ff06", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "ETH/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "eth-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003969b9f9a7449bb6103126212f320d518a6be1dbe2405955102bf6e3943f1", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "BNB/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "bnb-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003ae793fe8e95c53946a0227d29c70806515983cf7b06e8848aff3b1b1b891", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "POL/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "pol-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003b624d9d8cc1e111e89b6d7d4a15a3ce9743a280f30036a5a0171acf36c26", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "LINK/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "link-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003beb0c3c6d354b5198196755d983e24d68e9913dfd638c05e59a431190a10", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "BTC/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "btc-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003d6f7b434e394fb9d3d8234a6b2d887a82ca247100b4409ff321413457370", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-01node" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-chainlink" + } + ] + }, + { + "compareOffchain": "", + "contractAddress": "0xA618f119504455762c9bBbcE4aC9EE7fde457d05", + "contractType": "verifier", + "contractVersion": 1001, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "history": null, + "multiply": "1000000000000000000", + "name": "USDC/USD-RefPrice-DF-stream-EthereumMainnet-001", + "pair": [ + "", + "" + ], + "path": "usdc-usd-ref-price-df-stream-eth-mainnet-001", + "proxyAddress": null, + "threshold": 0, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "crypto", + "docs": { + "feedType": "crypto" + }, + "decimals": 18, + "feedId": "0x0003ed860c7faca03b33565610952a96d1d5984108e4b56f4871a160a54051b6", + "sourceChain": 1, + "status": "live", + "oracles": [ + { + "operator": "keystone-asset-chainlayer" + }, + { + "operator": "keystone-asset-dexTrac" + }, + { + "operator": "keystone-asset-fiews" + }, + { + "operator": "keystone-asset-inotel" + }, + { + "operator": "keystone-asset-linkPool" + }, + { + "operator": "keystone-asset-linkRiver" + }, + { + "operator": "keystone-asset-pierTwo" + }, + { + "operator": "keystone-asset-simplyVC" + }, + { + "operator": "keystone-asset-chainlink" + }, + { + "operator": "keystone-asset-galaxy" + }, + { + "operator": "keystone-asset-northWestNodes" + }, + { + "operator": "keystone-asset-validationCloud" + }, + { + "operator": "keystone-asset-syncnode" + }, + { + "operator": "keystone-asset-matrixedLink" + }, + { + "operator": "keystone-asset-easy2Stake" + }, + { + "operator": "keystone-asset-linkForest" + } + ] + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xA674a0fD742F37BD5077AFc90D1E82485c91989C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eurc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "EURC / USD", + "pair": [ + "", + "" + ], + "path": "eurc-usd", + "proxyAddress": "0x04F84020Fdf10d9ee64D1dcC2986EDF2F556DA11", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Circle EUR", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "EURC", + "baseAssetClic": "EURC_CR", + "blockchainName": "Ethereum", + "clicProductName": "EURC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA81C8267F4EDc906D77BF1EC29460967bFF27798", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lvlusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "lvlUSD / USD", + "pair": [ + "", + "" + ], + "path": "lvlusd-usd", + "proxyAddress": "0xe5181aA707feD57781e764437f021b633B34659E", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Level USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "lvlUSD", + "baseAssetClic": "lvlUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "lvlUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xA9845307Bb5F5637B136Ca70914746d1bb7d402a", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "bnb-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BNB / USD", + "pair": [ + "", + "" + ], + "path": "bnb-usd", + "proxyAddress": "0x14e613AC84a31f709eadbdF89C6CC390fDc9540A", + "threshold": 1, + "valuePrefix": "", + "assetName": "BNB", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BNB", + "baseAssetClic": "BNB_CR", + "blockchainName": "Ethereum", + "clicProductName": "BNB/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xAbab7646c0535dF1BeC82D4257c4E1f8df79c625", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "arbitrum-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Arbitrum Healthcheck", + "pair": [ + "", + "" + ], + "path": "arbitrum-hc", + "proxyAddress": "0x32EaFC72772821936BCc9b8A32dC394fEFcDBfD9", + "threshold": 1, + "valuePrefix": "", + "assetName": "Arbitrum Health Sequencer Flag", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Health Check", + "productType": "Blockchain", + "productTypeCode": "Health" + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0xAfDA097A70d1AF8D93874Dd8cD55b7E082b5ee57", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "xsolvbtc-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "xSolvBTC NAV", + "pair": [ + "", + "" + ], + "path": "xsolvbtc-nav", + "proxyAddress": "0x46cE854814ea38A4857AeA23aE7759b3A7970e4a", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Crypto", + "baseAsset": "xSolvBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Solv", + "porAuditor": "Solv", + "porSource": "Asset Issuer", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xB30Aae40B630500D5c8140B7d1E5Bb1d61C86B64", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "stbtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "stBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "stbtc-btc-exchange-rate", + "proxyAddress": "0xD93571A6201978976e37c4A0F7bE17806f2Feab2", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "stBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "stBTC", + "baseAssetClic": "stBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "stBTC/BTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xB38d1D12Ba17aA62255e588a0bC845c1a589A50d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "xag-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "XAG / USD", + "pair": [ + "", + "" + ], + "path": "xag-usd", + "proxyAddress": "0x379589227b15F1a12195D3f2d90bBc9F31f95235", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "Silver", + "feedCategory": "low", + "feedType": "Commodities", + "docs": { + "assetClass": "Commodity", + "assetSubClass": "Spot", + "baseAsset": "XAG", + "baseAssetClic": "XAG_CO", + "blockchainName": "Ethereum", + "clicProductName": "XAG/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Precious_Metals", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xB7fd4e173Fc15D4148f13789Cc9aF9cE9b65aE76", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "base-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Base Healthcheck", + "pair": [ + "", + "" + ], + "path": "base-hc", + "proxyAddress": "0x48D9DA600EC48DDd6ce7FC1D47D683818e511c81", + "threshold": 0.1, + "valuePrefix": "", + "assetName": "", + "feedCategory": "custom", + "feedType": "", + "docs": { + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true, + "productSubType": "Health Check", + "productType": "Blockchain", + "productTypeCode": "Health" + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0xB996D9f788D1ff0516c033794F438f10d6D7190d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "try-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TRY / USD", + "pair": [ + "", + "" + ], + "path": "try-usd", + "proxyAddress": "0xB09fC5fD3f11Cf9eb5E1C5Dba43114e3C9f477b5", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Turkish Lira", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "TRY", + "baseAssetClic": "TRY_FX", + "blockchainName": "Ethereum", + "clicProductName": "TRY/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xBae95c3247AA52738C52d2Df94ac6932b6b1907F", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "idr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "IDR / USD", + "pair": [ + "", + "" + ], + "path": "idr-usd", + "proxyAddress": "0x91b99C9b75aF469a71eE1AB528e8da994A5D7030", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Indonesian Rupiah", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "IDR", + "baseAssetClic": "IDR_FX", + "blockchainName": "Ethereum", + "clicProductName": "IDR/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Forex_IDR", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC1C24f0f2103F5899b7AB415A1930E519B7D3423", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ustbl-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "1000000", + "name": "USTBL NAV", + "pair": [ + "", + "" + ], + "path": "ustbl-nav", + "proxyAddress": "0x477e363c51Ab0C4D13B22CD6B57D56d4a3Cb7Abe", + "threshold": 1e-7, + "valuePrefix": "$", + "assetName": "Spiko US T-Bills Money Market Fund (USTBL)", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Money Market Fund", + "baseAsset": "USTBL", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Spiko", + "porAuditor": "Caceis", + "porSource": "Fund Administrator", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0xC1e7D47ECfbb15B99a4B5F69E6931587000DD0b0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "matic-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MATIC / USD", + "pair": [ + "", + "" + ], + "path": "matic-usd", + "proxyAddress": "0x7bAC85A8a13A4BcD8abb3eB7d6b4d632c5a57676", + "threshold": 1, + "valuePrefix": "", + "assetName": "Polygon (MATIC)", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MATIC", + "baseAssetClic": "MATIC_CR", + "blockchainName": "Ethereum", + "clicProductName": "MATIC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC27E191714b429C51e18FAfba6A4C31135B2e157", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cvx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CVX / USD", + "pair": [ + "", + "" + ], + "path": "cvx-usd", + "proxyAddress": "0xd962fC30A72A84cE50161031391756Bf2876Af5D", + "threshold": 2, + "valuePrefix": "", + "assetName": "Convex Finance", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CVX", + "baseAssetClic": "CVX_CR", + "blockchainName": "Ethereum", + "clicProductName": "CVX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC30f3447015278BfB50457EE0a94CD88f4db1792", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wtgxx-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "100000000", + "name": "WTGXX NAV", + "pair": [ + "", + "" + ], + "path": "wtgxx-nav", + "proxyAddress": "0x1DE472E766E87eB993d0C7904367014a913E55ee", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xC499ec76e2F5ac15e127A352Bc40cF24FC472401", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ethx-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "ETHx / ETH", + "pair": [ + "", + "" + ], + "path": "ethx-eth", + "proxyAddress": "0xC5f8c4aB091Be1A899214c0C3636ca33DcA0C547", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Stader ETHx", + "feedCategory": "hidden", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "ETHx", + "blockchainName": "Ethereum", + "clicProductName": "ETHx/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xC9c8Efa84eaB332d1950e5Ba0a913b090775825c", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "steth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "STETH / ETH", + "pair": [ + "", + "" + ], + "path": "steth-eth", + "proxyAddress": "0x86392dC19c0b719886221c78AB11eb8Cf5c52812", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Lido Staked ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "STETH", + "baseAssetClic": "STETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "STETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xD00a14A8d25692f7F2565a2fe3b98b468B91324D", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "QQQon / USD", + "pair": [ + "", + "" + ], + "path": "qqqon-usd-shared-svr", + "proxyAddress": "0xE5DF423251c67D85B2D70787Af76069d96BC4D4C", + "secondaryProxyAddress": "0xE6417a3B82438f783DC8fd2B1cB6B0808585030B", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Invesco QQQ (Ondo Tokenized ETF)", + "feedCategory": "custom", + "feedType": "Equities", + "docs": { + "assetClass": "Equities", + "baseAsset": "QQQon", + "baseAssetClic": "QQQon_CR", + "blockchainName": "Ethereum", + "clicProductName": "QQQon/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "US", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xD03f0FAeCB11cD49DE7A2397960E30F3BeA17E07", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cad-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CAD / USD", + "pair": [ + "", + "" + ], + "path": "cad-usd", + "proxyAddress": "0xa34317DB73e77d453b1B8d04550c44D10e981C8e", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Canadian Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "CAD", + "baseAssetClic": "CAD_FX", + "blockchainName": "Ethereum", + "clicProductName": "CAD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xD0f0efAfB63ce1e46ae1aF84BCFE2A2A175E6797", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "solvbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SolvBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "solvbtc-por", + "proxyAddress": "0xda9258AFc797Cd64d1b6FC651051224cdAB1B25E", + "threshold": 2, + "valuePrefix": "", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SolvBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Solv Protocol", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xD37190eC18fEfE85F4a0fCdEb8Bc220A47093457", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wsteth-usd-calculated", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "wstETH / USD Calculated", + "pair": [ + "", + "" + ], + "path": "wsteth-usd-calculated", + "proxyAddress": "0x164b276057258d81941e97B0a900D4C7B358bCe0", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xD7496378523f90f1e82dA528F385B2B30120afE2", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdg-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDG / USD", + "pair": [ + "", + "" + ], + "path": "usdg-usd", + "proxyAddress": "0x14f0737d6b705259e521EA6E9E3506AC78dBd311", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "Global Dollar", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDG", + "baseAssetClic": "USDG_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDG/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xDAE05e337C56CD1b988Fd7a6B74e8BbD3028C4C6", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TBTC / USD", + "pair": [ + "", + "" + ], + "path": "tbtc-usd", + "proxyAddress": "0x8350b7De6a6a2C1368E7D4Bd968190e13E354297", + "threshold": 2, + "valuePrefix": "", + "assetName": "tBTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "tBTC", + "baseAssetClic": "tBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "tBTC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xE5490FcdFe66b1680f2b4c09f81149f0C285a2E3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "swell-eth-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "Swell ETH Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "swell-eth-por", + "proxyAddress": "0x60cbE8D88EF519cF3C62414D76f50818D211fea1", + "threshold": 2, + "valuePrefix": "", + "valueSuffix": "ETH", + "assetName": "Staked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "swETH", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Swell Network", + "marketHours": "Crypto", + "porAuditor": "Beacon Chain / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xE6c7AE04e83aa7e491988cAeecf5BD6a240A0d14", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ib01-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "IB01 / USD", + "pair": [ + "", + "" + ], + "path": "ib01-usd", + "proxyAddress": "0x32d1463EB53b73C095625719Afa544D5426354cB", + "threshold": 2, + "valuePrefix": "", + "assetName": "iShares Treasury Bond 0-1yr UCITS ETF", + "feedCategory": "low", + "feedType": "Equities", + "docs": { + "assetClass": "ETF", + "assetSubClass": "UK", + "baseAsset": "IB01", + "baseAssetClic": "IB01_EQ", + "blockchainName": "Ethereum", + "clicProductName": "IB01/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "LSE", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xE83E0706933a1E25C40D6A6A7Bb758f6A2120FE0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SPYon / USD", + "pair": [ + "", + "" + ], + "path": "spyon-usd-shared-svr", + "proxyAddress": "0x6EcC1b902dB35eAFE95332443802774Fd1D72576", + "secondaryProxyAddress": "0xc9c10271B2B76767C385Ac389C05d77c319DC41C", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "SPDR S&P 500 ETF (Ondo Tokenized ETF)", + "feedCategory": "custom", + "feedType": "Equities", + "docs": { + "assetClass": "Equities", + "baseAsset": "SPYon", + "baseAssetClic": "SPYon_CR", + "blockchainName": "Ethereum", + "clicProductName": "SPYon/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "US", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xE95FEbF9b8623b1b3B79BF995491197A8b67D2A7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "unibtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "uniBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "unibtc-btc-exchange-rate", + "proxyAddress": "0x861d15F8a4059cb918bD6F3670adAEB1220B298f", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "uniBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "uniBTC", + "baseAssetClic": "uniBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "uniBTC/BTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xEA530C83AFa51A66f80935c78aB9BB574d7DdfCb", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "nexus-weth-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "Nexus wETH Reserves", + "pair": [ + "", + "" + ], + "path": "nexus-weth-por", + "proxyAddress": "0xCc72039A141c6e34a779eF93AEF5eB4C82A893c7", + "threshold": 0.3, + "valuePrefix": "", + "valueSuffix": "ETH", + "assetName": "wETH token", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "NXMTY", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Nexus Mutual", + "marketHours": "Crypto", + "porAuditor": "Enzyme", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "ETH", + "reserveAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xEC6292c0fDF55d9f1523bA80EBD7465e0c9d04ce", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fbtc-btc-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "FBTC / BTC Exchange Rate", + "pair": [ + "", + "" + ], + "path": "fbtc-btc-exchange-rate", + "proxyAddress": "0xe5346a4Fd329768A99455d969724768a00CA63FB", + "threshold": 0.01, + "valuePrefix": "", + "assetName": "FBTC / BTC Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "FBTC", + "baseAssetClic": "FBTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "FBTC/BTC-ExRate-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xEa503957019A61DB0C7cDeb8d05966Fe6095F9d8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "m-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 93600, + "history": null, + "multiply": "100000000", + "name": "M NAV", + "pair": [ + "", + "" + ], + "path": "m-nav", + "proxyAddress": "0xC28198Df9aee1c4990994B35ff51eFA4C769e534", + "threshold": 1e-7, + "valuePrefix": "$", + "assetName": "M", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Stablecoin", + "baseAsset": "MN", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "M^0 Protocol", + "porAuditor": "M^0 Labs", + "porSource": "M^0 Labs", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xEe870cD3035e1cCF8fcfBb865d85e1C364E29146", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ohmv2-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "OHMv2 / ETH", + "pair": [ + "", + "" + ], + "path": "ohmv2-eth", + "proxyAddress": "0x9a72298ae3886221820B1c878d12D872087D3a23", + "threshold": 2, + "valuePrefix": "", + "assetName": "Olympus v2", + "feedCategory": "", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "OHMV2", + "baseAssetClic": "OHMV2_CR", + "blockchainName": "Ethereum", + "clicProductName": "OHMV2/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xF4068d9B0cd6507aA8E61763B02a0452e5E63b22", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "celo-healthcheck", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1", + "name": "Celo Healthcheck", + "pair": [ + "", + "" + ], + "path": "celo-hc", + "proxyAddress": "0x7Fa89217C9bA5eb1307Aca6B84E99ed9220e076F", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 0 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0xF4cF94EB58b2a6eFd05A39dbdc5B02Cf33A509D8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ath-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ATH / USD", + "pair": [ + "", + "" + ], + "path": "ath-usd", + "proxyAddress": "0xd95044Eb392CdE502b1F903Fc978317462049E52", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Aethir", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Crypto", + "baseAsset": "ATH", + "baseAssetClic": "ATH_CR", + "blockchainName": "Ethereum", + "clicProductName": "ATH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xF69C2CdFa50C970235d059DfeEE767b27E02F260", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pce-price-index-percent-change-annual-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3024000, + "history": null, + "multiply": "10", + "name": "PCE Price Index — Percent Change (Annual Rate)", + "pair": [ + "", + "" + ], + "path": "pce-price-index-percentage", + "proxyAddress": "0x64c4c1BF5ec145CB6095A289249592B5bb007098", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "%", + "assetName": "", + "feedCategory": "custom", + "feedType": "Macroeconomics", + "docs": { + "assetClass": "Macroeconomics", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "productSubType": "Reference", + "productType": "Macroeconomics", + "productTypeCode": "RefMacro" + }, + "decimals": 1 + }, + { + "compareOffchain": "", + "contractAddress": "0xF816091bA795C1b55859599fcDa8f786B2816e01", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usd0-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USD0++ / USD", + "pair": [ + "", + "" + ], + "path": "usd0++-usd", + "proxyAddress": "0xFC9e30Cf89f8A00dba3D34edf8b65BCDAdeCC1cB", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Staked USD0", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "USD0++", + "baseAssetClic": "USD0++_CR", + "blockchainName": "Ethereum", + "clicProductName": "USD0++/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xFe5AFc4225E2626EB40Ca11A59962eBEEeb09E76", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "stg-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "STG / USD", + "pair": [ + "", + "" + ], + "path": "stg-usd", + "proxyAddress": "0x7A9f34a0Aa917D438e9b6E630067062B7F8f6f3d", + "threshold": 5, + "valuePrefix": "", + "assetName": "Stargate Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "STG", + "baseAssetClic": "STG_CR", + "blockchainName": "Ethereum", + "clicProductName": "STG/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xFfF8FdC3C2B041C783D90dFeFDDd842B15A98712", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ren-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "REN / ETH", + "pair": [ + "", + "" + ], + "path": "ren-eth", + "proxyAddress": "0x3147D7203354Dc06D9fd350c7a2437bcA92387a4", + "threshold": 2, + "valuePrefix": "", + "assetName": "Ren", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "REN", + "baseAssetClic": "REN_CR", + "blockchainName": "Ethereum", + "clicProductName": "REN/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xa3884fd01b3f9FBCDA0B4268DAa332aFE6Edac20", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ibta-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "IBTA / USD", + "pair": [ + "", + "" + ], + "path": "ibta-usd", + "proxyAddress": "0xd27e6D02b72eB6FCe04Ad5690C419196B4EF2885", + "threshold": 2, + "valuePrefix": "", + "assetName": "iShares Treasury Bond 1-3yr UCITS ETF", + "feedCategory": "low", + "feedType": "Equities", + "docs": { + "assetClass": "ETF", + "assetSubClass": "UK", + "baseAsset": "IBTA", + "baseAssetClic": "IBTA_EQ", + "blockchainName": "Ethereum", + "clicProductName": "IBTA/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "LSE", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xa685F0Bb86044e9c6A182A3689bBF8A98eB5764C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "swell-restaked-eth-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "Swell Restaked ETH Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "swell-restaked-eth-por", + "proxyAddress": "0x0c89c488e763AC2d69cB058CCAC7A8B283EE3DbA", + "threshold": 0.5, + "valuePrefix": "", + "valueSuffix": "ETH", + "assetName": "Restaked ETH", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "rswETH", + "baseAssetClic": "rswETH_CR", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Swell Network", + "marketHours": "Crypto", + "porAuditor": "Beacon Chain / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xa7Daf8A03B064262FfF0D615663553DAe3E18744", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fast-gas-gwei", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 7200, + "history": null, + "multiply": "1", + "name": "Fast Gas / Gwei", + "pair": [ + "", + "" + ], + "path": "fast-gas-gwei", + "proxyAddress": "0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C", + "threshold": 25, + "valuePrefix": "", + "assetName": "Fast Gas", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Gas", + "productType": "Blockchain", + "productTypeCode": "Gas" + }, + "decimals": 0 + }, + { + "compareOffchain": "", + "contractAddress": "0xa88757c4D7f75C672a07Ae1Cf8011C4552a275f0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SOL / USD", + "pair": [ + "", + "" + ], + "path": "sol-usd", + "proxyAddress": "0x4ffC43a60e009B551865A93d232E33Fce9f01507", + "threshold": 2, + "valuePrefix": "", + "assetName": "Solana", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SOL", + "baseAssetClic": "SOL_CR", + "blockchainName": "Ethereum", + "clicProductName": "SOL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xad88fc1A810379Ef4EFbF2D97EdE57e306178e5a", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "ETH / USD", + "pair": [ + "", + "" + ], + "path": "eth-usd-shared-svr", + "proxyAddress": "0xd82562bb17557231Cd871e1B2525F3AB8d63D409", + "secondaryProxyAddress": "0xc0053f3FBcCD593758258334Dfce24C2A9A673aD", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "ETH/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xb0Fd105DAD6b9B07f36D5F8496712a36114279ad", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "btc-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "BTC / ETH", + "pair": [ + "", + "" + ], + "path": "btc-eth", + "proxyAddress": "0xdeb288F737066589598e9214E782fa5A8eD689e8", + "threshold": 2, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "baseAssetClic": "BTC_CR", + "blockchainName": "Ethereum", + "clicProductName": "BTC/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xb3478aC41a7acD9a33eb15D7A764b7119e571A3C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "crv-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "CRV / ETH", + "pair": [ + "", + "" + ], + "path": "crv-eth", + "proxyAddress": "0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e", + "threshold": 2, + "valuePrefix": "", + "assetName": "Curve DAO", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CRV", + "baseAssetClic": "CRV_CR", + "blockchainName": "Ethereum", + "clicProductName": "CRV/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xb49dBd447D2C3ae00B205200Fe629cA73E3E80e3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "hbtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 259200, + "history": null, + "multiply": "1000000000000000000", + "name": "HBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "hbtc-por", + "proxyAddress": "0x0A8cD0115B1EE87EbA5b8E06A9a15ED93e230f7a", + "threshold": 1e-7, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "BTC", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "HBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Huobi", + "marketHours": "Crypto", + "porAuditor": "Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xb611401574061947aBAc7d2406711F115BE22A6e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdp-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDP / USD", + "pair": [ + "", + "" + ], + "path": "usdp-usd", + "proxyAddress": "0x09023c0DA49Aaf8fc3fA3ADF34C6A7016D38D5e3", + "threshold": 1, + "valuePrefix": "", + "assetName": "Pax Dollar", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDP", + "baseAssetClic": "USDP_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDP/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xbBaf2F253Dec10c17eF9531bc8Cd7A7C708A10Bc", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "unibtc-por", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "uniBTC Proof of Reserves", + "pair": [ + "", + "" + ], + "path": "unibtc-por", + "proxyAddress": "0xc590D9fb8eE78a0909dFF341ccf717000b7b7fF2", + "threshold": 2, + "valuePrefix": "", + "valueSuffix": "BTC", + "assetName": "Bitcoin (BTC)", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "uniBTC", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Bedrock", + "marketHours": "Crypto", + "porAuditor": "Bitcoin Network / Cross-chain", + "porSource": "Wallet Address Manager", + "porType": "Cross-chain", + "productSubType": "Cross-chain", + "productType": "Proof of Reserve", + "productTypeCode": "PoR", + "reserveAsset": "BTC", + "reserveAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xbCD99Bc4C5Bee667939bf7E9B3367d0A0Fa096a0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "nzd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "NZD / USD", + "pair": [ + "", + "" + ], + "path": "nzd-usd", + "proxyAddress": "0x3977CFc9e4f29C184D4675f4EB8e0013236e5f3e", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "New Zealand Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "NZD", + "baseAssetClic": "NZD_FX", + "blockchainName": "Ethereum", + "clicProductName": "NZD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc0bc2B4DB974586f481C2a13549a4C61F350f8E4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ceth-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "CETH Reserves", + "pair": [ + "", + "" + ], + "path": "ceth-por", + "proxyAddress": "0xa7d76167900493Acf2650Dc001fb2Bc5256579B0", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "21Shares Core Ethereum ETF", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "ETF", + "assetSubClass": "US", + "baseAsset": "21Shares_Core_Ethereum_ETF", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "hidden": true, + "porAuditor": "Cross-chain / Ethereum Network", + "porSource": "Custodian API", + "porType": "Cross-chain", + "productSubType": "Cross-chain / Ethereum Network", + "productType": "Proof of Reserve", + "productTypeCode": "PoR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xc1c54D09554Cf65d74a289805c2731cf6EA57373", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "fxs-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "FXS / USD", + "pair": [ + "", + "" + ], + "path": "fxs-usd", + "proxyAddress": "0x6Ebc52C8C1089be9eB3945C4350B68B8E4C2233f", + "threshold": 2, + "valuePrefix": "", + "assetName": "Frax Share", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "FXS", + "baseAssetClic": "FXS_CR", + "blockchainName": "Ethereum", + "clicProductName": "FXS/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc240796f93C5659708C5d14D90563e297314C532", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "imx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "IMX / USD", + "pair": [ + "", + "" + ], + "path": "imx-usd", + "proxyAddress": "0xBAEbEFc1D023c0feCcc047Bff42E75F15Ff213E6", + "threshold": 2, + "valuePrefix": "", + "assetName": "Immutable X", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "IMX", + "baseAssetClic": "IMX_CR", + "blockchainName": "Ethereum", + "clicProductName": "IMX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc4f25Fed1c2C5973947d5C90f7C9a32353ceEb22", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "frax-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "FRAX / ETH", + "pair": [ + "", + "" + ], + "path": "frax-eth", + "proxyAddress": "0x14d04Fff8D21bd62987a5cE9ce543d2F1edF5D3E", + "threshold": 2, + "valuePrefix": "", + "assetName": "FRAX", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "FRAX", + "baseAssetClic": "FRAX_CR", + "blockchainName": "Ethereum", + "clicProductName": "FRAX/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xc778E9686F0fde6Fe4D7d8fE4B481463Fce898fD", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "snx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SNX / USD", + "pair": [ + "", + "" + ], + "path": "snx-usd", + "proxyAddress": "0xDC3EA94CD0AC27d9A86C180091e7f78C683d3699", + "threshold": 1, + "valuePrefix": "", + "assetName": "Synthetix Network", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SNX", + "baseAssetClic": "SNX_CR", + "blockchainName": "Ethereum", + "clicProductName": "SNX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc77904CD2CA0806CC3DB0819E9630FF3e2f6093d", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "reth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "RETH / ETH", + "pair": [ + "", + "" + ], + "path": "reth-eth", + "proxyAddress": "0x536218f9E9Eb48863970252233c8F271f554C2d0", + "threshold": 2, + "valuePrefix": "", + "assetName": "Rocket Pool ETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "RETH", + "baseAssetClic": "RETH_CR", + "blockchainName": "Ethereum", + "clicProductName": "RETH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xc9E1a09622afdB659913fefE800fEaE5DBbFe9d7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 82800, + "history": null, + "multiply": "100000000", + "name": "USDC / USD", + "pair": [ + "", + "" + ], + "path": "usdc-usd", + "proxyAddress": "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "Circle USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDC", + "baseAssetClic": "USDC_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xcC00DfdEaA0c96606b37EC6C83BaE9FD1f6cFb3E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ape-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "APE / ETH", + "pair": [ + "", + "" + ], + "path": "ape-eth", + "proxyAddress": "0xc7de7f4d4C9c991fF62a07D18b3E31e349833A18", + "threshold": 2, + "valuePrefix": "", + "assetName": "APECoin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "APE", + "baseAssetClic": "APE_CR", + "blockchainName": "Ethereum", + "clicProductName": "APE/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xcC16f670129f965b396f2e81312F6e339FFDB18e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usde-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 82800, + "history": null, + "multiply": "100000000", + "name": "USDe / USD", + "pair": [ + "", + "" + ], + "path": "usde-usd", + "proxyAddress": "0xa569d910839Ae8865Da8F8e70FfFb0cBA869F961", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethena USDe", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDE", + "baseAssetClic": "USDE_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDE/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xcC1843B09Ba15b829095Cbca8D7aB460d669236a", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ampl-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "AMPL / ETH", + "pair": [ + "", + "" + ], + "path": "ampl-eth", + "proxyAddress": "0x492575FDD11a0fCf2C6C719867890a7648d526eB", + "threshold": 2, + "valuePrefix": "", + "assetName": "Ampleforth", + "feedCategory": "hidden", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AMPL", + "baseAssetClic": "AMPL_CR", + "blockchainName": "Ethereum", + "clicProductName": "AMPL/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "hidden": true, + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xcC96Df6653b23cd20F19c7f60ccBcB974b0a6FF4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "shib-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SHIB / ETH", + "pair": [ + "", + "" + ], + "path": "shib-eth", + "proxyAddress": "0x8dD1CD88F43aF196ae478e91b9F5E4Ac69A97C61", + "threshold": 2, + "valuePrefix": "", + "assetName": "Shiba Inu", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SHIB", + "baseAssetClic": "SHIB_CR", + "blockchainName": "Ethereum", + "clicProductName": "SHIB/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xcD2d64424aBE57AB8c70d9f9253d0C6DffeBB2E7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ousdt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "OUSDT / USD", + "pair": [ + "", + "" + ], + "path": "ousdt-usd", + "proxyAddress": "0xE3fd61Cd8935EAE81e1c31AF36D7134e411490Cd", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "OpenUSDT", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "OUSDT", + "baseAssetClic": "OUSDT_CR", + "blockchainName": "Ethereum", + "clicProductName": "OUSDT/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xcd07B31D85756098334eDdC92DE755dEae8FE62f", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "AAVE / USD", + "pair": [ + "", + "" + ], + "path": "aave-usd-svr", + "proxyAddress": "0xbd7F896e60B650C01caf2d7279a1148189A68884", + "secondaryProxyAddress": "0xF02C1e2A3B77c1cacC72f72B44f7d0a4c62e4a85", + "threshold": 1, + "valuePrefix": "", + "assetName": "Aave", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AAVE", + "baseAssetClic": "AAVE_CR", + "blockchainName": "Ethereum", + "clicProductName": "AAVE/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xcd2D4e80aA0E93d4e788f037A79ab597E0857917", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "cusd-aum", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "cUSD AUM", + "pair": [ + "", + "" + ], + "path": "cusd-aum", + "proxyAddress": "0x16caE6d6ffb4AE01e206b928de925Ac0C8C8116A", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Cap USD", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Stablecoin", + "baseAsset": "cUSD", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Cap", + "porAuditor": "Wallet Address Manager", + "porSource": "Cap", + "productType": "SmartData", + "productTypeCode": "SmartAUM" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xced238b8B9D39f2B1CD42adbEeFBB85cd46C14F2", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "gousd-reserves", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "goUSD Reserves", + "pair": [ + "", + "" + ], + "path": "gousd-reserves", + "proxyAddress": "0x269f871c80b50a5cF34cDfCfEC11460adA4D66f1", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xd22697ca59B59D21C2B60F9668d3b58d816B3724", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "secured-overnight-financing-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "Secured Overnight Financing Rate", + "pair": [ + "", + "" + ], + "path": "sofr-rate", + "proxyAddress": "0xBc8f5e8B47D69fa10A4B64eC5B45b466f81B77CA", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true, + "marketHours": "NYSE" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xd5090674b4653240cd94eE886484ca808c6E6694", + "contractType": "", + "contractVersion": 4, + "decimalPlaces": 3, + "ens": "ampl-usd", + "formatDecimalPlaces": 0, + "healthPrice": "", + "heartbeat": 172800, + "history": false, + "multiply": "1000000000000000000", + "name": "AMPL / USD", + "pair": [ + "AMPL", + "USD" + ], + "path": "ampl-usd", + "proxyAddress": "0xe20CA8D7546932360e37E9D72c1a47334af57706", + "threshold": 1000, + "valuePrefix": "$", + "assetName": "Ampleforth", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AMPL", + "baseAssetClic": "AMPL_CR", + "blockchainName": "Ethereum", + "clicProductName": "AMPL/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xd5BC4e3c7e77A5776fD9D0DDe8471B8B4aEc10f5", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ustb-nav-per-share", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 95400, + "history": null, + "multiply": "1000000", + "name": "USTB NAV per Share", + "pair": [ + "", + "" + ], + "path": "ustb-nav", + "proxyAddress": "0x289B5036cd942e619E1Ee48670F98d214E745AAC", + "threshold": 0.0001, + "valuePrefix": "$", + "assetName": "Superstate Short Duration US Government Securities Fund (USTB)", + "feedCategory": "custom", + "feedType": "Fixed Income", + "docs": { + "assetClass": "Tokenized Treasury Fund", + "baseAsset": "USTB", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Superstate", + "marketHours": "NYSE", + "porAuditor": "Superstate", + "porSource": "Asset Manager API", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0xd8B9aA6E811c935eF63e877CFA7Be276931293DA", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "aave-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "AAVE / USD", + "pair": [ + "", + "" + ], + "path": "aave-usd", + "proxyAddress": "0x547a514d5e3769680Ce22B2361c10Ea13619e8a9", + "threshold": 1, + "valuePrefix": "", + "assetName": "Aave", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "AAVE", + "baseAssetClic": "AAVE_CR", + "blockchainName": "Ethereum", + "clicProductName": "AAVE/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xdA0DA298550E8E449b935CEA865c8100F3cA1b73", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "crv-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CRV / USD", + "pair": [ + "", + "" + ], + "path": "crv-usd", + "proxyAddress": "0xCd627aA160A6fA45Eb793D19Ef54f5062F20f33f", + "threshold": 1, + "valuePrefix": "", + "assetName": "Curve DAO", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "CRV", + "baseAssetClic": "CRV_CR", + "blockchainName": "Ethereum", + "clicProductName": "CRV/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xdEf8C51d7c1040637A198efFc39613865B32EA51", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "uni-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "UNI / USD", + "pair": [ + "", + "" + ], + "path": "uni-usd", + "proxyAddress": "0x553303d460EE0afB37EdFf9bE42922D8FF63220e", + "threshold": 1, + "valuePrefix": "", + "assetName": "Uniswap", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "UNI", + "blockchainName": "Ethereum", + "clicProductName": "UNI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xdaA1c6511Aa051e9e83Dd7Ac2D65d5E41D1f6b98", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eutbl-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "1000000", + "name": "EUTBL NAV", + "pair": [ + "", + "" + ], + "path": "eutbl-nav", + "proxyAddress": "0xfD628af590c4150A9651C1f4ddD0b4f532B703ae", + "threshold": 1e-7, + "valuePrefix": "€", + "assetName": "Spiko EU T-Bills Money Market Fund (EUTBL)", + "feedCategory": "custom", + "feedType": "", + "docs": { + "assetClass": "Money Market Fund", + "baseAsset": "EUTBL", + "blockchainName": "Ethereum", + "deliveryChannelCode": "DF", + "issuer": "Spiko", + "porAuditor": "Caceis", + "porSource": "Fund Administrator", + "productType": "NAVLink", + "productTypeCode": "NAV" + }, + "decimals": 6 + }, + { + "compareOffchain": "", + "contractAddress": "0xdc715c751f1cc129A6b47fEDC87D9918a4580502", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "BTC / USD", + "pair": [ + "", + "" + ], + "path": "btc-usd-svr", + "proxyAddress": "0x85355da30ee4b35F4B30759Bd49a1EBE3fc41Bdb", + "secondaryProxyAddress": "0xb41E773f507F7a7EA890b1afB7d2b660c30C8B0A", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "blockchainName": "Ethereum", + "clicProductName": "BTC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xe07f52971153dB2713ACe5ebAAf2eA8b0A9230B7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "susde-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "sUSDe / USD", + "pair": [ + "", + "" + ], + "path": "susde-usd", + "proxyAddress": "0xFF3BC18cCBd5999CE63E788A1c250a88626aD099", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethena Staked USDe", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "SUSDE", + "baseAssetClic": "SUSDE_CR", + "blockchainName": "Ethereum", + "clicProductName": "SUSDE/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xe13fafe4FB769e0f4a1cB69D35D21EF99188EFf7", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": null, + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDC / USD", + "pair": [ + "", + "" + ], + "path": "usdc-usd-svr", + "proxyAddress": "0xfB6471ACD42c91FF265344Ff73E88353521d099F", + "secondaryProxyAddress": "0xEa674bBC33AE708Bc9EB4ba348b04E4eB55b496b", + "threshold": 0.25, + "valuePrefix": "", + "assetName": "Circle USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDC", + "baseAssetClic": "USDC_CR", + "blockchainName": "Ethereum", + "clicProductName": "USDC/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xe88C679E2D42963acDC76810d21daC2e6a8D7c29", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "zrx-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ZRX / USD", + "pair": [ + "", + "" + ], + "path": "zrx-usd", + "proxyAddress": "0x2885d15b8Af22648b98B122b22FDF4D2a56c6023", + "threshold": 1, + "valuePrefix": "", + "assetName": "0x", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ZRX", + "blockchainName": "Ethereum", + "clicProductName": "ZRX/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xe9a6BCCdE4875F8c1228975F9c84598558a75AC8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "mkr-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "100000000", + "name": "MKR / USD", + "pair": [ + "", + "" + ], + "path": "mkr-usd", + "proxyAddress": "0xec1D1B3b0443256cc3860e24a46F108e699484Aa", + "threshold": 1, + "valuePrefix": "", + "assetName": "Maker", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MKR", + "blockchainName": "Ethereum", + "clicProductName": "MKR/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0xe9cf7cF5827e45407448B50cDC0aed5C798037A4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wlfi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WLFI / USD", + "pair": [ + "", + "" + ], + "path": "wlfi-usd", + "proxyAddress": "0x14E5FC91Ddb3f97C33013Cc9fA74F54062Ad1Aa1", + "threshold": 2, + "valuePrefix": "", + "assetName": "World Liberty Financial", + "feedCategory": "new", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "WLFI", + "blockchainName": "Ethereum", + "clicProductName": "WLFI/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xf17CB308606999DF25F5d4B9f74bD9fe47A5b3b3", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tbill-nav", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 97200, + "history": null, + "multiply": "100000000", + "name": "TBILL NAV", + "pair": [ + "", + "" + ], + "path": "tbill-nav", + "proxyAddress": "0xAbE7a3643615Ed32d3431e11E0Ee5A486Cb27d48", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "", + "feedCategory": "", + "feedType": "", + "docs": { + "hidden": true + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xf3A0a2363Ee3e5FC1CcF923F4eA9c06BaC1A6834", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "crvusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "CRVUSD / USD", + "pair": [ + "", + "" + ], + "path": "crvusd-usd", + "proxyAddress": "0xEEf0C605546958c1f899b6fB336C20671f9cD49F", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "crvUSD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "CRVUSD", + "baseAssetClic": "CRVUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "CRVUSD/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xfD69366dD8F8aaE18C8344F66Cc841782e73b2F0", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "meth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "mETH / ETH", + "pair": [ + "", + "" + ], + "path": "meth-eth", + "proxyAddress": "0x5b563107C8666d2142C216114228443B94152362", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Mantle Staked Ether", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "METH", + "baseAssetClic": "METH_CR", + "blockchainName": "Ethereum", + "clicProductName": "METH/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xfadcAf88F39649F2Bf51c49e93A2DE1f39C51318", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "arb-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ARB / USD", + "pair": [ + "", + "" + ], + "path": "arb-usd", + "proxyAddress": "0x31697852a68433DbCc2Ff612c516d69E3D9bd08F", + "threshold": 2, + "valuePrefix": "", + "assetName": "Arbitrum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ARB", + "baseAssetClic": "ARB_CR", + "blockchainName": "Ethereum", + "clicProductName": "ARB/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xfc7b00A255f24C979BA96135e11B58bD6F693Ec4", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ldo-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "LDO / ETH", + "pair": [ + "", + "" + ], + "path": "ldo-eth", + "proxyAddress": "0x4e844125952D32AcdF339BE976c98E22F6F318dB", + "threshold": 2, + "valuePrefix": "", + "assetName": "Lido DAO", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LDO", + "baseAssetClic": "LDO_CR", + "blockchainName": "Ethereum", + "clicProductName": "LDO/ETH-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR" + }, + "decimals": 18 + }, + { + "compareOffchain": "", + "contractAddress": "0xfed25Dff478d14b32cb983100cc15d44BFa54247", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sgd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SGD / USD", + "pair": [ + "", + "" + ], + "path": "sgd-usd", + "proxyAddress": "0xe25277fF4bbF9081C75Ab0EB13B4A13a721f3E13", + "threshold": 0.15, + "valuePrefix": "", + "assetName": "Singapore Dollar", + "feedCategory": "low", + "feedType": "Forex", + "docs": { + "assetClass": "Fiat", + "baseAsset": "SGD", + "baseAssetClic": "SGD_FX", + "blockchainName": "Ethereum", + "clicProductName": "SGD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Forex", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xff221Bf2E61B62182210b3d42dE7f77da5b5b41F", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "gho-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "GHO / USD", + "pair": [ + "", + "" + ], + "path": "gho-usd", + "proxyAddress": "0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "GHO", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "GHO", + "baseAssetClic": "GHO_CR", + "blockchainName": "Ethereum", + "clicProductName": "GHO/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "GHO", + "quoteAssetClic": "GHO_CR", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xffB5820Df5F3366949754b31AB1E48331b943C1f", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "tusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "TUSD / USD", + "pair": [ + "", + "" + ], + "path": "tusd-usd", + "proxyAddress": "0xec746eCF986E2927Abd291a2A1716c940100f8Ba", + "threshold": 0.3, + "valuePrefix": "", + "assetName": "True USD", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "TUSD", + "baseAssetClic": "TUSD_CR", + "blockchainName": "Ethereum", + "clicProductName": "TUSD/USD-RefPrice-DF-Ethereum-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + } + ] \ No newline at end of file diff --git a/src/constants/chainlink-data/polygon.json b/src/constants/chainlink-data/polygon.json new file mode 100644 index 00000000..e89fe10a --- /dev/null +++ b/src/constants/chainlink-data/polygon.json @@ -0,0 +1,1014 @@ +[ + { + "compareOffchain": "", + "contractAddress": "0x2C7aA4B8509A45d5395EBC792C5F1f6A8e24b02e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sfrxusdfrxusd-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "SFRXUSD-FRXUSD Exchange Rate", + "pair": [ + "", + "" + ], + "path": "sfrxusd-frxusd-exchange-rate", + "proxyAddress": "0xCf7824ed30bd7a3844F4a644aB996bE5380dEE76", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "Staked Frax USD", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "SFRXUSD", + "baseAssetClic": "SFRXUSD_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "SFRXUSD/FRXUSD-ExRate-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "FRXUSD", + "quoteAssetClic": "FRXUSD_CR", + "underlyingAsset": "FRXUSD", + "underlyingAssetClic": "FRXUSD_CR" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x2F584c39F33A28A5fd70388Ebd119c57c91F0A53", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "weeth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "weETH / ETH", + "pair": [ + "", + "" + ], + "path": "weeth-eth", + "proxyAddress": "0x3Eae75C0a2f9b1038C7c9993C1Da36281E838811", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped eETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "weETH", + "baseAssetClic": "weETH_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "weETH/ETH-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "ETH", + "underlyingAssetClic": "ETH_CR" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x315D8643084C6b8C10d78DD7E62B576A4CE35fB2", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wsteth-eth", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "wstETH / ETH", + "pair": [ + "", + "" + ], + "path": "wsteth-eth", + "proxyAddress": "0xCB568C33EA2B0B81852655d722E3a52d9D44e7De", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped stETH", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WSTETH", + "baseAssetClic": "WSTETH_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "WSTETH/ETH-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "ETH", + "quoteAssetClic": "ETH_CR", + "underlyingAsset": "STETH", + "underlyingAssetClic": "STETH_CR" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x345551718a054FA05Ba665261A189102AcfeCB7B", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sfrxusd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SFRXUSD / USD", + "pair": [ + "", + "" + ], + "path": "sfrxusd-usd", + "proxyAddress": "0xC68bBBf73F5d3F0D455f03509522cfA7A8cc2706", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Staked Frax USD", + "feedCategory": "high", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "sfrxUSD", + "baseAssetClic": "sfrxUSD_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "sfrxUSD/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x433c0516fAE1a55E750d701C9F9031b2359bc647", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WBTC / BTC", + "pair": [ + "", + "" + ], + "path": "wbtc-btc", + "proxyAddress": "0xAd2937e7D25c237856B03319265465C0291b1895", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped Bitcoin", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WBTC", + "baseAssetClic": "WBTC_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "WBTC/BTC-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x47522E7273344f1016a1e67e496DdB4F77D852C9", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "eth-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "ETH / USD", + "pair": [ + "", + "" + ], + "path": "eth-usd", + "proxyAddress": "0x7BdBDB772f4a073BadD676A567C6ED82049a8eEE", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Ethereum", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "ETH", + "baseAssetClic": "ETH_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "ETH/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x49bb123E42330baE0e2B40D7f0bACB77d24f9403", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "pol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "POL / USD", + "pair": [ + "", + "" + ], + "path": "pol-usd", + "proxyAddress": "0xF6630799b5387e0E9ACe92a5E82673021781B440", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "POL", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "POL", + "baseAssetClic": "POL_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "POL/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x56Ac2b1b78225d47993e8866795A34Ad540a515C", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "btc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "BTC / USD", + "pair": [ + "", + "" + ], + "path": "btc-usd", + "proxyAddress": "0x41DdB7F8F5e1b2bD28193B84C1C36Be698dEd162", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "BTC", + "blockchainName": "Polygon-Katana", + "clicProductName": "BTC/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x681EDcE7cE1c3E01833AEa6678C95bb83c2a29EF", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "jitosol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "JITOSOL / USD", + "pair": [ + "", + "" + ], + "path": "jitosol-usd", + "proxyAddress": "0x36E03469335b7F2eF51aAeB914b76c038645679A", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "Jito Staked SOL", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "JITOSOL", + "baseAssetClic": "JITOSOL_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "JITOSOL/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x6e3dAB4DC369E337A8302A008cb15B7Cd1309956", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdt-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDT / USD", + "pair": [ + "", + "" + ], + "path": "usdt-usd", + "proxyAddress": "0xF03E1566Fc6B0eBFA3dD3aA197759C4c6617ec78", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Tether USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDT", + "baseAssetClic": "USDT_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "USDT/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x70576Bf8FE28A1EB5A9349F8b4509370eA38C46e", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "link-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LINK / USD", + "pair": [ + "", + "" + ], + "path": "link-usd", + "proxyAddress": "0x06bD6464e94Bee9393Ae15B5Dd5eCDFAa4F299C1", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Chainlink", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LINK", + "blockchainName": "Polygon-Katana", + "clicProductName": "LINK/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x729bc72F6a6e37394d64d8c98f0637Ea92983921", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "yfi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "YFI / USD", + "pair": [ + "", + "" + ], + "path": "yfi-usd", + "proxyAddress": "0xfcDcCF5C2BEAB72FDb910481beaE807F5453686B", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Yearn Finance", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "YFI", + "baseAssetClic": "YFI_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "YFI/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0x74237D00F3a8BfEDc8a1a6aD5E550a738e664d14", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "wbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "WBTC / USD", + "pair": [ + "", + "" + ], + "path": "wbtc-usd", + "proxyAddress": "0x0D03E26E0B5D09E24E5a45696D0FcA12E9648FBB", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Wrapped Bitcoin", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "WBTC", + "baseAssetClic": "WBTC_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "WBTC/BTC-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR", + "underlyingAsset": "BTC", + "underlyingAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0x766faDCc743BF3646A9f0db9cC7Be456E123F341", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usdc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDC / USD", + "pair": [ + "", + "" + ], + "path": "usdc-usd", + "proxyAddress": "0xbe5CE90e16B9d9d988D64b0E1f6ed46EbAfb9606", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Circle USD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDC", + "baseAssetClic": "USDC_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "USDC/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0x91616662d719dB85EFd931556cbFd453824448Ef", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "yusd-usd-exchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "1000000000000000000", + "name": "yUSD / USD Exchange Rate", + "pair": [ + "", + "" + ], + "path": "yusd-usd-exchange-rate", + "proxyAddress": "0xe61b585418B92917771c89D4d3957707cfFE6154", + "threshold": 1e-7, + "valuePrefix": "", + "assetName": "yUSD / USD Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "yUSD", + "baseAssetClic": "yUSD_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "yUSD/USD-ExRate-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xA3E7CF38E05F6eD4E9C96A477263c984E2e30326", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lbtc-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LBTC / USD", + "pair": [ + "", + "" + ], + "path": "lbtc-usd", + "proxyAddress": "0x5C2c6A77310C7750fCc5c3f13a3f9C3b18a68d3e", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Lombard Staked BTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "LBTC", + "baseAssetClic": "LBTC_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "LBTC/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xC7c94c13fe86f3B9DEAcaab7fE62d107112c0408", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "usds-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "USDS / USD", + "pair": [ + "", + "" + ], + "path": "usds-usd", + "proxyAddress": "0x44cdCd6F81cEe5BAC68B21845Fc82846ee09A369", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "USDS", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "USDS", + "baseAssetClic": "USDS_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "USDS/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xE18707ea3D3b430b757aa9190b26a9fC39Dd9500", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "jitosol-sol", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "1000000000000000000", + "name": "JitoSOL / SOL", + "pair": [ + "", + "" + ], + "path": "jitosol-sol", + "proxyAddress": "0x1C0a310cf42F357087Be122e69ee402D19A265dC", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Jito Staked SOL", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "JITOSOL", + "baseAssetClic": "JITOSOL_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "JITOSOL/ETH-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "SOL", + "quoteAssetClic": "SOL_CR", + "underlyingAsset": "SOL", + "underlyingAssetClic": "SOL_CR" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xEc9eDC8321c9aB7880aDA1084f54C846a17aD748", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "lbtc-btc", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "LBTC / BTC", + "pair": [ + "", + "" + ], + "path": "lbtc-btc", + "proxyAddress": "0x6830BfE63F8804B4972D92826b9088d2fb6AFe5b", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "LBTC / BTC", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "LBTC", + "baseAssetClic": "LBTC_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "LBTC/BTC-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "BTC", + "quoteAssetClic": "BTC_CR" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0xba984fb6452fEB34132B905BD2E20bfb49cF0020", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "morpho-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "MORPHO / USD", + "pair": [ + "", + "" + ], + "path": "morpho-usd", + "proxyAddress": "0xdFd824A5Dcad8667142d58FE4aF115d5d052f26c", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Morpho", + "feedCategory": "medium", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "MORPHO", + "baseAssetClic": "MORPHO_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "MORPHO/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0xc714e4493525F4E0996E8dfc3E8F16De74e5201E", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sushi-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SUSHI / USD", + "pair": [ + "", + "" + ], + "path": "sushi-usd", + "proxyAddress": "0xA30C356781E5e1b455b274cdDe524FB7BF3809da", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Sushi", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SUSHI", + "baseAssetClic": "SUSHI_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "SUSHI/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "compareOffchain": "", + "contractAddress": "0xc943c5F7455379Dea16634949B2E2458C6a3bce8", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "vyusdusdexchange-rate", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 3600, + "history": null, + "multiply": "1000000000000000000", + "name": "vyUSD-USD-Exchange Rate", + "pair": [ + "", + "" + ], + "path": "vyusd-usd-exchange-rate", + "proxyAddress": "0xA3c605120295cdf90064A25A7689dB15Ca80Ee12", + "threshold": 0.05, + "valuePrefix": "", + "assetName": "vyUSD / USD Exchange Rate", + "feedCategory": "custom", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Pegged Asset", + "baseAsset": "vyUSD", + "baseAssetClic": "vyUSD_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "vyUSD/USD-ExRate-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Exchange Rate", + "productType": "Price", + "productTypeCode": "ExRate", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 18 + }, + { + "benchmark": "dex-state", + "compareOffchain": "", + "contractAddress": "0xe6Cd972DbD5Fd921Bb1FdBf4829F0CEB16aDC4d2", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "ausd-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "AUSD / USD", + "pair": [ + "", + "" + ], + "path": "ausd-usd", + "proxyAddress": "0x3A49D4e23868222785f148BA2bd0bAEc80d36a2A", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "AUSD", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "assetSubClass": "Stablecoin", + "baseAsset": "AUSD", + "baseAssetClic": "AUSD_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "AUSD/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX", + "underlyingAsset": "USD", + "underlyingAssetClic": "USD_FX" + }, + "decimals": 8 + }, + { + "benchmark": "cex-lwba", + "compareOffchain": "", + "contractAddress": "0xf70c1677D31a2593bB8beEdf3BE0BC5FD5492Da6", + "contractType": "", + "contractVersion": 6, + "decimalPlaces": null, + "ens": "sol-usd", + "formatDecimalPlaces": null, + "healthPrice": "", + "heartbeat": 86400, + "history": null, + "multiply": "100000000", + "name": "SOL / USD", + "pair": [ + "", + "" + ], + "path": "sol-usd", + "proxyAddress": "0x709c4dc298322916eaE59bfdc2e3d750B55C864B", + "threshold": 0.5, + "valuePrefix": "", + "assetName": "Solana", + "feedCategory": "low", + "feedType": "Crypto", + "docs": { + "assetClass": "Crypto", + "baseAsset": "SOL", + "baseAssetClic": "SOL_CR", + "blockchainName": "Polygon-Katana", + "clicProductName": "SOL/USD-RefPrice-DF-Polygon-Katana-001", + "deliveryChannelCode": "DF", + "marketHours": "Crypto", + "productSubType": "Reference", + "productType": "Price", + "productTypeCode": "RefPrice", + "quoteAsset": "USD", + "quoteAssetClic": "USD_FX" + }, + "decimals": 8 + } + ] \ No newline at end of file diff --git a/src/constants/chainlink-data/types.ts b/src/constants/chainlink-data/types.ts new file mode 100644 index 00000000..c50cc5e7 --- /dev/null +++ b/src/constants/chainlink-data/types.ts @@ -0,0 +1,19 @@ +export type ChainlinkOracleEntry = { + contractAddress: string + contractVersion: number + ens: string + heartbeat: number + multiply: string + name: string + path: string + proxyAddress: string + threshold: number + valuePrefix: string + assetName: string + feedCategory: 'low' | 'medium' | 'high' | 'custom' + feedType: string + decimals: number + baseAsset: string + quoteAsset: string + isSVR: boolean +} From 384119c142651bc4eb0bf0bafaf45e7ab3a5e3af Mon Sep 17 00:00:00 2001 From: antoncoding Date: Thu, 4 Sep 2025 18:05:48 +0800 Subject: [PATCH 03/19] feat: chainlink feed data --- app/market/[chainId]/[marketid]/content.tsx | 70 +++++----- .../MarketOracle/ChainlinkFeedTooltip.tsx | 122 ++++++++++++++++++ src/components/MarketOracle/FeedEntry.tsx | 62 +++++++++ .../MarketOracle/MarketOracleFeedInfo.tsx | 67 ++++++++++ src/components/MarketOracle/index.ts | 3 + src/constants/chainlink-data/index.ts | 18 ++- src/utils/oracle.ts | 41 +++++- 7 files changed, 338 insertions(+), 45 deletions(-) create mode 100644 src/components/MarketOracle/ChainlinkFeedTooltip.tsx create mode 100644 src/components/MarketOracle/FeedEntry.tsx create mode 100644 src/components/MarketOracle/MarketOracleFeedInfo.tsx create mode 100644 src/components/MarketOracle/index.ts diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index 44837c8a..1627271e 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -13,7 +13,7 @@ import { useAccount } from 'wagmi'; import { BorrowModal } from '@/components/BorrowModal'; import { Button } from '@/components/common'; import { Spinner } from '@/components/common/Spinner'; -import { OracleFeedInfo } from '@/components/FeedInfo/OracleFeedInfo'; +import { MarketOracleFeedInfo } from '@/components/MarketOracle'; import Header from '@/components/layout/header/Header'; import OracleVendorBadge from '@/components/OracleVendorBadge'; import { SupplyModalV2 } from '@/components/SupplyModalV2'; @@ -324,53 +324,43 @@ function MarketContent() { - Oracle Info + + Oracle Info + {market.oracle?.data && ( + + + + + + + )} +
-
- Vendor: - {market.oracle?.data && ( - - {' '} - - - )} -
Live Price: {Number(formattedOraclePrice).toFixed(4)} {market.loanAsset.symbol}
- {hasFeed && ( -
-

Feed Routes:

- {market.oracle?.data && ( -
- - - - -
- )} -
+ {hasFeed && market.oracle?.data && ( + <> +
+ Feeds Info: +
+ + )}
diff --git a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx new file mode 100644 index 00000000..8ecb2a94 --- /dev/null +++ b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx @@ -0,0 +1,122 @@ +import Image from 'next/image' +import Link from 'next/link' +import { ExternalLinkIcon } from '@radix-ui/react-icons' +import { Address } from 'viem' +import { getSlicedAddress } from '@/utils/address' +import { getExplorerURL } from '@/utils/external' +import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { OracleFeed } from '@/utils/types' +import { ChainlinkOracleEntry, getChainlinkFeedUrl } from '@/constants/chainlink-data' + +type ChainlinkFeedTooltipProps = { + feed: OracleFeed + chainlinkData?: ChainlinkOracleEntry + chainId: number +} + +export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: ChainlinkFeedTooltipProps) { + const baseAsset = feed.pair?.[0] ?? chainlinkData?.baseAsset ?? 'Unknown' + const quoteAsset = feed.pair?.[1] ?? chainlinkData?.quoteAsset ?? 'Unknown' + + const vendorIcon = OracleVendorIcons[OracleVendors.Chainlink] + + // Generate Chainlink feed URL if we have the chainlink data + const chainlinkUrl = chainlinkData ? getChainlinkFeedUrl(chainId, { + ens: chainlinkData.ens, + contractAddress: chainlinkData.contractAddress, + contractVersion: chainlinkData.contractVersion, + heartbeat: chainlinkData.heartbeat, + multiply: chainlinkData.multiply, + name: chainlinkData.name, + path: chainlinkData.path, + proxyAddress: chainlinkData.proxyAddress, + threshold: chainlinkData.threshold, + valuePrefix: chainlinkData.valuePrefix, + assetName: chainlinkData.assetName, + feedCategory: chainlinkData.feedCategory, + feedType: chainlinkData.feedType, + decimals: chainlinkData.decimals, + docs: { + baseAsset: chainlinkData.baseAsset, + quoteAsset: chainlinkData.quoteAsset, + } + }) : '' + + return ( +
+
+ {/* Header with icon and title */} +
+ {vendorIcon && ( +
+ Chainlink +
+ )} +
Chainlink Feed Details
+
+ + {/* Feed info */} +
+
+ {baseAsset} / {quoteAsset} +
+
+ + {/* Address */} +
+
Address:
+ + {getSlicedAddress(feed.address as Address)} + + +
+ + {/* Chainlink Specific Data */} + {chainlinkData && ( +
+
+ Heartbeat: + {chainlinkData.heartbeat}s +
+
+ Category: + {chainlinkData.feedCategory} +
+
+ Threshold: + {(chainlinkData.threshold * 100).toFixed(1)}% +
+ {chainlinkData.isSVR && ( +
+ Type: + + SVR Feed + +
+ )} +
+ )} + + {/* Chainlink Feed Link */} + {chainlinkUrl && ( +
+ + View on Chainlink + + +
+ )} +
+
+ ) +} \ No newline at end of file diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx new file mode 100644 index 00000000..cb873be1 --- /dev/null +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -0,0 +1,62 @@ +import { Tooltip } from '@heroui/react' +import Image from 'next/image' +import { IoIosSwap } from 'react-icons/io' +import { IoWarningOutline } from 'react-icons/io5' +import { useMemo } from 'react' +import { Address } from 'viem' +import { getChainlinkOracle } from '@/constants/chainlink-data' +import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { OracleFeed } from '@/utils/types' +import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' + +type FeedEntryProps = { + feed: OracleFeed | null + chainId: number +} + +export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null { + if (!feed) return null + + const chainlinkFeedData = useMemo(() => { + if (!feed?.address) return undefined + return getChainlinkOracle(chainId, feed.address as Address) + }, [chainId, feed.address]) + + const truncateAsset = (asset: string) => asset.length > 5 ? asset.slice(0, 5) : asset + + const fromAsset = truncateAsset(feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown') + const toAsset = truncateAsset(feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown') + + const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] + const isChainlink = feed.vendor === OracleVendors.Chainlink + const isSVR = chainlinkFeedData?.isSVR ?? false + + return ( + } + > +
+
+ {fromAsset} + + {toAsset} +
+ +
+ {isSVR && ( + + SVR + + )} + + {isChainlink && vendorIcon ? ( + Chainlink + ) : ( + + )} +
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/MarketOracle/MarketOracleFeedInfo.tsx b/src/components/MarketOracle/MarketOracleFeedInfo.tsx new file mode 100644 index 00000000..a9a5ef27 --- /dev/null +++ b/src/components/MarketOracle/MarketOracleFeedInfo.tsx @@ -0,0 +1,67 @@ +import { OracleFeed } from '@/utils/types' +import { FeedEntry } from './FeedEntry' + +type MarketOracleFeedInfoProps = { + baseFeedOne: OracleFeed | null + baseFeedTwo: OracleFeed | null + quoteFeedOne: OracleFeed | null + quoteFeedTwo: OracleFeed | null + chainId: number +} + +export function MarketOracleFeedInfo({ + baseFeedOne, + baseFeedTwo, + quoteFeedOne, + quoteFeedTwo, + chainId, +}: MarketOracleFeedInfoProps): JSX.Element { + const hasAnyFeed = baseFeedOne || baseFeedTwo || quoteFeedOne || quoteFeedTwo + + if (!hasAnyFeed) { + return ( +
+ No feed routes available +
+ ) + } + + const EmptyFeedSlot = () => ( +
+ -- +
+ ) + + const renderFeed = (feed: OracleFeed | null) => + feed ? ( +
+ +
+ ) : ( + + ) + + return ( +
+ {(baseFeedOne || baseFeedTwo) && ( +
+ Base: +
+
{renderFeed(baseFeedOne)}
+
{renderFeed(baseFeedTwo)}
+
+
+ )} + + {(quoteFeedOne || quoteFeedTwo) && ( +
+ Quote: +
+
{renderFeed(quoteFeedOne)}
+
{renderFeed(quoteFeedTwo)}
+
+
+ )} +
+ ) +} \ No newline at end of file diff --git a/src/components/MarketOracle/index.ts b/src/components/MarketOracle/index.ts new file mode 100644 index 00000000..bef1edef --- /dev/null +++ b/src/components/MarketOracle/index.ts @@ -0,0 +1,3 @@ +export { FeedEntry } from './FeedEntry' +export { MarketOracleFeedInfo } from './MarketOracleFeedInfo' +export { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' \ No newline at end of file diff --git a/src/constants/chainlink-data/index.ts b/src/constants/chainlink-data/index.ts index db3c846a..5883e57c 100644 --- a/src/constants/chainlink-data/index.ts +++ b/src/constants/chainlink-data/index.ts @@ -72,12 +72,22 @@ export const isChainlinkOracle = (chainId: number, address: string): boolean => } export const getChainlinkOracle = (chainId: number, address: string): ChainlinkOracleEntry | undefined => { - if (!isSupportedChain(chainId) || !address) return undefined const network = chainId as SupportedNetworks - return CHAINLINK_ORACLES[network].find((oracle) => oracle.proxyAddress.toLowerCase() === address.toLowerCase()) - - + return CHAINLINK_ORACLES[network].find((oracle) => oracle.proxyAddress.toLowerCase() === address.toLowerCase()) +} + +export const getChainlinkFeedUrl = (chainId: number, rawOracleEntry: RawOracleEntry): string => { + if (chainId === SupportedNetworks.Mainnet) { + return `https://data.chain.link/feeds/ethereum/mainnet/${rawOracleEntry.ens}` + } + if (chainId === SupportedNetworks.Base) { + return `https://data.chain.link/feeds/base/base/${rawOracleEntry.ens}` + } + if (chainId === SupportedNetworks.Polygon) { + return `https://data.chain.link/feeds/polygon/mainnet/${rawOracleEntry.ens}` + } + return '' } export * from './types' \ No newline at end of file diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index 695a5af3..56d84b06 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -1,4 +1,5 @@ -import { MorphoChainlinkOracleData } from './types'; +import { getChainlinkOracle } from '@/constants/chainlink-data'; +import { MorphoChainlinkOracleData, OracleFeed } from './types'; type VendorInfo = { vendors: OracleVendors[]; @@ -61,3 +62,41 @@ export function parseOracleVendors( isUnknown: vendors.has(OracleVendors.Unknown) || vendors.size === 0, }; } + +export function checkFeedsPath( + oracleData: MorphoChainlinkOracleData | null | undefined, + chainId: number, + collateralSymbol: string, + loanSymbol: string, +): boolean { + if (!oracleData) return false; + + /** + Price = Base Feed 1 * Base Feed 2 / Quote Feed 1 * Quote Feed 2 + */ + + const baseFee1Path = getFeedPath(oracleData.baseFeedOne, chainId); + const baseFee2Path = getFeedPath(oracleData.baseFeedTwo, chainId); + const quoteFee1Path = getFeedPath(oracleData.quoteFeedOne, chainId); + const quoteFee2Path = getFeedPath(oracleData.quoteFeedTwo, chainId); + + const nominators = [baseFee1Path.base, baseFee2Path.base, quoteFee1Path.quote, quoteFee2Path.quote]; + const denominators = [baseFee1Path.quote, baseFee2Path.quote, quoteFee1Path.base, quoteFee2Path.base]; + + return false; +} + +/** + * + * @param feed + * @param chainId + * @returns { base: "ETH", qutoe: "USD" } + */ +function getFeedPath(feed: OracleFeed | null | undefined, chainId: number): { base: string, quote: string } { + if (!feed || !feed.address) return { base: "EMPTY", quote: "EMPTY" }; + + const chainlinkData = getChainlinkOracle(chainId, feed.address); + if (!chainlinkData) return { base: "EMPTY", quote: "EMPTY" }; + + return { base: chainlinkData.baseAsset.toLowerCase(), quote: chainlinkData.quoteAsset.toLowerCase() }; +} \ No newline at end of file From 61bb878ef584c394d0e3a6f38d6ef7692c84f66f Mon Sep 17 00:00:00 2001 From: antoncoding Date: Fri, 5 Sep 2025 10:50:30 +0800 Subject: [PATCH 04/19] feat: chainlink oracle feeds --- docs/Styling.md | 14 ++- .../MarketOracle/ChainlinkFeedTooltip.tsx | 99 ++++++++++-------- src/components/MarketOracle/FeedEntry.tsx | 5 +- src/components/TooltipContent.tsx | 10 +- src/imgs/etherscan.png | Bin 0 -> 119739 bytes 5 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 src/imgs/etherscan.png diff --git a/docs/Styling.md b/docs/Styling.md index c99354f0..2f85f2ab 100644 --- a/docs/Styling.md +++ b/docs/Styling.md @@ -98,20 +98,26 @@ import { Button } from '@/components/common/Button'; ## Tooltip -Use the nextui tooltip with component for consistnet styling +Use the nextui tooltip with component for consistent styling. Always use the classNames configuration to remove HeroUI's default wrapper styling: -``` +```tsx } title="Tooltip Title" detail="Tooltip Detail" />} - > + {/* Your trigger element */} + ``` +**Important:** The `classNames` configuration removes HeroUI's default padding, background, and borders to prevent double-wrapper styling issues. This ensures only your `TooltipContent` component handles the visual styling. + ## Input Components The codebase uses two different input approaches depending on the use case: diff --git a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx index 8ecb2a94..5b0173d9 100644 --- a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx +++ b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx @@ -1,12 +1,12 @@ import Image from 'next/image' import Link from 'next/link' -import { ExternalLinkIcon } from '@radix-ui/react-icons' import { Address } from 'viem' -import { getSlicedAddress } from '@/utils/address' import { getExplorerURL } from '@/utils/external' import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { ChainlinkOracleEntry, getChainlinkFeedUrl } from '@/constants/chainlink-data' +import { Badge } from '@/components/common/Badge' +import etherscanLogo from '@/imgs/etherscan.png' type ChainlinkFeedTooltipProps = { feed: OracleFeed @@ -42,8 +42,26 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink } }) : '' + // Risk tier badge using Badge component + const getRiskTierBadge = (category: string) => { + const variantMap = { + low: 'success' as const, + medium: 'warning' as const, + high: 'danger' as const, + custom: 'primary' as const + } + + const variant = variantMap[category as keyof typeof variantMap] || 'primary' + + return ( + + {category.toUpperCase()} RISK + + ) + } + return ( -
+
{/* Header with icon and title */}
@@ -55,67 +73,64 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink
Chainlink Feed Details
- {/* Feed info */} -
-
+ {/* Feed pair name with SVR badge if applicable */} +
+
{baseAsset} / {quoteAsset}
-
- - {/* Address */} -
-
Address:
- - {getSlicedAddress(feed.address as Address)} - - + {chainlinkData?.isSVR && ( + + SVR + + )}
{/* Chainlink Specific Data */} {chainlinkData && ( -
+
Heartbeat: {chainlinkData.heartbeat}s
-
- Category: - {chainlinkData.feedCategory} +
+ Risk Tier: + {getRiskTierBadge(chainlinkData.feedCategory)}
- Threshold: - {(chainlinkData.threshold * 100).toFixed(1)}% + Deviation Threshold: + {(chainlinkData.threshold).toFixed(1)}%
- {chainlinkData.isSVR && ( -
- Type: - - SVR Feed - -
- )}
)} - {/* Chainlink Feed Link */} - {chainlinkUrl && ( -
+ {/* External Links */} +
+
+ View on: +
+
- View on Chainlink - + Etherscan + Etherscan + {chainlinkUrl && ( + + {vendorIcon && Chainlink} + Chainlink + + )}
- )} +
) diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index cb873be1..e329abb5 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -33,7 +33,10 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null return ( } >
diff --git a/src/components/TooltipContent.tsx b/src/components/TooltipContent.tsx index 6e8a5d7d..65e5f1c4 100644 --- a/src/components/TooltipContent.tsx +++ b/src/components/TooltipContent.tsx @@ -13,21 +13,21 @@ export function TooltipContent({ icon, title, detail, className = '' }: TooltipC // Simple tooltip with just an icon and title if (!detail) { return ( -
+
{icon &&
{icon}
} - {title} + {title}
); } // Complex tooltip with additional details return ( -
+
{icon &&
{icon}
}
- {title &&
{title}
} -
{detail}
+ {title &&
{title}
} +
{detail}
diff --git a/src/imgs/etherscan.png b/src/imgs/etherscan.png new file mode 100644 index 0000000000000000000000000000000000000000..f93a966702b3f32d648818b2c74c8207e8d273e4 GIT binary patch literal 119739 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

3o;d5|svi5`w89lk1#|5^mK#SFs|Ah|X& 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 Date: Fri, 5 Sep 2025 12:45:57 +0800 Subject: [PATCH 05/19] chore: compound feed --- src/components/FeedInfo/OracleFeedInfo.tsx | 30 +++- .../MarketOracle/ChainlinkFeedTooltip.tsx | 2 +- .../MarketOracle/CompoundFeedTooltip.tsx | 165 ++++++++++++++++++ src/components/MarketOracle/FeedEntry.tsx | 49 +++++- .../MarketOracle/UnknownFeedTooltip.tsx | 83 +++++++++ src/constants/compound/index.ts | 23 +++ src/utils/oracle.ts | 10 ++ 7 files changed, 349 insertions(+), 13 deletions(-) create mode 100644 src/components/MarketOracle/CompoundFeedTooltip.tsx create mode 100644 src/components/MarketOracle/UnknownFeedTooltip.tsx create mode 100644 src/constants/compound/index.ts diff --git a/src/components/FeedInfo/OracleFeedInfo.tsx b/src/components/FeedInfo/OracleFeedInfo.tsx index 33066524..18299d73 100644 --- a/src/components/FeedInfo/OracleFeedInfo.tsx +++ b/src/components/FeedInfo/OracleFeedInfo.tsx @@ -10,6 +10,8 @@ import { getExplorerURL } from '@/utils/external'; import { OracleVendors, OracleVendorIcons } from '@/utils/oracle'; import { OracleFeed } from '@/utils/types'; import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data'; +import { ChainlinkFeedTooltip } from '@/components/MarketOracle/ChainlinkFeedTooltip'; +import { TooltipContent } from '@/components/TooltipContent'; import { useMemo } from 'react'; export function OracleFeedInfo({ @@ -26,10 +28,12 @@ export function OracleFeedInfo({ return getChainlinkOracle(chainId, feed.address as Address); }, [chainId, feed.address]) - console.log('chainlinkFeedData', chainlinkFeedData); + const isChainlink = useMemo(() => { + return isChainlinkOracle(chainId, feed.address as Address); + }, [chainId, feed.address]); - const fromAsset = feed.pair?.[0] ?? 'Unknown'; - const toAsset = feed.pair?.[1] ?? 'Unknown'; + const fromAsset = feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown'; + const toAsset = feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown'; const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] ?? OracleVendorIcons[OracleVendors.Unknown]; @@ -49,10 +53,26 @@ export function OracleFeedInfo({

); + const getTooltipContent = () => { + if (isChainlink && chainlinkFeedData) { + return ; + } + + return ( + + ); + }; + return ( +
{/* Header with icon and title */}
diff --git a/src/components/MarketOracle/CompoundFeedTooltip.tsx b/src/components/MarketOracle/CompoundFeedTooltip.tsx new file mode 100644 index 00000000..e866bc4c --- /dev/null +++ b/src/components/MarketOracle/CompoundFeedTooltip.tsx @@ -0,0 +1,165 @@ +import Image from 'next/image' +import Link from 'next/link' +import { Address } from 'viem' +import { getExplorerURL } from '@/utils/external' +import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { OracleFeed } from '@/utils/types' +import { CompoundFeedEntry } from '@/constants/compound' +import { ChainlinkOracleEntry, getChainlinkFeedUrl, getChainlinkOracle } from '@/constants/chainlink-data' +import { Badge } from '@/components/common/Badge' +import { useMemo } from 'react' +import etherscanLogo from '@/imgs/etherscan.png' + +type CompoundFeedTooltipProps = { + feed: OracleFeed + compoundData: CompoundFeedEntry + chainId: number +} + +export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFeedTooltipProps) { + const baseAsset = compoundData.base + const quoteAsset = compoundData.quote + + const compoundLogo = OracleVendorIcons[OracleVendors.Compound] + const chainlinkLogo = OracleVendorIcons[OracleVendors.Chainlink] + + // Get the underlying Chainlink feed data + const underlyingChainlinkData = useMemo(() => { + return getChainlinkOracle(chainId, compoundData.underlyingChainlinkFeed as Address) + }, [chainId, compoundData.underlyingChainlinkFeed]) + + // Generate Chainlink feed URL if we have the underlying chainlink data + const chainlinkUrl = underlyingChainlinkData ? getChainlinkFeedUrl(chainId, { + ens: underlyingChainlinkData.ens, + contractAddress: underlyingChainlinkData.contractAddress, + contractVersion: underlyingChainlinkData.contractVersion, + heartbeat: underlyingChainlinkData.heartbeat, + multiply: underlyingChainlinkData.multiply, + name: underlyingChainlinkData.name, + path: underlyingChainlinkData.path, + proxyAddress: underlyingChainlinkData.proxyAddress, + threshold: underlyingChainlinkData.threshold, + valuePrefix: underlyingChainlinkData.valuePrefix, + assetName: underlyingChainlinkData.assetName, + feedCategory: underlyingChainlinkData.feedCategory, + feedType: underlyingChainlinkData.feedType, + decimals: underlyingChainlinkData.decimals, + docs: { + baseAsset: underlyingChainlinkData.baseAsset, + quoteAsset: underlyingChainlinkData.quoteAsset, + } + }) : '' + + // Risk tier badge using Badge component + const getRiskTierBadge = (category: string) => { + const variantMap = { + low: 'success' as const, + medium: 'warning' as const, + high: 'danger' as const, + custom: 'primary' as const + } + + const variant = variantMap[category as keyof typeof variantMap] || 'primary' + + return ( + + {category.toUpperCase()} RISK + + ) + } + + return ( +
+
+ {/* Header with icon and title */} +
+ {compoundLogo && ( +
+ Compound +
+ )} +
Compound Feed Details
+
+ + {/* Feed pair name */} +
+
+ {baseAsset} / {quoteAsset} +
+
+ + {/* Compound-specific description */} +
+
+ Compound Wrapper Feed +
+
+ This feed converts {underlyingChainlinkData?.baseAsset ?? 'Unknown'} / {underlyingChainlinkData?.quoteAsset ?? 'Unknown'} to {baseAsset} / {quoteAsset} using Compound's conversion logic. +
+
+ + {/* Underlying Chainlink Data */} + {underlyingChainlinkData && ( +
+
+ {chainlinkLogo && Chainlink} + + Underlying Chainlink Feed + +
+
+ Heartbeat: + {underlyingChainlinkData.heartbeat}s +
+
+ Risk Tier: + {getRiskTierBadge(underlyingChainlinkData.feedCategory)} +
+
+ Deviation Threshold: + {(underlyingChainlinkData.threshold).toFixed(1)}% +
+
+ )} + + {/* External Links */} +
+
+ View on: +
+
+ + Etherscan + Compound Feed + + + Etherscan + Underlying Feed + + {chainlinkUrl && ( + + {chainlinkLogo && Chainlink} + Chainlink + + )} +
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index e329abb5..f6573bbd 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -4,10 +4,13 @@ import { IoIosSwap } from 'react-icons/io' import { IoWarningOutline } from 'react-icons/io5' import { useMemo } from 'react' import { Address } from 'viem' -import { getChainlinkOracle } from '@/constants/chainlink-data' +import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data' +import { isCompoundFeed, getCompoundFeed } from '@/constants/compound' import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' +import { CompoundFeedTooltip } from './CompoundFeedTooltip' +import { UnknownFeedTooltip } from './UnknownFeedTooltip' type FeedEntryProps = { feed: OracleFeed | null @@ -22,22 +25,54 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null return getChainlinkOracle(chainId, feed.address as Address) }, [chainId, feed.address]) + const compoundFeedData = useMemo(() => { + if (!feed?.address) return undefined + return getCompoundFeed(feed.address as Address) + }, [feed.address]) + const truncateAsset = (asset: string) => asset.length > 5 ? asset.slice(0, 5) : asset - const fromAsset = truncateAsset(feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown') - const toAsset = truncateAsset(feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown') + // Determine asset names based on feed type + const getAssetNames = () => { + if (compoundFeedData) { + return { + fromAsset: truncateAsset(compoundFeedData.base), + toAsset: truncateAsset(compoundFeedData.quote) + } + } + return { + fromAsset: truncateAsset(feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown'), + toAsset: truncateAsset(feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown') + } + } + + const { fromAsset, toAsset } = getAssetNames() const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] - const isChainlink = feed.vendor === OracleVendors.Chainlink + const isChainlink = isChainlinkOracle(chainId, feed.address as Address) + const isCompound = isCompoundFeed(feed.address as Address) const isSVR = chainlinkFeedData?.isSVR ?? false + const getTooltipContent = () => { + if (isCompound && compoundFeedData) { + return + } + + if (isChainlink && chainlinkFeedData) { + return + } + + // Default fallback for unknown/unsupported feeds + return + } + return ( } + content={getTooltipContent()} >
@@ -53,8 +88,8 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null )} - {isChainlink && vendorIcon ? ( - Chainlink + {(isChainlink || isCompound) && vendorIcon ? ( + {feed.vendor ) : ( )} diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx new file mode 100644 index 00000000..b4a1568a --- /dev/null +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -0,0 +1,83 @@ +import Image from 'next/image' +import Link from 'next/link' +import { Address } from 'viem' +import { getExplorerURL } from '@/utils/external' +import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { OracleFeed } from '@/utils/types' +import { getSlicedAddress } from '@/utils/address' +import etherscanLogo from '@/imgs/etherscan.png' + +type UnknownFeedTooltipProps = { + feed: OracleFeed + chainId: number +} + +export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { + const baseAsset = feed.pair?.[0] ?? 'Unknown' + const quoteAsset = feed.pair?.[1] ?? 'Unknown' + + const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] + + return ( +
+
+ {/* Header with icon and title */} +
+ {vendorIcon ? ( +
+ {feed.vendor +
+ ) : ( +
+ ? +
+ )} +
Oracle Feed Details
+
+ + {/* Feed pair name */} +
+
+ {baseAsset} / {quoteAsset} +
+
+ + {/* Oracle Information */} +
+
+ Provider: + {feed.vendor ?? 'Unknown'} +
+
+ Address: + {getSlicedAddress(feed.address as Address)} +
+ {feed.description && ( +
+ Description: + {feed.description} +
+ )} +
+ + {/* External Links */} +
+
+ View on: +
+
+ + Etherscan + Etherscan + +
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/constants/compound/index.ts b/src/constants/compound/index.ts new file mode 100644 index 00000000..278a3533 --- /dev/null +++ b/src/constants/compound/index.ts @@ -0,0 +1,23 @@ +export type CompoundFeedEntry = { + address: string + base: string + quote: string + underlyingChainlinkFeed: string +} + +const compoundFeeds: CompoundFeedEntry[] = [ + { + address: '0x4F67e4d9BD67eFa28236013288737D39AeF48e79', + base: 'wstETH', + quote: 'ETH', + underlyingChainlinkFeed: '0x86392dC19c0b719886221c78AB11eb8Cf5c52812', + }, +] + +export function isCompoundFeed(address: string): boolean { + return compoundFeeds.some(feed => feed.address.toLowerCase() === address.toLowerCase()) +} + +export function getCompoundFeed(address: string): CompoundFeedEntry | undefined { + return compoundFeeds.find(feed => feed.address.toLowerCase() === address.toLowerCase()) +} \ No newline at end of file diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index 56d84b06..d425f182 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -83,6 +83,16 @@ export function checkFeedsPath( const nominators = [baseFee1Path.base, baseFee2Path.base, quoteFee1Path.quote, quoteFee2Path.quote]; const denominators = [baseFee1Path.quote, baseFee2Path.quote, quoteFee1Path.base, quoteFee2Path.base]; + // go through each nominator, and try to find thethe same denominator to cancel them out + let finalBase; + for (const nominator of nominators) { + for (const denominator of denominators) { + if (nominator === denominator) { + + } + } + // no matched denominator + } return false; } From 7f4607cd789ab83aeb4d22a08e2ad7e3355940b9 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Fri, 5 Sep 2025 15:15:26 +0800 Subject: [PATCH 06/19] feat: oracle and feed separation --- app/error.tsx | 1 + app/global-error.tsx | 1 + app/market/[chainId]/[marketid]/content.tsx | 51 +++++++------------ app/markets/components/OracleFilter.tsx | 10 ++-- app/markets/components/markets.tsx | 6 +-- app/markets/components/utils.ts | 8 +-- .../components/onboarding/RiskSelection.tsx | 8 +-- src/components/FeedInfo/OracleFeedInfo.tsx | 4 +- .../MarketOracle/ChainlinkFeedTooltip.tsx | 4 +- .../MarketOracle/CompoundFeedTooltip.tsx | 6 +-- src/components/MarketOracle/FeedEntry.tsx | 4 +- .../MarketOracle/MarketOracleFeedInfo.tsx | 14 ++--- .../MarketOracle/OracleTypeInfo.tsx | 40 +++++++++++++++ .../MarketOracle/UnknownFeedTooltip.tsx | 4 +- src/components/MarketOracle/index.ts | 3 +- src/components/OracleVendorBadge.tsx | 6 +-- src/utils/oracle.ts | 49 +++++++++++++----- 17 files changed, 134 insertions(+), 85 deletions(-) create mode 100644 src/components/MarketOracle/OracleTypeInfo.tsx diff --git a/app/error.tsx b/app/error.tsx index 4026f76a..ed33d7bc 100644 --- a/app/error.tsx +++ b/app/error.tsx @@ -25,3 +25,4 @@ export default function AppError({
); } + diff --git a/app/global-error.tsx b/app/global-error.tsx index 0be2491a..d77e2cd9 100644 --- a/app/global-error.tsx +++ b/app/global-error.tsx @@ -21,3 +21,4 @@ export default function GlobalError({ error, reset }: { error: Error; reset: () ); } + diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index 1627271e..01cd950e 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -13,7 +13,7 @@ import { useAccount } from 'wagmi'; import { BorrowModal } from '@/components/BorrowModal'; import { Button } from '@/components/common'; import { Spinner } from '@/components/common/Spinner'; -import { MarketOracleFeedInfo } from '@/components/MarketOracle'; +import { MarketOracleFeedInfo, OracleTypeInfo } from '@/components/MarketOracle'; import Header from '@/components/layout/header/Header'; import OracleVendorBadge from '@/components/OracleVendorBadge'; import { SupplyModalV2 } from '@/components/SupplyModalV2'; @@ -179,11 +179,6 @@ function MarketContent() { // 8. Derived values that depend on market data const cardStyle = 'bg-surface rounded shadow-sm p-4'; - const hasFeed = - market.oracle?.data?.baseFeedOne || - market.oracle?.data?.baseFeedTwo || - market.oracle?.data?.quoteFeedOne || - market.oracle?.data?.quoteFeedTwo; return ( <> @@ -326,19 +321,18 @@ function MarketContent() { Oracle Info - {market.oracle?.data && ( - - - - - - - )} + + + + + + +
@@ -348,20 +342,11 @@ function MarketContent() { {Number(formattedOraclePrice).toFixed(4)} {market.loanAsset.symbol}
- {hasFeed && market.oracle?.data && ( - <> -
- Feeds Info: -
- - - )} +
diff --git a/app/markets/components/OracleFilter.tsx b/app/markets/components/OracleFilter.tsx index beef1019..5312805f 100644 --- a/app/markets/components/OracleFilter.tsx +++ b/app/markets/components/OracleFilter.tsx @@ -3,12 +3,12 @@ import { ChevronDownIcon } from '@radix-ui/react-icons'; import Image from 'next/image'; import { FaQuestionCircle } from 'react-icons/fa'; import OracleVendorBadge from '@/components/OracleVendorBadge'; -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleFilterProps = { - selectedOracles: OracleVendors[]; - setSelectedOracles: (oracles: OracleVendors[]) => void; + selectedOracles: PriceFeedVendors[]; + setSelectedOracles: (oracles: PriceFeedVendors[]) => void; }; export default function OracleFilter({ selectedOracles, setSelectedOracles }: OracleFilterProps) { @@ -30,7 +30,7 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or const toggleDropdown = () => setIsOpen(!isOpen); - const toggleOracle = (oracle: OracleVendors) => { + const toggleOracle = (oracle: PriceFeedVendors) => { if (selectedOracles.includes(oracle)) { setSelectedOracles(selectedOracles.filter((o) => o !== oracle)); } else { @@ -84,7 +84,7 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or }`} >
    - {Object.values(OracleVendors).map((oracle) => ( + {Object.values(PriceFeedVendors).map((oracle) => (
  • (''); - const [selectedOracles, setSelectedOracles] = useState([]); + const [selectedOracles, setSelectedOracles] = useState([]); const { currentPage, setCurrentPage, entriesPerPage, handleEntriesPerPageChange, resetPage } = usePagination(); @@ -208,7 +208,7 @@ export default function Markets({ ).filter((market) => { if (!searchQuery) return true; // If no search query, show all markets const lowercaseQuery = searchQuery.toLowerCase(); - const { vendors } = parseOracleVendors(market.oracle?.data); + const { vendors } = parsePriceFeedVendors(market.oracle?.data); const vendorsName = vendors.join(','); return ( market.uniqueKey.toLowerCase().includes(lowercaseQuery) || diff --git a/app/markets/components/utils.ts b/app/markets/components/utils.ts index b55606c4..ebc3c565 100644 --- a/app/markets/components/utils.ts +++ b/app/markets/components/utils.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { SupportedNetworks } from '@/utils/networks'; -import { parseOracleVendors, OracleVendors } from '@/utils/oracle'; +import { parsePriceFeedVendors, PriceFeedVendors } from '@/utils/oracle'; import { ERC20Token } from '@/utils/tokens'; import { Market } from '@/utils/types'; import { SortColumn } from './constants'; @@ -61,7 +61,7 @@ export function applyFilterAndSort( showUnknownOracle: boolean, selectedCollaterals: string[], selectedLoanAssets: string[], - selectedOracles: OracleVendors[], + selectedOracles: PriceFeedVendors[], staredIds: string[], findToken: (address: string, chainId: number) => ERC20Token | undefined, usdFilters: UsdFilters, @@ -91,7 +91,7 @@ export function applyFilterAndSort( if ( !showUnknownOracle && - (!market.oracle || parseOracleVendors(market.oracle.data).isUnknown) + (!market.oracle || parsePriceFeedVendors(market.oracle.data).isUnknown) ) { return false; } @@ -105,7 +105,7 @@ export function applyFilterAndSort( } if (selectedOracles.length > 0 && !!market.oracle) { - const marketOracles = parseOracleVendors(market.oracle.data).vendors; + const marketOracles = parsePriceFeedVendors(market.oracle.data).vendors; if (!marketOracles.some((oracle) => selectedOracles.includes(oracle))) { return false; } diff --git a/app/positions/components/onboarding/RiskSelection.tsx b/app/positions/components/onboarding/RiskSelection.tsx index adcc1128..75d4f349 100644 --- a/app/positions/components/onboarding/RiskSelection.tsx +++ b/app/positions/components/onboarding/RiskSelection.tsx @@ -6,7 +6,7 @@ import { Button } from '@/components/common/Button'; import { MarketInfoBlock } from '@/components/common/MarketInfoBlock'; import { useTokens } from '@/components/providers/TokenProvider'; import { formatReadable } from '@/utils/balance'; -import { OracleVendors, parseOracleVendors } from '@/utils/oracle'; +import { PriceFeedVendors, parsePriceFeedVendors } from '@/utils/oracle'; import { Market } from '@/utils/types'; import AssetFilter from 'app/markets/components/AssetFilter'; import OracleFilter from 'app/markets/components/OracleFilter'; @@ -27,7 +27,7 @@ export function RiskSelection() { goToPrevStep, } = useOnboarding(); const [selectedCollaterals, setSelectedCollaterals] = useState([]); - const [selectedOracles, setSelectedOracles] = useState([]); + const [selectedOracles, setSelectedOracles] = useState([]); const { findToken, getUniqueTokens } = useTokens(); @@ -63,11 +63,11 @@ export function RiskSelection() { // Check if oracle is selected (if any are selected) if (selectedOracles.length > 0) { - const { vendors } = parseOracleVendors(market.oracle?.data); + const { vendors } = parsePriceFeedVendors(market.oracle?.data); // if vendors is empty, push "unknown oracle" into list that needed to be selected if (vendors.length === 0) { - vendors.push(OracleVendors.Unknown); + vendors.push(PriceFeedVendors.Unknown); } // Check if all vendors are selected diff --git a/src/components/FeedInfo/OracleFeedInfo.tsx b/src/components/FeedInfo/OracleFeedInfo.tsx index 18299d73..27accbb4 100644 --- a/src/components/FeedInfo/OracleFeedInfo.tsx +++ b/src/components/FeedInfo/OracleFeedInfo.tsx @@ -7,7 +7,7 @@ import { IoWarningOutline } from 'react-icons/io5'; import { Address } from 'viem'; import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; import { OracleFeed } from '@/utils/types'; import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data'; import { ChainlinkFeedTooltip } from '@/components/MarketOracle/ChainlinkFeedTooltip'; @@ -36,7 +36,7 @@ export function OracleFeedInfo({ const toAsset = feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown'; const vendorIcon = - OracleVendorIcons[feed.vendor as OracleVendors] ?? OracleVendorIcons[OracleVendors.Unknown]; + OracleVendorIcons[feed.vendor as PriceFeedVendors] ?? OracleVendorIcons[PriceFeedVendors.Unknown]; const content = (
    diff --git a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx index 913037da..d6f5a667 100644 --- a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx +++ b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx @@ -2,7 +2,7 @@ import Image from 'next/image' import Link from 'next/link' import { Address } from 'viem' import { getExplorerURL } from '@/utils/external' -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { ChainlinkOracleEntry, getChainlinkFeedUrl } from '@/constants/chainlink-data' import { Badge } from '@/components/common/Badge' @@ -18,7 +18,7 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink const baseAsset = feed.pair?.[0] ?? chainlinkData?.baseAsset ?? 'Unknown' const quoteAsset = feed.pair?.[1] ?? chainlinkData?.quoteAsset ?? 'Unknown' - const vendorIcon = OracleVendorIcons[OracleVendors.Chainlink] + const vendorIcon = OracleVendorIcons[PriceFeedVendors.Chainlink] // Generate Chainlink feed URL if we have the chainlink data const chainlinkUrl = chainlinkData ? getChainlinkFeedUrl(chainId, { diff --git a/src/components/MarketOracle/CompoundFeedTooltip.tsx b/src/components/MarketOracle/CompoundFeedTooltip.tsx index e866bc4c..a5f8bb19 100644 --- a/src/components/MarketOracle/CompoundFeedTooltip.tsx +++ b/src/components/MarketOracle/CompoundFeedTooltip.tsx @@ -2,7 +2,7 @@ import Image from 'next/image' import Link from 'next/link' import { Address } from 'viem' import { getExplorerURL } from '@/utils/external' -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { CompoundFeedEntry } from '@/constants/compound' import { ChainlinkOracleEntry, getChainlinkFeedUrl, getChainlinkOracle } from '@/constants/chainlink-data' @@ -20,8 +20,8 @@ export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFee const baseAsset = compoundData.base const quoteAsset = compoundData.quote - const compoundLogo = OracleVendorIcons[OracleVendors.Compound] - const chainlinkLogo = OracleVendorIcons[OracleVendors.Chainlink] + const compoundLogo = OracleVendorIcons[PriceFeedVendors.Compound] + const chainlinkLogo = OracleVendorIcons[PriceFeedVendors.Chainlink] // Get the underlying Chainlink feed data const underlyingChainlinkData = useMemo(() => { diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index f6573bbd..50331ce4 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -6,7 +6,7 @@ import { useMemo } from 'react' import { Address } from 'viem' import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data' import { isCompoundFeed, getCompoundFeed } from '@/constants/compound' -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' import { CompoundFeedTooltip } from './CompoundFeedTooltip' @@ -48,7 +48,7 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null const { fromAsset, toAsset } = getAssetNames() - const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] + const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors] const isChainlink = isChainlinkOracle(chainId, feed.address as Address) const isCompound = isCompoundFeed(feed.address as Address) const isSVR = chainlinkFeedData?.isSVR ?? false diff --git a/src/components/MarketOracle/MarketOracleFeedInfo.tsx b/src/components/MarketOracle/MarketOracleFeedInfo.tsx index a9a5ef27..6287889d 100644 --- a/src/components/MarketOracle/MarketOracleFeedInfo.tsx +++ b/src/components/MarketOracle/MarketOracleFeedInfo.tsx @@ -2,10 +2,10 @@ import { OracleFeed } from '@/utils/types' import { FeedEntry } from './FeedEntry' type MarketOracleFeedInfoProps = { - baseFeedOne: OracleFeed | null - baseFeedTwo: OracleFeed | null - quoteFeedOne: OracleFeed | null - quoteFeedTwo: OracleFeed | null + baseFeedOne: OracleFeed | null | undefined + baseFeedTwo: OracleFeed | null | undefined + quoteFeedOne: OracleFeed | null | undefined + quoteFeedTwo: OracleFeed | null | undefined chainId: number } @@ -32,7 +32,7 @@ export function MarketOracleFeedInfo({
    ) - const renderFeed = (feed: OracleFeed | null) => + const renderFeed = (feed: OracleFeed | null | undefined) => feed ? (
    @@ -45,7 +45,7 @@ export function MarketOracleFeedInfo({
    {(baseFeedOne || baseFeedTwo) && (
    - Base: + Base Feeds:
    {renderFeed(baseFeedOne)}
    {renderFeed(baseFeedTwo)}
    @@ -55,7 +55,7 @@ export function MarketOracleFeedInfo({ {(quoteFeedOne || quoteFeedTwo) && (
    - Quote: + Quote Feeds:
    {renderFeed(quoteFeedOne)}
    {renderFeed(quoteFeedTwo)}
    diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx new file mode 100644 index 00000000..a9d75463 --- /dev/null +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -0,0 +1,40 @@ +import { getOracleType, getOracleTypeDescription, OracleType } from '@/utils/oracle' +import { MarketOracleFeedInfo } from '@/components/MarketOracle' +import { MorphoChainlinkOracleData } from '@/utils/types' + +type OracleTypeInfoProps = { + oracleData: MorphoChainlinkOracleData | null | undefined + oracleAddress: string + chainId: number +} + +export function OracleTypeInfo({ oracleData, oracleAddress, chainId }: OracleTypeInfoProps) { + const oracleType = getOracleType(oracleData, oracleAddress, chainId) + const typeDescription = getOracleTypeDescription(oracleType) + + return ( + <> +
    + Oracle Type: + {oracleType} +
    + + {oracleType === OracleType.Standard ? () : ( +
    +
    + {typeDescription} +
    +
    + This market uses a custom oracle implementation that doesn't follow the standard Morpho feed structure. +
    +
    + )} + + ) +} \ No newline at end of file diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx index b4a1568a..7b757c0d 100644 --- a/src/components/MarketOracle/UnknownFeedTooltip.tsx +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -2,7 +2,7 @@ import Image from 'next/image' import Link from 'next/link' import { Address } from 'viem' import { getExplorerURL } from '@/utils/external' -import { OracleVendors, OracleVendorIcons } from '@/utils/oracle' +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' import { OracleFeed } from '@/utils/types' import { getSlicedAddress } from '@/utils/address' import etherscanLogo from '@/imgs/etherscan.png' @@ -16,7 +16,7 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { const baseAsset = feed.pair?.[0] ?? 'Unknown' const quoteAsset = feed.pair?.[1] ?? 'Unknown' - const vendorIcon = OracleVendorIcons[feed.vendor as OracleVendors] + const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors] return (
    diff --git a/src/components/MarketOracle/index.ts b/src/components/MarketOracle/index.ts index bef1edef..40db8c02 100644 --- a/src/components/MarketOracle/index.ts +++ b/src/components/MarketOracle/index.ts @@ -1,3 +1,4 @@ export { FeedEntry } from './FeedEntry' export { MarketOracleFeedInfo } from './MarketOracleFeedInfo' -export { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' \ No newline at end of file +export { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' +export { OracleTypeInfo } from './OracleTypeInfo' \ No newline at end of file diff --git a/src/components/OracleVendorBadge.tsx b/src/components/OracleVendorBadge.tsx index ad38a9b4..54800386 100644 --- a/src/components/OracleVendorBadge.tsx +++ b/src/components/OracleVendorBadge.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Tooltip } from '@heroui/react'; import Image from 'next/image'; import { IoWarningOutline } from 'react-icons/io5'; -import { OracleVendorIcons, OracleVendors, parseOracleVendors } from '@/utils/oracle'; +import { OracleVendorIcons, PriceFeedVendors, parsePriceFeedVendors } from '@/utils/oracle'; import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleVendorBadgeProps = { @@ -11,7 +11,7 @@ type OracleVendorBadgeProps = { showText?: boolean; }; -const renderVendorIcon = (vendor: OracleVendors) => +const renderVendorIcon = (vendor: PriceFeedVendors) => OracleVendorIcons[vendor] ? ( {vendor} ) : ( @@ -23,7 +23,7 @@ function OracleVendorBadge({ showText = false, useTooltip = true, }: OracleVendorBadgeProps) { - const { vendors, isUnknown } = parseOracleVendors(oracleData); + const { vendors, isUnknown } = parsePriceFeedVendors(oracleData); const content = (
    diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index d425f182..863bb56b 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -2,11 +2,16 @@ import { getChainlinkOracle } from '@/constants/chainlink-data'; import { MorphoChainlinkOracleData, OracleFeed } from './types'; type VendorInfo = { - vendors: OracleVendors[]; + vendors: PriceFeedVendors[]; isUnknown: boolean; }; -export enum OracleVendors { +export enum OracleType { + Standard = 'Standard', + Custom = 'Custom', +} + +export enum PriceFeedVendors { Chainlink = 'Chainlink', PythNetwork = 'Pyth Network', Redstone = 'Redstone', @@ -16,17 +21,33 @@ export enum OracleVendors { Unknown = 'Unknown', } -export const OracleVendorIcons: Record = { - [OracleVendors.Chainlink]: require('../imgs/oracles/chainlink.png') as string, - [OracleVendors.PythNetwork]: require('../imgs/oracles/pyth.png') as string, - [OracleVendors.Redstone]: require('../imgs/oracles/redstone.png') as string, - [OracleVendors.Oval]: require('../imgs/oracles/uma.png') as string, - [OracleVendors.Compound]: require('../imgs/oracles/compound.webp') as string, - [OracleVendors.Lido]: require('../imgs/oracles/lido.png') as string, - [OracleVendors.Unknown]: '', +export const OracleVendorIcons: Record = { + [PriceFeedVendors.Chainlink]: require('../imgs/oracles/chainlink.png') as string, + [PriceFeedVendors.PythNetwork]: require('../imgs/oracles/pyth.png') as string, + [PriceFeedVendors.Redstone]: require('../imgs/oracles/redstone.png') as string, + [PriceFeedVendors.Oval]: require('../imgs/oracles/uma.png') as string, + [PriceFeedVendors.Compound]: require('../imgs/oracles/compound.webp') as string, + [PriceFeedVendors.Lido]: require('../imgs/oracles/lido.png') as string, + [PriceFeedVendors.Unknown]: '', }; -export function parseOracleVendors( +export function getOracleTypeDescription(oracleType: OracleType): string { + if (oracleType === OracleType.Standard) return 'Standard Oracle from Price Feeds'; + + return 'Custom Oracle'; +} + +export function getOracleType(oracleData: MorphoChainlinkOracleData | null | undefined, oracleAddress: string, chainId: number) { + // Morpho API only contains oracleData if it follows the standard MorphoOracle structure with feeds + if (oracleData?.baseFeedOne !== null || oracleData?.baseFeedTwo !== null || oracleData?.quoteFeedOne !== null || oracleData?.quoteFeedTwo !== null) return OracleType.Standard; + + + // Other logics to determin oracle types + console.log("Skipping logic for oracleAddress", oracleAddress, "on chainId", chainId); + return OracleType.Custom; +} + +export function parsePriceFeedVendors( oracleData: MorphoChainlinkOracleData | null | undefined, ): VendorInfo { if (!oracleData) return { vendors: [], isUnknown: false }; @@ -51,15 +72,15 @@ export function parseOracleVendors( .filter((feed) => feed?.vendor) .map( (feed) => - Object.values(OracleVendors).find( + Object.values(PriceFeedVendors).find( (v) => v.toLowerCase() === feed!.vendor!.toLowerCase(), - ) ?? OracleVendors.Unknown, + ) ?? PriceFeedVendors.Unknown, ), ); return { vendors: Array.from(vendors), - isUnknown: vendors.has(OracleVendors.Unknown) || vendors.size === 0, + isUnknown: vendors.has(PriceFeedVendors.Unknown) || vendors.size === 0, }; } From 6cc533d859bbfd686fa69d52eb42bf277ff6a3a7 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Fri, 5 Sep 2025 16:15:34 +0800 Subject: [PATCH 07/19] feat: new oracle logic --- .../MarketOracle/OracleTypeInfo.tsx | 2 +- src/data-sources/subgraph/market.ts | 17 ++-- src/hooks/useUserPositions.ts | 4 +- src/utils/oracle.ts | 10 ++- src/utils/warnings.ts | 86 +++++++++++-------- 5 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index a9d75463..90296d17 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -9,7 +9,7 @@ type OracleTypeInfoProps = { } export function OracleTypeInfo({ oracleData, oracleAddress, chainId }: OracleTypeInfoProps) { - const oracleType = getOracleType(oracleData, oracleAddress, chainId) + const oracleType = getOracleType(oracleData) const typeDescription = getOracleTypeDescription(oracleType) return ( diff --git a/src/data-sources/subgraph/market.ts b/src/data-sources/subgraph/market.ts index f2c3e840..1daa93c7 100644 --- a/src/data-sources/subgraph/market.ts +++ b/src/data-sources/subgraph/market.ts @@ -235,10 +235,8 @@ const transformSubgraphMarketToMarket = ( // Use whitelisted oracle data (feeds) if available, otherwise default const oracleDataToUse = whitelistedOracleData ?? defaultOracleData; - // Regenerate warningsWithDetail *after* potentially adding whitelist warnings - const warningsWithDetail = getMarketWarningsWithDetail({ warnings, uniqueKey: marketId }); - - const marketDetail: Market = { + + const marketDetail = { id: marketId, uniqueKey: marketId, lltv: lltv, @@ -278,7 +276,7 @@ const transformSubgraphMarketToMarket = ( }, }, warnings: warnings, // Assign the potentially filtered warnings - warningsWithDetail: warningsWithDetail, + // warningsWithDetail: warningsWithDetail, oracle: { data: oracleDataToUse, // Use the determined oracle data }, @@ -287,7 +285,14 @@ const transformSubgraphMarketToMarket = ( isMonarchWhitelisted: false, }; - return marketDetail; + // Regenerate warningsWithDetail *after* potentially adding whitelist warnings + const warningsWithDetail = getMarketWarningsWithDetail(marketDetail); + + + return { + ...marketDetail, + warningsWithDetail: warningsWithDetail + }; }; // Fetcher for market details from Subgraph diff --git a/src/hooks/useUserPositions.ts b/src/hooks/useUserPositions.ts index 831b4815..5d5da5f9 100644 --- a/src/hooks/useUserPositions.ts +++ b/src/hooks/useUserPositions.ts @@ -9,7 +9,7 @@ import { fetchSubgraphUserPositionMarkets } from '@/data-sources/subgraph/positi import { SupportedNetworks } from '@/utils/networks'; import { fetchPositionSnapshot, type PositionSnapshot } from '@/utils/positions'; import { getClient } from '@/utils/rpc'; -import { Market } from '@/utils/types'; +import { Market, WarningWithDetail } from '@/utils/types'; import { getMarketWarningsWithDetail } from '@/utils/warnings'; import { useUserMarketsCache } from '../hooks/useUserMarketsCache'; import { useCustomRpc } from './useCustomRpc'; @@ -29,7 +29,7 @@ type InitialDataResponse = { // Type for the final processed position data type EnhancedMarketPosition = { state: PositionSnapshot; - market: Market & { warningsWithDetail: ReturnType }; + market: Market & { warningsWithDetail: WarningWithDetail[] }; }; // --- Query Keys (adjusted for two-step process) --- diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index 863bb56b..00cb10bb 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -1,5 +1,7 @@ import { getChainlinkOracle } from '@/constants/chainlink-data'; import { MorphoChainlinkOracleData, OracleFeed } from './types'; +import { zeroAddress } from 'viem'; +import { isSupportedChain } from './networks'; type VendorInfo = { vendors: PriceFeedVendors[]; @@ -37,13 +39,15 @@ export function getOracleTypeDescription(oracleType: OracleType): string { return 'Custom Oracle'; } -export function getOracleType(oracleData: MorphoChainlinkOracleData | null | undefined, oracleAddress: string, chainId: number) { +export function getOracleType(oracleData: MorphoChainlinkOracleData | null | undefined, oracleAddress?: string, chainId?: number) { // Morpho API only contains oracleData if it follows the standard MorphoOracle structure with feeds - if (oracleData?.baseFeedOne !== null || oracleData?.baseFeedTwo !== null || oracleData?.quoteFeedOne !== null || oracleData?.quoteFeedTwo !== null) return OracleType.Standard; + if (!oracleData) return OracleType.Custom + + if (oracleData.baseFeedOne !== null || oracleData.baseFeedTwo !== null || oracleData.quoteFeedOne !== null || oracleData.quoteFeedTwo !== null) return OracleType.Standard; // Other logics to determin oracle types - console.log("Skipping logic for oracleAddress", oracleAddress, "on chainId", chainId); + if (oracleAddress === zeroAddress || (chainId && isSupportedChain(chainId))) return OracleType.Custom return OracleType.Custom; } diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 6e91e702..34bc112f 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -1,6 +1,7 @@ -import { MarketWarning } from '@/utils/types'; +import { MarketWarning, MorphoChainlinkOracleData } from '@/utils/types'; import { monarchWhitelistedMarkets } from './markets'; import { WarningCategory, WarningWithDetail } from './types'; +import { getOracleType, OracleType } from './oracle'; // Subgraph Warnings @@ -47,37 +48,6 @@ const morphoOfficialWarnings: WarningWithDetail[] = [ description: 'This market is using a hardcoded value in one or more of its feed routes', category: WarningCategory.oracle, }, - { - code: 'unrecognized_oracle', - level: 'alert', - description: 'The oracle is not recognized', - category: WarningCategory.oracle, - }, - { - code: 'unrecognized_oracle_feed', - level: 'alert', - description: 'This market oracle has feed(s) that are not part of our recognized feeds list.', - category: WarningCategory.oracle, - }, - { - code: 'incorrect_loan_exchange_rate', - level: 'warning', - description: 'The market is using the exchange rate from a token different from the loan one. ', - category: WarningCategory.oracle, - }, - { - code: 'incorrect_collateral_exchange_rate', - level: 'warning', - description: - 'The market is using the exchange rate from a token different from the collateral one.', - category: WarningCategory.oracle, - }, - { - code: 'incompatible_oracle_feeds', - level: 'alert', - description: 'The market is using oracle feeds which do not match with each other.', - category: WarningCategory.oracle, - }, // asset types { code: 'unrecognized_collateral_asset', @@ -141,12 +111,54 @@ const subgraphWarnings: WarningWithDetail[] = [ }, ]; +const UNRECOGNIZED_ORACLE: WarningWithDetail = { + code: 'unrecognized_oracle', + level: 'alert', + description: 'This market is using a custom oracle contract that is not recognized.', + category: WarningCategory.oracle, +} + +const INCOMPATIBLE_ORACLE_FEEDS: WarningWithDetail = { + code: 'incompatible_oracle_feeds', + level: 'alert', + description: 'The market is using oracle feeds which do not match with each other.', + category: WarningCategory.oracle, +} + +const UNRECOGNIZED_FEEDS: WarningWithDetail = { + code: 'unknown feeds', + level: 'alert', + description: 'This market oracle has feed(s) that are not part of our recognized feeds list.', + category: WarningCategory.oracle +} + + // { + // code: 'incorrect_loan_exchange_rate', + // level: 'warning', + // description: 'The market is using the exchange rate from a token different from the loan one. ', + // category: WarningCategory.oracle, + // }, + // { + // code: 'incorrect_collateral_exchange_rate', + // level: 'warning', + // description: + // 'The market is using the exchange rate from a token different from the collateral one.', + // category: WarningCategory.oracle, + // }, + + export const getMarketWarningsWithDetail = ( - market: { warnings: MarketWarning[]; uniqueKey: string }, + market: { + warnings: MarketWarning[]; + uniqueKey: string, + oracle?: {data: MorphoChainlinkOracleData}, + oracleAddress?: string, + morphoBlue: {chain: {id:number}} + }, considerWhitelist = false, ) => { const result = []; - + const allDetails = [...morphoOfficialWarnings, ...subgraphWarnings]; const whitelistedMarketData = considerWhitelist @@ -176,5 +188,11 @@ export const getMarketWarningsWithDetail = ( result.push(foundWarning); } } + + // append our own oracle warnings + const oracleType = getOracleType(market.oracle?.data, market.oracleAddress, market.morphoBlue.chain.id) + if (oracleType === OracleType.Custom) result.push(UNRECOGNIZED_ORACLE) + + return result; }; From 8de8e66b0505f11180d03c57f5425673e6db04b3 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Fri, 5 Sep 2025 16:50:38 +0800 Subject: [PATCH 08/19] feat: refactor warning details --- app/markets/components/MarketRowDetail.tsx | 4 +- app/markets/components/RiskIndicator.tsx | 19 +- .../components/PositionsSummaryTable.tsx | 92 +++++-- .../components/SuppliedMarketsDetail.tsx | 256 ++++++++++-------- src/contexts/MarketsContext.tsx | 4 - src/data-sources/morpho-api/market.ts | 3 - src/data-sources/subgraph/market.ts | 11 +- src/hooks/useMarketWarnings.ts | 27 ++ src/hooks/useUserPositions.ts | 10 +- src/utils/positions.ts | 8 - src/utils/types.ts | 3 - 11 files changed, 260 insertions(+), 177 deletions(-) create mode 100644 src/hooks/useMarketWarnings.ts diff --git a/app/markets/components/MarketRowDetail.tsx b/app/markets/components/MarketRowDetail.tsx index 2d033589..9cbd97b6 100644 --- a/app/markets/components/MarketRowDetail.tsx +++ b/app/markets/components/MarketRowDetail.tsx @@ -4,12 +4,14 @@ import { OracleFeedInfo } from '@/components/FeedInfo/OracleFeedInfo'; import { Info } from '@/components/Info/info'; import OracleVendorBadge from '@/components/OracleVendorBadge'; import { TooltipContent } from '@/components/TooltipContent'; +import { useMarketWarnings } from '@/hooks/useMarketWarnings'; import { formatReadable } from '@/utils/balance'; import { getExplorerURL } from '@/utils/external'; import { Market } from '@/utils/types'; export function ExpandedMarketDetail({ market }: { market: Market }) { const oracleData = market.oracle ? market.oracle.data : null; + const warningsWithDetail = useMarketWarnings(market, true); const hasFeeds = oracleData && @@ -87,7 +89,7 @@ export function ExpandedMarketDetail({ market }: { market: Market }) {
    - {market.warningsWithDetail.map((warning) => { + {warningsWithDetail.map((warning) => { return ( +
    @@ -79,7 +83,7 @@ export function RiskIndicatorFromWarning({ isBatched = false, mode = 'simple', }: { - market: { warningsWithDetail: WarningWithDetail[] }; + market: Market; category: WarningCategory; greenDescription: string; yellowDescription: string; @@ -87,7 +91,8 @@ export function RiskIndicatorFromWarning({ isBatched?: boolean; mode?: 'simple' | 'complex'; }) { - const warnings = market.warningsWithDetail.filter((w) => w.category === category); + const warningsWithDetail = useMarketWarnings(market, true); + const warnings = warningsWithDetail.filter((w) => w.category === category); if (warnings.length === 0) { return ; @@ -120,7 +125,7 @@ export function MarketAssetIndicator({ isBatched = false, mode = 'simple', }: { - market: { warningsWithDetail: WarningWithDetail[] }; + market: Market; isBatched?: boolean; mode?: 'simple' | 'complex'; }) { @@ -142,7 +147,7 @@ export function MarketOracleIndicator({ isBatched = false, mode = 'simple', }: { - market: { warningsWithDetail: WarningWithDetail[] }; + market: Market; isBatched?: boolean; mode?: 'simple' | 'complex'; }) { @@ -164,7 +169,7 @@ export function MarketDebtIndicator({ isBatched = false, mode = 'simple', }: { - market: { warningsWithDetail: WarningWithDetail[] }; + market: Market; isBatched?: boolean; mode?: 'simple' | 'complex'; }) { diff --git a/app/positions/components/PositionsSummaryTable.tsx b/app/positions/components/PositionsSummaryTable.tsx index 9bd5b3e3..b1d785d1 100644 --- a/app/positions/components/PositionsSummaryTable.tsx +++ b/app/positions/components/PositionsSummaryTable.tsx @@ -37,15 +37,85 @@ import { GroupedPosition, MarketPositionWithEarnings, UserRebalancerInfo, + WarningWithDetail, + WarningCategory, } from '@/utils/types'; import { - MarketAssetIndicator, - MarketOracleIndicator, - MarketDebtIndicator, + RiskIndicator, } from 'app/markets/components/RiskIndicator'; +import { computeMarketWarnings } from '@/hooks/useMarketWarnings'; import { RebalanceModal } from './RebalanceModal'; import { SuppliedMarketsDetail } from './SuppliedMarketsDetail'; +// Component to compute and display aggregated risk indicators for a group of positions +function AggregatedRiskIndicators({ groupedPosition }: { groupedPosition: GroupedPosition }) { + // Compute warnings for all markets in the group + const allWarnings: WarningWithDetail[] = []; + + for (const position of groupedPosition.markets) { + const marketWarnings = computeMarketWarnings(position.market, true); + allWarnings.push(...marketWarnings); + } + + // Remove duplicates based on warning code + const uniqueWarnings = allWarnings.filter((warning, index, array) => + array.findIndex(w => w.code === warning.code) === index + ); + + // Helper to get warnings by category and determine risk level + const getWarningIndicator = (category: WarningCategory, greenDesc: string, yellowDesc: string, redDesc: string) => { + const categoryWarnings = uniqueWarnings.filter(w => w.category === category); + + if (categoryWarnings.length === 0) { + return ; + } + + if (categoryWarnings.some(w => w.level === 'alert')) { + const alertWarning = categoryWarnings.find(w => w.level === 'alert'); + return ( + + ); + } + + return ( + + ); + }; + + return ( + <> + {getWarningIndicator( + WarningCategory.asset, + "Recognized asset", + "Asset with warning", + "High-risk asset" + )} + {getWarningIndicator( + WarningCategory.oracle, + "Recognized oracles", + "Oracle warning", + "Oracle warning" + )} + {getWarningIndicator( + WarningCategory.debt, + "No bad debt", + "Bad debt has occurred", + "Bad debt higher than 1% of supply" + )} + + ); +} + type PositionsSummaryTableProps = { account: string; marketPositions: MarketPositionWithEarnings[]; @@ -344,21 +414,7 @@ export function PositionsSummaryTable({
    - - - +
    diff --git a/app/positions/components/SuppliedMarketsDetail.tsx b/app/positions/components/SuppliedMarketsDetail.tsx index f381dc02..db60e3f2 100644 --- a/app/positions/components/SuppliedMarketsDetail.tsx +++ b/app/positions/components/SuppliedMarketsDetail.tsx @@ -6,6 +6,7 @@ import { IoWarningOutline } from 'react-icons/io5'; import { Button } from '@/components/common'; import OracleVendorBadge from '@/components/OracleVendorBadge'; import { TokenIcon } from '@/components/TokenIcon'; +import { useMarketWarnings } from '@/hooks/useMarketWarnings'; import { formatReadable, formatBalance } from '@/utils/balance'; import { MarketPosition, GroupedPosition, WarningWithDetail, WarningCategory } from '@/utils/types'; import { getCollateralColor } from '../utils/colors'; @@ -39,6 +40,135 @@ function WarningTooltip({ warnings }: { warnings: WarningWithDetail[] }) { ); } +function MarketRow({ + position, + totalSupply, + setShowWithdrawModal, + setShowSupplyModal, + setSelectedPosition, +}: { + position: MarketPosition; + totalSupply: number; + setShowWithdrawModal: (show: boolean) => void; + setShowSupplyModal: (show: boolean) => void; + setSelectedPosition: (position: MarketPosition) => void; +}) { + const warningsWithDetail = useMarketWarnings(position.market, true); + + const getWarningColor = (warnings: WarningWithDetail[]) => { + if (warnings.some((w) => w.level === 'alert')) return 'text-red-500'; + if (warnings.some((w) => w.level === 'warning')) return 'text-yellow-500'; + return ''; + }; + + const suppliedAmount = Number( + formatBalance(position.state.supplyAssets, position.market.loanAsset.decimals), + ); + const percentageOfPortfolio = + totalSupply > 0 ? (suppliedAmount / totalSupply) * 100 : 0; + const warningColor = getWarningColor(warningsWithDetail); + + return ( + + +
    +
    + {warningsWithDetail.length > 0 ? ( + } + placement="top" + > +
    + +
    +
    + ) : ( +
    + )} +
    + + {position.market.uniqueKey.slice(2, 8)} + +
    + + + {position.market.collateralAsset ? ( +
    + + {position.market.collateralAsset.symbol} +
    + ) : ( + 'N/A' + )} + + +
    + +
    + + + {formatBalance(position.market.lltv, 16)}% + + + {formatReadable(position.market.state.supplyApy * 100)}% + + + {formatReadable(suppliedAmount)} {position.market.loanAsset.symbol} + + +
    +
    +
    +
    + + {formatReadable(percentageOfPortfolio)}% + +
    + + +
    + + +
    + + + ); +} + export function SuppliedMarketsDetail({ groupedPosition, setShowWithdrawModal, @@ -65,12 +195,6 @@ export function SuppliedMarketsDetail({ const totalSupply = groupedPosition.totalSupply; - const getWarningColor = (warnings: WarningWithDetail[]) => { - if (warnings.some((w) => w.level === 'alert')) return 'text-red-500'; - if (warnings.some((w) => w.level === 'warning')) return 'text-yellow-500'; - return ''; - }; - return ( - {filteredMarkets.map((position) => { - const suppliedAmount = Number( - formatBalance(position.state.supplyAssets, position.market.loanAsset.decimals), - ); - const percentageOfPortfolio = - totalSupply > 0 ? (suppliedAmount / totalSupply) * 100 : 0; - const warningColor = getWarningColor(position.market.warningsWithDetail); - - return ( - - -
    -
    - {position.market.warningsWithDetail.length > 0 ? ( - - } - placement="top" - > -
    - -
    -
    - ) : ( -
    - )} -
    - - {position.market.uniqueKey.slice(2, 8)} - -
    - - - {position.market.collateralAsset ? ( -
    - - {position.market.collateralAsset.symbol} -
    - ) : ( - 'N/A' - )} - - -
    - -
    - - - {formatBalance(position.market.lltv, 16)}% - - - {formatReadable(position.market.state.supplyApy * 100)}% - - - {formatReadable(suppliedAmount)} {position.market.loanAsset.symbol} - - -
    -
    -
    -
    - - {formatReadable(percentageOfPortfolio)}% - -
    - - -
    - - -
    - - - ); - })} + {filteredMarkets.map((position) => ( + + ))}
    diff --git a/src/contexts/MarketsContext.tsx b/src/contexts/MarketsContext.tsx index 720af067..b52c3260 100644 --- a/src/contexts/MarketsContext.tsx +++ b/src/contexts/MarketsContext.tsx @@ -17,7 +17,6 @@ import { useLocalStorage } from '@/hooks/useLocalStorage'; import { monarchWhitelistedMarkets, blacklistedMarkets } from '@/utils/markets'; import { isSupportedChain, SupportedNetworks } from '@/utils/networks'; import { Market } from '@/utils/types'; -import { getMarketWarningsWithDetail } from '@/utils/warnings'; // Export the type definition export type MarketsContextType = { @@ -134,7 +133,6 @@ export function MarketsProvider({ children }: MarketsProviderProps) { .filter((market) => !blacklistedMarkets.includes(market.uniqueKey)); const processedMarkets = filtered.map((market) => { - const warningsWithDetail = getMarketWarningsWithDetail(market, true); // Recalculate warnings if needed, though fetchers might do this const isProtectedByLiquidationBots = liquidatedMarketKeys.has(market.uniqueKey); // only show this indicator when it's not already whitelisted @@ -147,8 +145,6 @@ export function MarketsProvider({ children }: MarketsProviderProps) { return { ...market, whitelisted: market.whitelisted || isMonarchWhitelisted, - // Ensure warningsWithDetail from fetchers are used or recalculated consistently - warningsWithDetail: market.warningsWithDetail ?? warningsWithDetail, isProtectedByLiquidationBots, isMonarchWhitelisted, }; diff --git a/src/data-sources/morpho-api/market.ts b/src/data-sources/morpho-api/market.ts index db16f103..4c7fe8c3 100644 --- a/src/data-sources/morpho-api/market.ts +++ b/src/data-sources/morpho-api/market.ts @@ -2,7 +2,6 @@ import { marketDetailQuery, marketsQuery } from '@/graphql/morpho-api-queries'; import { SupportedNetworks } from '@/utils/networks'; import { blacklistTokens } from '@/utils/tokens'; import { Market } from '@/utils/types'; -import { getMarketWarningsWithDetail } from '@/utils/warnings'; import { morphoGraphqlFetcher } from './fetchers'; type MarketGraphQLResponse = { @@ -29,10 +28,8 @@ type MarketsGraphQLResponse = { }; const processMarketData = (market: Market): Market => { - const warningsWithDetail = getMarketWarningsWithDetail(market, true); return { ...market, - warningsWithDetail, isProtectedByLiquidationBots: false, isMonarchWhitelisted: false, diff --git a/src/data-sources/subgraph/market.ts b/src/data-sources/subgraph/market.ts index 1daa93c7..d133d278 100644 --- a/src/data-sources/subgraph/market.ts +++ b/src/data-sources/subgraph/market.ts @@ -22,7 +22,6 @@ import { } from '@/utils/tokens'; import { MorphoChainlinkOracleData, Market, MarketWarning } from '@/utils/types'; import { - getMarketWarningsWithDetail, SUBGRAPH_NO_ORACLE, SUBGRAPH_NO_PRICE, UNRECOGNIZED_COLLATERAL, @@ -276,7 +275,6 @@ const transformSubgraphMarketToMarket = ( }, }, warnings: warnings, // Assign the potentially filtered warnings - // warningsWithDetail: warningsWithDetail, oracle: { data: oracleDataToUse, // Use the determined oracle data }, @@ -285,14 +283,7 @@ const transformSubgraphMarketToMarket = ( isMonarchWhitelisted: false, }; - // Regenerate warningsWithDetail *after* potentially adding whitelist warnings - const warningsWithDetail = getMarketWarningsWithDetail(marketDetail); - - - return { - ...marketDetail, - warningsWithDetail: warningsWithDetail - }; + return marketDetail; }; // Fetcher for market details from Subgraph diff --git a/src/hooks/useMarketWarnings.ts b/src/hooks/useMarketWarnings.ts new file mode 100644 index 00000000..150adde8 --- /dev/null +++ b/src/hooks/useMarketWarnings.ts @@ -0,0 +1,27 @@ +import { useMemo } from 'react'; +import { Market, WarningWithDetail } from '@/utils/types'; +import { getMarketWarningsWithDetail } from '@/utils/warnings'; + +/** + * Hook to compute market warnings with details on-demand + * This separates data fetching concerns from presentation logic + */ +export const useMarketWarnings = ( + market: Pick, + considerWhitelist = false, +): WarningWithDetail[] => { + return useMemo(() => { + return getMarketWarningsWithDetail(market, considerWhitelist); + }, [market.warnings, market.uniqueKey, market.oracle, market.oracleAddress, market.morphoBlue?.chain?.id, considerWhitelist]); +}; + +/** + * Utility function for computing warnings in non-React contexts + * Use this in contexts where you can't use hooks + */ +export const computeMarketWarnings = ( + market: Pick, + considerWhitelist = false, +): WarningWithDetail[] => { + return getMarketWarningsWithDetail(market, considerWhitelist); +}; \ No newline at end of file diff --git a/src/hooks/useUserPositions.ts b/src/hooks/useUserPositions.ts index 5d5da5f9..00cb2c7a 100644 --- a/src/hooks/useUserPositions.ts +++ b/src/hooks/useUserPositions.ts @@ -9,8 +9,7 @@ import { fetchSubgraphUserPositionMarkets } from '@/data-sources/subgraph/positi import { SupportedNetworks } from '@/utils/networks'; import { fetchPositionSnapshot, type PositionSnapshot } from '@/utils/positions'; import { getClient } from '@/utils/rpc'; -import { Market, WarningWithDetail } from '@/utils/types'; -import { getMarketWarningsWithDetail } from '@/utils/warnings'; +import { Market } from '@/utils/types'; import { useUserMarketsCache } from '../hooks/useUserMarketsCache'; import { useCustomRpc } from './useCustomRpc'; import { useMarkets } from './useMarkets'; @@ -29,7 +28,7 @@ type InitialDataResponse = { // Type for the final processed position data type EnhancedMarketPosition = { state: PositionSnapshot; - market: Market & { warningsWithDetail: WarningWithDetail[] }; + market: Market; }; // --- Query Keys (adjusted for two-step process) --- @@ -242,10 +241,7 @@ const useUserPositions = (user: string | undefined, showEmpty = false) => { }) .map((position) => ({ state: position.state, - market: { - ...position.market, - warningsWithDetail: getMarketWarningsWithDetail(position.market, true), - }, + market: position.market, })); // Update market cache diff --git a/src/utils/positions.ts b/src/utils/positions.ts index a75a8c98..0641913d 100644 --- a/src/utils/positions.ts +++ b/src/utils/positions.ts @@ -428,14 +428,6 @@ export function groupPositionsByLoanAsset( if (shouldInclude) { groupedPosition.markets.push(position); - // Restore original logic for totals, warnings, and collaterals - groupedPosition.allWarnings = [ - ...new Set([ - ...groupedPosition.allWarnings, - ...(position.market.warningsWithDetail || []), - ]), - ] as WarningWithDetail[]; - const supplyAmount = Number( formatUnits(BigInt(position.state.supplyAssets), loanAssetDecimals), ); diff --git a/src/utils/types.ts b/src/utils/types.ts index 91829edc..c149ddf4 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -298,9 +298,6 @@ export type Market = { // whether we have USD price such has supplyUSD, borrowUSD, collateralUSD, etc. If not, use estimationP hasUSDPrice: boolean; warnings: MarketWarning[]; - - // appended by us - warningsWithDetail: WarningWithDetail[]; isProtectedByLiquidationBots: boolean; isMonarchWhitelisted?: boolean; From d32e90f33f8edd7280318b9f0ef3b9455c055644 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Fri, 5 Sep 2025 18:20:32 +0800 Subject: [PATCH 09/19] feat: price feed data from Morpho --- app/error.tsx | 1 - app/global-error.tsx | 1 - app/market/[chainId]/[marketid]/content.tsx | 6 +- app/markets/components/RiskIndicator.tsx | 12 +- .../components/PositionsSummaryTable.tsx | 55 +- .../components/SuppliedMarketsDetail.tsx | 9 +- app/rewards/components/RewardTable.tsx | 5 +- docs/Styling.md | 8 +- src/OnchainProviders.tsx | 11 +- src/components/FeedInfo/OracleFeedInfo.tsx | 81 +- .../MarketOracle/ChainlinkFeedTooltip.tsx | 118 +- .../MarketOracle/CompoundFeedTooltip.tsx | 162 +- src/components/MarketOracle/FeedEntry.tsx | 129 +- .../MarketOracle/GeneralFeedTooltip.tsx | 119 + .../MarketOracle/MarketOracleFeedInfo.tsx | 36 +- .../MarketOracle/OracleTypeInfo.tsx | 49 +- .../MarketOracle/UnknownFeedTooltip.tsx | 62 +- src/components/MarketOracle/index.ts | 8 +- src/components/TooltipContent.tsx | 4 +- src/components/layout/header/Navbar.tsx | 6 +- src/components/providers/ClientProviders.tsx | 1 - src/components/providers/QueryProvider.tsx | 6 +- src/components/settings/CustomRpcSettings.tsx | 4 +- src/constants/chainlink-data/types.ts | 19 - .../{ => oracle}/chainlink-data/README | 11 +- .../{ => oracle}/chainlink-data/base.json | 4770 ++++---- .../{ => oracle}/chainlink-data/index.ts | 102 +- .../{ => oracle}/chainlink-data/mainnet.json | 10128 ++++++++-------- .../{ => oracle}/chainlink-data/polygon.json | 832 +- src/constants/oracle/chainlink-data/types.ts | 19 + src/constants/{ => oracle}/compound/index.ts | 18 +- src/constants/oracle/general-feeds/index.ts | 37 + .../oracle/general-feeds/price-feeds.json | 9821 +++++++++++++++ src/constants/oracle/general-feeds/types.ts | 16 + src/data-sources/subgraph/market.ts | 1 - src/hooks/useCustomRpc.ts | 1 - src/hooks/useMarketWarnings.ts | 11 +- src/hooks/usePositionReport.ts | 5 +- src/hooks/useTransactionWithToast.tsx | 13 +- src/hooks/useUserPositions.ts | 5 +- src/hooks/useUserPositionsSummaryData.ts | 2 +- src/utils/oracle.ts | 242 +- src/utils/positions.ts | 2 +- src/utils/rpc.ts | 1 - src/utils/warnings.ts | 62 +- 45 files changed, 18648 insertions(+), 8363 deletions(-) create mode 100644 src/components/MarketOracle/GeneralFeedTooltip.tsx delete mode 100644 src/constants/chainlink-data/types.ts rename src/constants/{ => oracle}/chainlink-data/README (53%) rename src/constants/{ => oracle}/chainlink-data/base.json (59%) rename src/constants/{ => oracle}/chainlink-data/index.ts (58%) rename src/constants/{ => oracle}/chainlink-data/mainnet.json (57%) rename src/constants/{ => oracle}/chainlink-data/polygon.json (56%) create mode 100644 src/constants/oracle/chainlink-data/types.ts rename src/constants/{ => oracle}/compound/index.ts (59%) create mode 100644 src/constants/oracle/general-feeds/index.ts create mode 100644 src/constants/oracle/general-feeds/price-feeds.json create mode 100644 src/constants/oracle/general-feeds/types.ts diff --git a/app/error.tsx b/app/error.tsx index ed33d7bc..4026f76a 100644 --- a/app/error.tsx +++ b/app/error.tsx @@ -25,4 +25,3 @@ export default function AppError({
    ); } - diff --git a/app/global-error.tsx b/app/global-error.tsx index d77e2cd9..0be2491a 100644 --- a/app/global-error.tsx +++ b/app/global-error.tsx @@ -21,4 +21,3 @@ export default function GlobalError({ error, reset }: { error: Error; reset: () ); } - diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index 01cd950e..1d2342a6 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -13,8 +13,8 @@ import { useAccount } from 'wagmi'; import { BorrowModal } from '@/components/BorrowModal'; import { Button } from '@/components/common'; import { Spinner } from '@/components/common/Spinner'; -import { MarketOracleFeedInfo, OracleTypeInfo } from '@/components/MarketOracle'; import Header from '@/components/layout/header/Header'; +import { MarketOracleFeedInfo, OracleTypeInfo } from '@/components/MarketOracle'; import OracleVendorBadge from '@/components/OracleVendorBadge'; import { SupplyModalV2 } from '@/components/SupplyModalV2'; import { TokenIcon } from '@/components/TokenIcon'; @@ -179,7 +179,6 @@ function MarketContent() { // 8. Derived values that depend on market data const cardStyle = 'bg-surface rounded shadow-sm p-4'; - return ( <>
    @@ -321,7 +320,7 @@ function MarketContent() { Oracle Info - + -
    diff --git a/app/markets/components/RiskIndicator.tsx b/app/markets/components/RiskIndicator.tsx index e3538afe..9db8ec37 100644 --- a/app/markets/components/RiskIndicator.tsx +++ b/app/markets/components/RiskIndicator.tsx @@ -63,10 +63,14 @@ export function RiskIndicator({ ); return ( - +
    diff --git a/app/positions/components/PositionsSummaryTable.tsx b/app/positions/components/PositionsSummaryTable.tsx index b1d785d1..fa13541c 100644 --- a/app/positions/components/PositionsSummaryTable.tsx +++ b/app/positions/components/PositionsSummaryTable.tsx @@ -22,6 +22,7 @@ import { Button } from '@/components/common/Button'; import { TokenIcon } from '@/components/TokenIcon'; import { TooltipContent } from '@/components/TooltipContent'; import { useLocalStorage } from '@/hooks/useLocalStorage'; +import { computeMarketWarnings } from '@/hooks/useMarketWarnings'; import { useStyledToast } from '@/hooks/useStyledToast'; import { formatReadable, formatBalance } from '@/utils/balance'; import { getNetworkImg } from '@/utils/networks'; @@ -40,10 +41,7 @@ import { WarningWithDetail, WarningCategory, } from '@/utils/types'; -import { - RiskIndicator, -} from 'app/markets/components/RiskIndicator'; -import { computeMarketWarnings } from '@/hooks/useMarketWarnings'; +import { RiskIndicator } from 'app/markets/components/RiskIndicator'; import { RebalanceModal } from './RebalanceModal'; import { SuppliedMarketsDetail } from './SuppliedMarketsDetail'; @@ -51,27 +49,32 @@ import { SuppliedMarketsDetail } from './SuppliedMarketsDetail'; function AggregatedRiskIndicators({ groupedPosition }: { groupedPosition: GroupedPosition }) { // Compute warnings for all markets in the group const allWarnings: WarningWithDetail[] = []; - + for (const position of groupedPosition.markets) { const marketWarnings = computeMarketWarnings(position.market, true); allWarnings.push(...marketWarnings); } - + // Remove duplicates based on warning code - const uniqueWarnings = allWarnings.filter((warning, index, array) => - array.findIndex(w => w.code === warning.code) === index + const uniqueWarnings = allWarnings.filter( + (warning, index, array) => array.findIndex((w) => w.code === warning.code) === index, ); - + // Helper to get warnings by category and determine risk level - const getWarningIndicator = (category: WarningCategory, greenDesc: string, yellowDesc: string, redDesc: string) => { - const categoryWarnings = uniqueWarnings.filter(w => w.category === category); - + const getWarningIndicator = ( + category: WarningCategory, + greenDesc: string, + yellowDesc: string, + redDesc: string, + ) => { + const categoryWarnings = uniqueWarnings.filter((w) => w.category === category); + if (categoryWarnings.length === 0) { return ; } - - if (categoryWarnings.some(w => w.level === 'alert')) { - const alertWarning = categoryWarnings.find(w => w.level === 'alert'); + + if (categoryWarnings.some((w) => w.level === 'alert')) { + const alertWarning = categoryWarnings.find((w) => w.level === 'alert'); return ( ); } - + return ( ); }; - + return ( <> {getWarningIndicator( WarningCategory.asset, - "Recognized asset", - "Asset with warning", - "High-risk asset" + 'Recognized asset', + 'Asset with warning', + 'High-risk asset', )} {getWarningIndicator( WarningCategory.oracle, - "Recognized oracles", - "Oracle warning", - "Oracle warning" + 'Recognized oracles', + 'Oracle warning', + 'Oracle warning', )} {getWarningIndicator( WarningCategory.debt, - "No bad debt", - "Bad debt has occurred", - "Bad debt higher than 1% of supply" + 'No bad debt', + 'Bad debt has occurred', + 'Bad debt higher than 1% of supply', )} ); diff --git a/app/positions/components/SuppliedMarketsDetail.tsx b/app/positions/components/SuppliedMarketsDetail.tsx index db60e3f2..e53b5537 100644 --- a/app/positions/components/SuppliedMarketsDetail.tsx +++ b/app/positions/components/SuppliedMarketsDetail.tsx @@ -54,7 +54,7 @@ function MarketRow({ setSelectedPosition: (position: MarketPosition) => void; }) { const warningsWithDetail = useMarketWarnings(position.market, true); - + const getWarningColor = (warnings: WarningWithDetail[]) => { if (warnings.some((w) => w.level === 'alert')) return 'text-red-500'; if (warnings.some((w) => w.level === 'warning')) return 'text-yellow-500'; @@ -64,8 +64,7 @@ function MarketRow({ const suppliedAmount = Number( formatBalance(position.state.supplyAssets, position.market.loanAsset.decimals), ); - const percentageOfPortfolio = - totalSupply > 0 ? (suppliedAmount / totalSupply) * 100 : 0; + const percentageOfPortfolio = totalSupply > 0 ? (suppliedAmount / totalSupply) * 100 : 0; const warningColor = getWarningColor(warningsWithDetail); return ( @@ -136,9 +135,7 @@ function MarketRow({ style={{ width: `${percentageOfPortfolio}%` }} />
    - - {formatReadable(percentageOfPortfolio)}% - + {formatReadable(percentageOfPortfolio)}%
    diff --git a/app/rewards/components/RewardTable.tsx b/app/rewards/components/RewardTable.tsx index 98c96dc0..88a88490 100644 --- a/app/rewards/components/RewardTable.tsx +++ b/app/rewards/components/RewardTable.tsx @@ -141,7 +141,10 @@ export default function RewardTable({ height={20} /> ) : ( -
    +
    )}
    diff --git a/docs/Styling.md b/docs/Styling.md index 2f85f2ab..f48336cc 100644 --- a/docs/Styling.md +++ b/docs/Styling.md @@ -104,13 +104,9 @@ Use the nextui tooltip with component for consistent styling. A } - title="Tooltip Title" - detail="Tooltip Detail" - />} + content={} title="Tooltip Title" detail="Tooltip Detail" />} > {/* Your trigger element */} diff --git a/src/OnchainProviders.tsx b/src/OnchainProviders.tsx index ae69556a..d6a31f41 100644 --- a/src/OnchainProviders.tsx +++ b/src/OnchainProviders.tsx @@ -9,7 +9,6 @@ import { CustomRpcProvider, useCustomRpcContext } from './components/providers/C type Props = { children: ReactNode }; - const projectId = process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID ?? ''; if (!projectId) { if (process.env.NODE_ENV !== 'production') { @@ -22,11 +21,11 @@ const staticWagmiConfig = createWagmiConfig(projectId); function WagmiConfigProvider({ children }: Props) { const { customRpcUrls } = useCustomRpcContext(); - + // Only use dynamic config when custom RPCs are explicitly set const hasCustomRpcs = Object.keys(customRpcUrls).length > 0; - const wagmiConfig = hasCustomRpcs - ? createWagmiConfig(projectId, customRpcUrls) + const wagmiConfig = hasCustomRpcs + ? createWagmiConfig(projectId, customRpcUrls) : staticWagmiConfig; return ( @@ -44,9 +43,7 @@ function WagmiConfigProvider({ children }: Props) { }} modalSize="compact" > - - {children} - + {children} ); diff --git a/src/components/FeedInfo/OracleFeedInfo.tsx b/src/components/FeedInfo/OracleFeedInfo.tsx index 27accbb4..d23131c1 100644 --- a/src/components/FeedInfo/OracleFeedInfo.tsx +++ b/src/components/FeedInfo/OracleFeedInfo.tsx @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { Tooltip } from '@heroui/react'; import { ExternalLinkIcon } from '@radix-ui/react-icons'; import Image from 'next/image'; @@ -5,14 +6,14 @@ import Link from 'next/link'; import { IoIosSwap } from 'react-icons/io'; import { IoWarningOutline } from 'react-icons/io5'; import { Address } from 'viem'; +import { ChainlinkFeedTooltip } from '@/components/MarketOracle/ChainlinkFeedTooltip'; +import { CompoundFeedTooltip } from '@/components/MarketOracle/CompoundFeedTooltip'; +import { GeneralFeedTooltip } from '@/components/MarketOracle/GeneralFeedTooltip'; +import { TooltipContent } from '@/components/TooltipContent'; import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; +import { detectFeedVendor, PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; import { OracleFeed } from '@/utils/types'; -import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data'; -import { ChainlinkFeedTooltip } from '@/components/MarketOracle/ChainlinkFeedTooltip'; -import { TooltipContent } from '@/components/TooltipContent'; -import { useMemo } from 'react'; export function OracleFeedInfo({ feed, @@ -21,22 +22,20 @@ export function OracleFeedInfo({ feed: OracleFeed | null; chainId: number; }): JSX.Element | null { - if (!feed) return null; + // Use centralized feed detection - moved before early return to avoid conditional hook calls + const feedVendorResult = useMemo(() => { + if (!feed?.address) return null; + return detectFeedVendor(feed.address as Address, chainId); + }, [feed?.address, chainId, feed?.pair]); - const chainlinkFeedData = useMemo(() => { - if (!feed || !feed.address) return undefined; - return getChainlinkOracle(chainId, feed.address as Address); - }, [chainId, feed.address]) + if (!feed) return null; - const isChainlink = useMemo(() => { - return isChainlinkOracle(chainId, feed.address as Address); - }, [chainId, feed.address]); + if (!feedVendorResult) return null; - const fromAsset = feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown'; - const toAsset = feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown'; + const { vendor, data, assetPair } = feedVendorResult; + const { fromAsset, toAsset } = assetPair; - const vendorIcon = - OracleVendorIcons[feed.vendor as PriceFeedVendors] ?? OracleVendorIcons[PriceFeedVendors.Unknown]; + const vendorIcon = OracleVendorIcons[vendor] ?? OracleVendorIcons[PriceFeedVendors.Unknown]; const content = (
    @@ -54,23 +53,51 @@ export function OracleFeedInfo({ ); const getTooltipContent = () => { - if (isChainlink && chainlinkFeedData) { - return ; + // Use discriminated union for type-safe tooltip selection + switch (vendor) { + case PriceFeedVendors.Chainlink: + return ; + + case PriceFeedVendors.Compound: + return ; + + case PriceFeedVendors.Redstone: + case PriceFeedVendors.PythNetwork: + case PriceFeedVendors.Oval: + case PriceFeedVendors.Lido: + return ; + + case PriceFeedVendors.Unknown: + // For unknown feeds, check if we have general feed data or fallback to default + if (data) { + return ; + } + return ( + + ); + + default: + return ( + + ); } - - return ( - - ); }; return ( diff --git a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx index d6f5a667..d3b6002c 100644 --- a/src/components/MarketOracle/ChainlinkFeedTooltip.tsx +++ b/src/components/MarketOracle/ChainlinkFeedTooltip.tsx @@ -1,67 +1,69 @@ -import Image from 'next/image' -import Link from 'next/link' -import { Address } from 'viem' -import { getExplorerURL } from '@/utils/external' -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' -import { OracleFeed } from '@/utils/types' -import { ChainlinkOracleEntry, getChainlinkFeedUrl } from '@/constants/chainlink-data' -import { Badge } from '@/components/common/Badge' -import etherscanLogo from '@/imgs/etherscan.png' +import Image from 'next/image'; +import Link from 'next/link'; +import { Address } from 'viem'; +import { Badge } from '@/components/common/Badge'; +import { ChainlinkOracleEntry, getChainlinkFeedUrl } from '@/constants/oracle/chainlink-data'; +import etherscanLogo from '@/imgs/etherscan.png'; +import { getExplorerURL } from '@/utils/external'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; +import { OracleFeed } from '@/utils/types'; type ChainlinkFeedTooltipProps = { - feed: OracleFeed - chainlinkData?: ChainlinkOracleEntry - chainId: number -} + feed: OracleFeed; + chainlinkData?: ChainlinkOracleEntry; + chainId: number; +}; export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: ChainlinkFeedTooltipProps) { - const baseAsset = feed.pair?.[0] ?? chainlinkData?.baseAsset ?? 'Unknown' - const quoteAsset = feed.pair?.[1] ?? chainlinkData?.quoteAsset ?? 'Unknown' - - const vendorIcon = OracleVendorIcons[PriceFeedVendors.Chainlink] - + const baseAsset = feed.pair?.[0] ?? chainlinkData?.baseAsset ?? 'Unknown'; + const quoteAsset = feed.pair?.[1] ?? chainlinkData?.quoteAsset ?? 'Unknown'; + + const vendorIcon = OracleVendorIcons[PriceFeedVendors.Chainlink]; + // Generate Chainlink feed URL if we have the chainlink data - const chainlinkUrl = chainlinkData ? getChainlinkFeedUrl(chainId, { - ens: chainlinkData.ens, - contractAddress: chainlinkData.contractAddress, - contractVersion: chainlinkData.contractVersion, - heartbeat: chainlinkData.heartbeat, - multiply: chainlinkData.multiply, - name: chainlinkData.name, - path: chainlinkData.path, - proxyAddress: chainlinkData.proxyAddress, - threshold: chainlinkData.threshold, - valuePrefix: chainlinkData.valuePrefix, - assetName: chainlinkData.assetName, - feedCategory: chainlinkData.feedCategory, - feedType: chainlinkData.feedType, - decimals: chainlinkData.decimals, - docs: { - baseAsset: chainlinkData.baseAsset, - quoteAsset: chainlinkData.quoteAsset, - } - }) : '' + const chainlinkUrl = chainlinkData + ? getChainlinkFeedUrl(chainId, { + ens: chainlinkData.ens, + contractAddress: chainlinkData.contractAddress, + contractVersion: chainlinkData.contractVersion, + heartbeat: chainlinkData.heartbeat, + multiply: chainlinkData.multiply, + name: chainlinkData.name, + path: chainlinkData.path, + proxyAddress: chainlinkData.proxyAddress, + threshold: chainlinkData.threshold, + valuePrefix: chainlinkData.valuePrefix, + assetName: chainlinkData.assetName, + feedCategory: chainlinkData.feedCategory, + feedType: chainlinkData.feedType, + decimals: chainlinkData.decimals, + docs: { + baseAsset: chainlinkData.baseAsset, + quoteAsset: chainlinkData.quoteAsset, + }, + }) + : ''; // Risk tier badge using Badge component const getRiskTierBadge = (category: string) => { const variantMap = { low: 'success' as const, - medium: 'warning' as const, + medium: 'warning' as const, high: 'danger' as const, - custom: 'primary' as const - } - - const variant = variantMap[category as keyof typeof variantMap] || 'primary' - + custom: 'primary' as const, + }; + + const variant = variantMap[category as keyof typeof variantMap] || 'primary'; + return ( {category.toUpperCase()} RISK - ) - } + ); + }; return ( -
    +
    {/* Header with icon and title */}
    @@ -92,20 +94,20 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink Heartbeat: {chainlinkData.heartbeat}s
    -
    +
    Risk Tier: {getRiskTierBadge(chainlinkData.feedCategory)}
    Deviation Threshold: - {(chainlinkData.threshold).toFixed(1)}% + {chainlinkData.threshold.toFixed(1)}%
    )} {/* External Links */}
    -
    +
    View on:
    @@ -113,9 +115,15 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink href={getExplorerURL(feed.address as Address, chainId)} target="_blank" rel="noopener noreferrer" - className="flex items-center gap-1 rounded-sm bg-hovered px-3 py-2 text-xs font-medium text-primary hover:bg-opacity-80 transition-all duration-200 no-underline" + className="bg-hovered flex items-center gap-1 rounded-sm px-3 py-2 text-xs font-medium text-primary no-underline transition-all duration-200 hover:bg-opacity-80" > - Etherscan + Etherscan Etherscan {chainlinkUrl && ( @@ -123,7 +131,7 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink href={chainlinkUrl} target="_blank" rel="noopener noreferrer" - className="flex items-center gap-1 rounded-sm bg-hovered px-3 py-2 text-xs font-medium text-primary hover:bg-opacity-80 transition-all duration-200 no-underline" + className="bg-hovered flex items-center gap-1 rounded-sm px-3 py-2 text-xs font-medium text-primary no-underline transition-all duration-200 hover:bg-opacity-80" > {vendorIcon && Chainlink} Chainlink @@ -133,5 +141,5 @@ export function ChainlinkFeedTooltip({ feed, chainlinkData, chainId }: Chainlink
    - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/CompoundFeedTooltip.tsx b/src/components/MarketOracle/CompoundFeedTooltip.tsx index a5f8bb19..a18ec203 100644 --- a/src/components/MarketOracle/CompoundFeedTooltip.tsx +++ b/src/components/MarketOracle/CompoundFeedTooltip.tsx @@ -1,75 +1,81 @@ -import Image from 'next/image' -import Link from 'next/link' -import { Address } from 'viem' -import { getExplorerURL } from '@/utils/external' -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' -import { OracleFeed } from '@/utils/types' -import { CompoundFeedEntry } from '@/constants/compound' -import { ChainlinkOracleEntry, getChainlinkFeedUrl, getChainlinkOracle } from '@/constants/chainlink-data' -import { Badge } from '@/components/common/Badge' -import { useMemo } from 'react' -import etherscanLogo from '@/imgs/etherscan.png' +import { useMemo } from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; +import { Address } from 'viem'; +import { Badge } from '@/components/common/Badge'; +import { + ChainlinkOracleEntry, + getChainlinkFeedUrl, + getChainlinkOracle, +} from '@/constants/oracle/chainlink-data'; +import { CompoundFeedEntry } from '@/constants/oracle/compound'; +import etherscanLogo from '@/imgs/etherscan.png'; +import { getExplorerURL } from '@/utils/external'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; +import { OracleFeed } from '@/utils/types'; type CompoundFeedTooltipProps = { - feed: OracleFeed - compoundData: CompoundFeedEntry - chainId: number -} + feed: OracleFeed; + compoundData: CompoundFeedEntry; + chainId: number; +}; export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFeedTooltipProps) { - const baseAsset = compoundData.base - const quoteAsset = compoundData.quote - - const compoundLogo = OracleVendorIcons[PriceFeedVendors.Compound] - const chainlinkLogo = OracleVendorIcons[PriceFeedVendors.Chainlink] - + const baseAsset = compoundData.base; + const quoteAsset = compoundData.quote; + + const compoundLogo = OracleVendorIcons[PriceFeedVendors.Compound]; + const chainlinkLogo = OracleVendorIcons[PriceFeedVendors.Chainlink]; + // Get the underlying Chainlink feed data const underlyingChainlinkData = useMemo(() => { - return getChainlinkOracle(chainId, compoundData.underlyingChainlinkFeed as Address) - }, [chainId, compoundData.underlyingChainlinkFeed]) + return getChainlinkOracle(chainId, compoundData.underlyingChainlinkFeed as Address); + }, [chainId, compoundData.underlyingChainlinkFeed]); // Generate Chainlink feed URL if we have the underlying chainlink data - const chainlinkUrl = underlyingChainlinkData ? getChainlinkFeedUrl(chainId, { - ens: underlyingChainlinkData.ens, - contractAddress: underlyingChainlinkData.contractAddress, - contractVersion: underlyingChainlinkData.contractVersion, - heartbeat: underlyingChainlinkData.heartbeat, - multiply: underlyingChainlinkData.multiply, - name: underlyingChainlinkData.name, - path: underlyingChainlinkData.path, - proxyAddress: underlyingChainlinkData.proxyAddress, - threshold: underlyingChainlinkData.threshold, - valuePrefix: underlyingChainlinkData.valuePrefix, - assetName: underlyingChainlinkData.assetName, - feedCategory: underlyingChainlinkData.feedCategory, - feedType: underlyingChainlinkData.feedType, - decimals: underlyingChainlinkData.decimals, - docs: { - baseAsset: underlyingChainlinkData.baseAsset, - quoteAsset: underlyingChainlinkData.quoteAsset, - } - }) : '' + const chainlinkUrl = underlyingChainlinkData + ? getChainlinkFeedUrl(chainId, { + ens: underlyingChainlinkData.ens, + contractAddress: underlyingChainlinkData.contractAddress, + contractVersion: underlyingChainlinkData.contractVersion, + heartbeat: underlyingChainlinkData.heartbeat, + multiply: underlyingChainlinkData.multiply, + name: underlyingChainlinkData.name, + path: underlyingChainlinkData.path, + proxyAddress: underlyingChainlinkData.proxyAddress, + threshold: underlyingChainlinkData.threshold, + valuePrefix: underlyingChainlinkData.valuePrefix, + assetName: underlyingChainlinkData.assetName, + feedCategory: underlyingChainlinkData.feedCategory, + feedType: underlyingChainlinkData.feedType, + decimals: underlyingChainlinkData.decimals, + docs: { + baseAsset: underlyingChainlinkData.baseAsset, + quoteAsset: underlyingChainlinkData.quoteAsset, + }, + }) + : ''; // Risk tier badge using Badge component const getRiskTierBadge = (category: string) => { const variantMap = { low: 'success' as const, - medium: 'warning' as const, + medium: 'warning' as const, high: 'danger' as const, - custom: 'primary' as const - } - - const variant = variantMap[category as keyof typeof variantMap] || 'primary' - + custom: 'primary' as const, + }; + + const variant = variantMap[category as keyof typeof variantMap] || 'primary'; + return ( {category.toUpperCase()} RISK - ) - } + ); + }; return ( -
    +
    {/* Header with icon and title */}
    @@ -89,20 +95,24 @@ export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFee
    {/* Compound-specific description */} -
    -
    +
    +
    Compound Wrapper Feed
    - This feed converts {underlyingChainlinkData?.baseAsset ?? 'Unknown'} / {underlyingChainlinkData?.quoteAsset ?? 'Unknown'} to {baseAsset} / {quoteAsset} using Compound's conversion logic. + This feed converts {underlyingChainlinkData?.baseAsset ?? 'Unknown'} /{' '} + {underlyingChainlinkData?.quoteAsset ?? 'Unknown'} to {baseAsset} / {quoteAsset} using + Compound's conversion logic.
    {/* Underlying Chainlink Data */} {underlyingChainlinkData && (
    -
    - {chainlinkLogo && Chainlink} +
    + {chainlinkLogo && ( + Chainlink + )} Underlying Chainlink Feed @@ -111,39 +121,51 @@ export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFee Heartbeat: {underlyingChainlinkData.heartbeat}s
    -
    +
    Risk Tier: {getRiskTierBadge(underlyingChainlinkData.feedCategory)}
    Deviation Threshold: - {(underlyingChainlinkData.threshold).toFixed(1)}% + {underlyingChainlinkData.threshold.toFixed(1)}%
    )} {/* External Links */}
    -
    +
    View on:
    -
    +
    - Etherscan + Etherscan Compound Feed - Etherscan + Etherscan Underlying Feed {chainlinkUrl && ( @@ -151,9 +173,11 @@ export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFee href={chainlinkUrl} target="_blank" rel="noopener noreferrer" - className="flex items-center gap-1 rounded-sm bg-hovered px-3 py-2 text-xs font-medium text-primary hover:bg-opacity-80 transition-all duration-200 no-underline" + className="bg-hovered flex items-center gap-1 rounded-sm px-3 py-2 text-xs font-medium text-primary no-underline transition-all duration-200 hover:bg-opacity-80" > - {chainlinkLogo && Chainlink} + {chainlinkLogo && ( + Chainlink + )} Chainlink )} @@ -161,5 +185,5 @@ export function CompoundFeedTooltip({ feed, compoundData, chainId }: CompoundFee
    - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index 50331ce4..d07e97e4 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -1,93 +1,98 @@ -import { Tooltip } from '@heroui/react' -import Image from 'next/image' -import { IoIosSwap } from 'react-icons/io' -import { IoWarningOutline } from 'react-icons/io5' -import { useMemo } from 'react' -import { Address } from 'viem' -import { getChainlinkOracle, isChainlinkOracle } from '@/constants/chainlink-data' -import { isCompoundFeed, getCompoundFeed } from '@/constants/compound' -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' -import { OracleFeed } from '@/utils/types' -import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' -import { CompoundFeedTooltip } from './CompoundFeedTooltip' -import { UnknownFeedTooltip } from './UnknownFeedTooltip' +import { useMemo } from 'react'; +import { Tooltip } from '@heroui/react'; +import Image from 'next/image'; +import { IoIosSwap } from 'react-icons/io'; +import { IoWarningOutline } from 'react-icons/io5'; +import { Address } from 'viem'; +import { + detectFeedVendor, + getTruncatedAssetName, + PriceFeedVendors, + OracleVendorIcons, +} from '@/utils/oracle'; +import { OracleFeed } from '@/utils/types'; +import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip'; +import { CompoundFeedTooltip } from './CompoundFeedTooltip'; +import { GeneralFeedTooltip } from './GeneralFeedTooltip'; +import { UnknownFeedTooltip } from './UnknownFeedTooltip'; type FeedEntryProps = { - feed: OracleFeed | null - chainId: number -} + feed: OracleFeed | null; + chainId: number; +}; export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null { - if (!feed) return null - - const chainlinkFeedData = useMemo(() => { - if (!feed?.address) return undefined - return getChainlinkOracle(chainId, feed.address as Address) - }, [chainId, feed.address]) + // Use centralized feed detection - moved before early return to avoid conditional hook calls + const feedVendorResult = useMemo(() => { + if (!feed?.address) return null; + return detectFeedVendor(feed.address as Address, chainId); + }, [feed?.address, chainId, feed?.pair]); - const compoundFeedData = useMemo(() => { - if (!feed?.address) return undefined - return getCompoundFeed(feed.address as Address) - }, [feed.address]) + if (!feed) return null; - const truncateAsset = (asset: string) => asset.length > 5 ? asset.slice(0, 5) : asset - - // Determine asset names based on feed type - const getAssetNames = () => { - if (compoundFeedData) { - return { - fromAsset: truncateAsset(compoundFeedData.base), - toAsset: truncateAsset(compoundFeedData.quote) - } - } - return { - fromAsset: truncateAsset(feed.pair?.[0] ?? chainlinkFeedData?.baseAsset ?? 'Unknown'), - toAsset: truncateAsset(feed.pair?.[1] ?? chainlinkFeedData?.quoteAsset ?? 'Unknown') - } - } + if (!feedVendorResult) return null; - const { fromAsset, toAsset } = getAssetNames() + const { vendor, data, assetPair } = feedVendorResult; + const { fromAsset, toAsset } = { + fromAsset: getTruncatedAssetName(assetPair.fromAsset), + toAsset: getTruncatedAssetName(assetPair.toAsset), + }; - const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors] - const isChainlink = isChainlinkOracle(chainId, feed.address as Address) - const isCompound = isCompoundFeed(feed.address as Address) - const isSVR = chainlinkFeedData?.isSVR ?? false + const vendorIcon = OracleVendorIcons[vendor]; + const isChainlink = vendor === PriceFeedVendors.Chainlink; + const isCompound = vendor === PriceFeedVendors.Compound; + // Type-safe SVR check using discriminated union + const isSVR = vendor === PriceFeedVendors.Chainlink && data?.isSVR; const getTooltipContent = () => { - if (isCompound && compoundFeedData) { - return - } - - if (isChainlink && chainlinkFeedData) { - return + // Use discriminated union for type-safe tooltip selection + switch (vendor) { + case PriceFeedVendors.Chainlink: + return ; + + case PriceFeedVendors.Compound: + return ; + + case PriceFeedVendors.Redstone: + case PriceFeedVendors.PythNetwork: + case PriceFeedVendors.Oval: + case PriceFeedVendors.Lido: + return ; + + case PriceFeedVendors.Unknown: + // For unknown feeds, check if we have general feed data or fallback to unknown + if (data) { + return ; + } + return ; + + default: + return ; } - - // Default fallback for unknown/unsupported feeds - return - } + }; return ( -
    +
    {fromAsset} {toAsset}
    - +
    {isSVR && ( SVR )} - + {(isChainlink || isCompound) && vendorIcon ? ( {feed.vendor ) : ( @@ -96,5 +101,5 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null
    - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/GeneralFeedTooltip.tsx b/src/components/MarketOracle/GeneralFeedTooltip.tsx new file mode 100644 index 00000000..2053d4d5 --- /dev/null +++ b/src/components/MarketOracle/GeneralFeedTooltip.tsx @@ -0,0 +1,119 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import { Address } from 'viem'; +import { Badge } from '@/components/common/Badge'; +import { GeneralPriceFeed } from '@/constants/oracle/general-feeds'; +import etherscanLogo from '@/imgs/etherscan.png'; +import { getExplorerURL } from '@/utils/external'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; +import { OracleFeed } from '@/utils/types'; + +type GeneralFeedTooltipProps = { + feed: OracleFeed; + feedData: GeneralPriceFeed; + chainId: number; +}; + +export function GeneralFeedTooltip({ feed, feedData, chainId }: GeneralFeedTooltipProps) { + const [baseAsset, quoteAsset] = feedData.pair; + + const vendorIcon = + OracleVendorIcons[feedData.vendor as PriceFeedVendors] || + OracleVendorIcons[PriceFeedVendors.Unknown]; + + // Get vendor badge variant based on vendor type + const getVendorBadge = (vendor: string) => { + const variantMap = { + redstone: 'danger' as const, + 'pyth network': 'primary' as const, + pyth: 'primary' as const, + oval: 'warning' as const, + lido: 'success' as const, + pendle: 'secondary' as const, + }; + + const variant = variantMap[vendor.toLowerCase() as keyof typeof variantMap] || 'primary'; + + return ( + + {vendor.toUpperCase()} + + ); + }; + + return ( +
    +
    + {/* Header with icon and title */} +
    + {vendorIcon && ( +
    + {feedData.vendor} +
    + )} +
    Price Feed Details
    +
    + + {/* Feed pair name with vendor badge */} +
    +
    + {baseAsset} / {quoteAsset} +
    + {getVendorBadge(feedData.vendor)} +
    + + {/* Feed Details */} +
    +
    + Vendor: + {feedData.vendor} +
    +
    + Decimals: + {feedData.decimals} +
    +
    + Chain ID: + {feedData.chainId} +
    +
    + + {/* Description */} + {feedData.description && ( +
    +
    + Description: +
    +
    + {feedData.description} +
    +
    + )} + + {/* External Links */} +
    +
    + View on: +
    +
    + + Etherscan + Etherscan + +
    +
    +
    +
    + ); +} diff --git a/src/components/MarketOracle/MarketOracleFeedInfo.tsx b/src/components/MarketOracle/MarketOracleFeedInfo.tsx index 6287889d..cc1f913b 100644 --- a/src/components/MarketOracle/MarketOracleFeedInfo.tsx +++ b/src/components/MarketOracle/MarketOracleFeedInfo.tsx @@ -1,13 +1,13 @@ -import { OracleFeed } from '@/utils/types' -import { FeedEntry } from './FeedEntry' +import { OracleFeed } from '@/utils/types'; +import { FeedEntry } from './FeedEntry'; type MarketOracleFeedInfoProps = { - baseFeedOne: OracleFeed | null | undefined - baseFeedTwo: OracleFeed | null | undefined - quoteFeedOne: OracleFeed | null | undefined - quoteFeedTwo: OracleFeed | null | undefined - chainId: number -} + baseFeedOne: OracleFeed | null | undefined; + baseFeedTwo: OracleFeed | null | undefined; + quoteFeedOne: OracleFeed | null | undefined; + quoteFeedTwo: OracleFeed | null | undefined; + chainId: number; +}; export function MarketOracleFeedInfo({ baseFeedOne, @@ -16,30 +16,30 @@ export function MarketOracleFeedInfo({ quoteFeedTwo, chainId, }: MarketOracleFeedInfoProps): JSX.Element { - const hasAnyFeed = baseFeedOne || baseFeedTwo || quoteFeedOne || quoteFeedTwo + const hasAnyFeed = baseFeedOne || baseFeedTwo || quoteFeedOne || quoteFeedTwo; if (!hasAnyFeed) { return (
    No feed routes available
    - ) + ); } - const EmptyFeedSlot = () => ( -
    + function EmptyFeedSlot() { + return
    --
    - ) +} - const renderFeed = (feed: OracleFeed | null | undefined) => + const renderFeed = (feed: OracleFeed | null | undefined) => feed ? (
    ) : ( - ) + ); return (
    @@ -52,7 +52,7 @@ export function MarketOracleFeedInfo({
    )} - + {(quoteFeedOne || quoteFeedTwo) && (
    Quote Feeds: @@ -63,5 +63,5 @@ export function MarketOracleFeedInfo({
    )}
    - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index 90296d17..f7122a3c 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -1,40 +1,41 @@ -import { getOracleType, getOracleTypeDescription, OracleType } from '@/utils/oracle' -import { MarketOracleFeedInfo } from '@/components/MarketOracle' -import { MorphoChainlinkOracleData } from '@/utils/types' +import { MarketOracleFeedInfo } from '@/components/MarketOracle'; +import { getOracleType, getOracleTypeDescription, OracleType } from '@/utils/oracle'; +import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleTypeInfoProps = { - oracleData: MorphoChainlinkOracleData | null | undefined - oracleAddress: string - chainId: number -} + oracleData: MorphoChainlinkOracleData | null | undefined; + oracleAddress: string; + chainId: number; +}; export function OracleTypeInfo({ oracleData, oracleAddress, chainId }: OracleTypeInfoProps) { - const oracleType = getOracleType(oracleData) - const typeDescription = getOracleTypeDescription(oracleType) - + const oracleType = getOracleType(oracleData); + const typeDescription = getOracleTypeDescription(oracleType); + return ( <>
    Oracle Type: {oracleType}
    - - {oracleType === OracleType.Standard ? () : ( + + {oracleType === OracleType.Standard ? ( + + ) : (
    -
    - {typeDescription} -
    +
    {typeDescription}
    - This market uses a custom oracle implementation that doesn't follow the standard Morpho feed structure. + This market uses a custom oracle implementation that doesn't follow the standard Morpho + feed structure.
    )} - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx index 7b757c0d..c365738f 100644 --- a/src/components/MarketOracle/UnknownFeedTooltip.tsx +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -1,25 +1,25 @@ -import Image from 'next/image' -import Link from 'next/link' -import { Address } from 'viem' -import { getExplorerURL } from '@/utils/external' -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle' -import { OracleFeed } from '@/utils/types' -import { getSlicedAddress } from '@/utils/address' -import etherscanLogo from '@/imgs/etherscan.png' +import Image from 'next/image'; +import Link from 'next/link'; +import { Address } from 'viem'; +import etherscanLogo from '@/imgs/etherscan.png'; +import { getSlicedAddress } from '@/utils/address'; +import { getExplorerURL } from '@/utils/external'; +import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; +import { OracleFeed } from '@/utils/types'; type UnknownFeedTooltipProps = { - feed: OracleFeed - chainId: number -} + feed: OracleFeed; + chainId: number; +}; export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { - const baseAsset = feed.pair?.[0] ?? 'Unknown' - const quoteAsset = feed.pair?.[1] ?? 'Unknown' - - const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors] - + const baseAsset = feed.pair?.[0] ?? 'Unknown'; + const quoteAsset = feed.pair?.[1] ?? 'Unknown'; + + const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors]; + return ( -
    +
    {/* Header with icon and title */}
    @@ -28,8 +28,8 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { {feed.vendor
    ) : ( -
    - ? +
    + ?
    )}
    Oracle Feed Details
    @@ -50,19 +50,21 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) {
    Address: - {getSlicedAddress(feed.address as Address)} + + {getSlicedAddress(feed.address as Address)} +
    {feed.description && ( -
    +
    Description: - {feed.description} + {feed.description}
    )}
    {/* External Links */}
    -
    +
    View on:
    @@ -70,14 +72,20 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { href={getExplorerURL(feed.address as Address, chainId)} target="_blank" rel="noopener noreferrer" - className="flex items-center gap-1 rounded-sm bg-hovered px-3 py-2 text-xs font-medium text-primary hover:bg-opacity-80 transition-all duration-200 no-underline" + className="bg-hovered flex items-center gap-1 rounded-sm px-3 py-2 text-xs font-medium text-primary no-underline transition-all duration-200 hover:bg-opacity-80" > - Etherscan + Etherscan Etherscan
    - ) -} \ No newline at end of file + ); +} diff --git a/src/components/MarketOracle/index.ts b/src/components/MarketOracle/index.ts index 40db8c02..acf67ca1 100644 --- a/src/components/MarketOracle/index.ts +++ b/src/components/MarketOracle/index.ts @@ -1,4 +1,4 @@ -export { FeedEntry } from './FeedEntry' -export { MarketOracleFeedInfo } from './MarketOracleFeedInfo' -export { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip' -export { OracleTypeInfo } from './OracleTypeInfo' \ No newline at end of file +export { FeedEntry } from './FeedEntry'; +export { MarketOracleFeedInfo } from './MarketOracleFeedInfo'; +export { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip'; +export { OracleTypeInfo } from './OracleTypeInfo'; diff --git a/src/components/TooltipContent.tsx b/src/components/TooltipContent.tsx index 65e5f1c4..869dd2f6 100644 --- a/src/components/TooltipContent.tsx +++ b/src/components/TooltipContent.tsx @@ -13,7 +13,7 @@ export function TooltipContent({ icon, title, detail, className = '' }: TooltipC // Simple tooltip with just an icon and title if (!detail) { return ( -
    +
    {icon &&
    {icon}
    } {title}
    @@ -22,7 +22,7 @@ export function TooltipContent({ icon, title, detail, className = '' }: TooltipC // Complex tooltip with additional details return ( -
    +
    {icon &&
    {icon}
    }
    diff --git a/src/components/layout/header/Navbar.tsx b/src/components/layout/header/Navbar.tsx index 85e7db22..c96edd20 100644 --- a/src/components/layout/header/Navbar.tsx +++ b/src/components/layout/header/Navbar.tsx @@ -102,11 +102,7 @@ export function Navbar() { )} - +
    diff --git a/app/markets/components/MarketTableBody.tsx b/app/markets/components/MarketTableBody.tsx index f60b679c..9dfaa8ae 100644 --- a/app/markets/components/MarketTableBody.tsx +++ b/app/markets/components/MarketTableBody.tsx @@ -13,6 +13,7 @@ import logo from '../../../imgs/logo.png'; import { ExpandedMarketDetail } from './MarketRowDetail'; import { TDAsset, TDTotalSupplyOrBorrow } from './MarketTableUtils'; import { MarketAssetIndicator, MarketOracleIndicator, MarketDebtIndicator } from './RiskIndicator'; +import { IoGitMerge } from 'react-icons/io5'; type MarketTableBodyProps = { currentEntries: Market[]; @@ -103,7 +104,7 @@ export function MarketTableBody({ />
    - +
    diff --git a/app/markets/components/OracleFilter.tsx b/app/markets/components/OracleFilter.tsx index 5312805f..e8d3cd31 100644 --- a/app/markets/components/OracleFilter.tsx +++ b/app/markets/components/OracleFilter.tsx @@ -67,6 +67,7 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or } showText={false} useTooltip={false} + chainId={1} /> ))}
    diff --git a/app/markets/components/markets.tsx b/app/markets/components/markets.tsx index 4b7ba9ca..fe1c6707 100644 --- a/app/markets/components/markets.tsx +++ b/app/markets/components/markets.tsx @@ -208,7 +208,7 @@ export default function Markets({ ).filter((market) => { if (!searchQuery) return true; // If no search query, show all markets const lowercaseQuery = searchQuery.toLowerCase(); - const { vendors } = parsePriceFeedVendors(market.oracle?.data); + const { vendors } = parsePriceFeedVendors(market.oracle?.data, market.morphoBlue.chain.id); const vendorsName = vendors.join(','); return ( market.uniqueKey.toLowerCase().includes(lowercaseQuery) || diff --git a/app/markets/components/utils.ts b/app/markets/components/utils.ts index ebc3c565..199e4ce4 100644 --- a/app/markets/components/utils.ts +++ b/app/markets/components/utils.ts @@ -91,7 +91,7 @@ export function applyFilterAndSort( if ( !showUnknownOracle && - (!market.oracle || parsePriceFeedVendors(market.oracle.data).isUnknown) + (!market.oracle || parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id)) ) { return false; } @@ -105,7 +105,7 @@ export function applyFilterAndSort( } if (selectedOracles.length > 0 && !!market.oracle) { - const marketOracles = parsePriceFeedVendors(market.oracle.data).vendors; + const marketOracles = parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id).vendors; if (!marketOracles.some((oracle) => selectedOracles.includes(oracle))) { return false; } diff --git a/app/positions/components/SuppliedMarketsDetail.tsx b/app/positions/components/SuppliedMarketsDetail.tsx index e53b5537..9190a4e2 100644 --- a/app/positions/components/SuppliedMarketsDetail.tsx +++ b/app/positions/components/SuppliedMarketsDetail.tsx @@ -114,6 +114,7 @@ function MarketRow({
    diff --git a/app/positions/components/onboarding/RiskSelection.tsx b/app/positions/components/onboarding/RiskSelection.tsx index 75d4f349..e775e91b 100644 --- a/app/positions/components/onboarding/RiskSelection.tsx +++ b/app/positions/components/onboarding/RiskSelection.tsx @@ -63,7 +63,7 @@ export function RiskSelection() { // Check if oracle is selected (if any are selected) if (selectedOracles.length > 0) { - const { vendors } = parsePriceFeedVendors(market.oracle?.data); + const { vendors } = parsePriceFeedVendors(market.oracle?.data, market.morphoBlue.chain.id); // if vendors is empty, push "unknown oracle" into list that needed to be selected if (vendors.length === 0) { diff --git a/app/positions/report/components/ReportTable.tsx b/app/positions/report/components/ReportTable.tsx index c6ea4718..d444c936 100644 --- a/app/positions/report/components/ReportTable.tsx +++ b/app/positions/report/components/ReportTable.tsx @@ -94,7 +94,7 @@ function MarketSummaryBlock({
    Oracle: - +
    diff --git a/src/components/OracleVendorBadge.tsx b/src/components/OracleVendorBadge.tsx index 54800386..d13c79aa 100644 --- a/src/components/OracleVendorBadge.tsx +++ b/src/components/OracleVendorBadge.tsx @@ -7,6 +7,7 @@ import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleVendorBadgeProps = { oracleData: MorphoChainlinkOracleData | null | undefined; + chainId: number; useTooltip?: boolean; showText?: boolean; }; @@ -20,19 +21,20 @@ const renderVendorIcon = (vendor: PriceFeedVendors) => function OracleVendorBadge({ oracleData, + chainId, showText = false, useTooltip = true, }: OracleVendorBadgeProps) { - const { vendors, isUnknown } = parsePriceFeedVendors(oracleData); + const { vendors, hasUnknown } = parsePriceFeedVendors(oracleData, chainId); const content = (
    {showText && ( - {isUnknown ? 'Unknown' : vendors.join(', ')} + {hasUnknown ? 'Unknown' : vendors.join(', ')} )} - {isUnknown ? ( + {hasUnknown ? ( ) : ( vendors.map((vendor, index) => ( @@ -48,7 +50,7 @@ function OracleVendorBadge({ content={

    - {isUnknown ? 'Unknown Oracle' : 'Oracle Vendors:'} + {hasUnknown ? 'Unknown Oracle' : 'Oracle Vendors:'}

      {vendors.map((vendor, index) => ( diff --git a/src/components/common/MarketDetailsBlock.tsx b/src/components/common/MarketDetailsBlock.tsx index 37dcde08..c2f4636f 100644 --- a/src/components/common/MarketDetailsBlock.tsx +++ b/src/components/common/MarketDetailsBlock.tsx @@ -85,7 +85,7 @@ export function MarketDetailsBlock({ {!isExpanded && (
      · - + · {getAPY()}% APY · @@ -116,6 +116,7 @@ export function MarketDetailsBlock({ oracleData={market.oracle?.data} showText useTooltip={false} + chainId={market.morphoBlue.chain.id} /> · {getIRMTitle(market.irmAddress)} diff --git a/src/components/common/MarketInfoBlock.tsx b/src/components/common/MarketInfoBlock.tsx index 7f162585..3d0c65c7 100644 --- a/src/components/common/MarketInfoBlock.tsx +++ b/src/components/common/MarketInfoBlock.tsx @@ -39,7 +39,7 @@ export function MarketInfoBlock({ market, amount, className }: MarketInfoBlockPr {formatBalance(amount, market.loanAsset.decimals)} {market.loanAsset.symbol} ) : ( - + )}
    @@ -130,7 +130,7 @@ export function MarketInfoBlockCompact({ {formatBalance(amount, market.loanAsset.decimals)} {market.loanAsset.symbol} ) : ( - + )}
    ); diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index 19789ddb..1fbac06d 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -11,7 +11,7 @@ import { MorphoChainlinkOracleData, OracleFeed } from './types'; type VendorInfo = { vendors: PriceFeedVendors[]; - isUnknown: boolean; + hasUnknown: boolean; }; export enum OracleType { @@ -69,8 +69,10 @@ export function getOracleType( export function parsePriceFeedVendors( oracleData: MorphoChainlinkOracleData | null | undefined, + chainId: number, ): VendorInfo { - if (!oracleData) return { vendors: [], isUnknown: false }; + + if (!oracleData) return { vendors: [], hasUnknown: false }; if ( !oracleData.baseFeedOne && @@ -78,7 +80,7 @@ export function parsePriceFeedVendors( !oracleData.quoteFeedOne && !oracleData.quoteFeedTwo ) - return { vendors: [], isUnknown: true }; + return { vendors: [], hasUnknown: true }; const feeds = [ oracleData.baseFeedOne, @@ -87,20 +89,25 @@ export function parsePriceFeedVendors( oracleData.quoteFeedTwo, ]; - const vendors = new Set( - feeds - .filter((feed) => feed?.vendor) - .map( - (feed) => - Object.values(PriceFeedVendors).find( - (v) => v.toLowerCase() === feed!.vendor!.toLowerCase(), - ) ?? PriceFeedVendors.Unknown, - ), - ); + const vendors = new Set(); + let hasUnknown = false; + + for (const feed of feeds) { + if (feed?.address) { + const feedResult = detectFeedVendor(feed.address, chainId); + vendors.add(feedResult.vendor); + if (feedResult.vendor === PriceFeedVendors.Unknown) { + hasUnknown = true; + } + } + } + // If we have no feeds with addresses, that should be considered as having unknown feeds + const hasFeeds = feeds.some(feed => feed?.address); + return { vendors: Array.from(vendors), - isUnknown: vendors.has(PriceFeedVendors.Unknown) || vendors.size === 0, + hasUnknown: hasUnknown || !hasFeeds, }; } diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 37aaf356..a1ce2337 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -1,6 +1,6 @@ import { MarketWarning, MorphoChainlinkOracleData } from '@/utils/types'; import { monarchWhitelistedMarkets } from './markets'; -import { getOracleType, OracleType } from './oracle'; +import { getOracleType, OracleType, parsePriceFeedVendors } from './oracle'; import { WarningCategory, WarningWithDetail } from './types'; // Subgraph Warnings @@ -196,5 +196,13 @@ export const getMarketWarningsWithDetail = ( ); if (oracleType === OracleType.Custom) result.push(UNRECOGNIZED_ORACLE); + // if any of the feeds are not null but also not recognized, return feed warning + if (market.oracle?.data) { + const vendorInfo = parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id); + if (vendorInfo.hasUnknown) { + result.push(UNRECOGNIZED_FEEDS); + } + } + return result; }; From c5395dc92e0a81d6257d72eec36ff1b9c5e0f5da Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 15:31:35 +0800 Subject: [PATCH 11/19] feat: filter and separation of unknown oracle and unknown feeds --- app/markets/components/OracleFilter.tsx | 33 +++++------ src/components/MarketOracle/FeedEntry.tsx | 2 + src/components/OracleVendorBadge.tsx | 67 +++++++++++++++++------ src/utils/warnings.ts | 2 +- 4 files changed, 70 insertions(+), 34 deletions(-) diff --git a/app/markets/components/OracleFilter.tsx b/app/markets/components/OracleFilter.tsx index e8d3cd31..561c7cc8 100644 --- a/app/markets/components/OracleFilter.tsx +++ b/app/markets/components/OracleFilter.tsx @@ -1,10 +1,8 @@ import { useState, useRef, useEffect } from 'react'; import { ChevronDownIcon } from '@radix-ui/react-icons'; import Image from 'next/image'; -import { FaQuestionCircle } from 'react-icons/fa'; -import OracleVendorBadge from '@/components/OracleVendorBadge'; +import { IoHelpCircleOutline } from 'react-icons/io5'; import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; -import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleFilterProps = { selectedOracles: PriceFeedVendors[]; @@ -58,17 +56,20 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or Oracle
    {selectedOracles.length > 0 ? ( -
    - {selectedOracles.map((oracle) => ( - +
    + {selectedOracles.map((oracle, index) => ( +
    + {OracleVendorIcons[oracle] ? ( + {oracle} + ) : ( + + )} +
    ))}
    ) : ( @@ -111,9 +112,9 @@ export default function OracleFilter({ selectedOracles, setSelectedOracles }: Or className="rounded-full" /> ) : ( - + )} - {oracle} + {oracle === PriceFeedVendors.Unknown ? 'Unknown Feed' : oracle}
  • ))} diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index d07e97e4..49ed641d 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -32,6 +32,8 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null if (!feedVendorResult) return null; + console.log('feedVendorResult', feedVendorResult) + const { vendor, data, assetPair } = feedVendorResult; const { fromAsset, toAsset } = { fromAsset: getTruncatedAssetName(assetPair.fromAsset), diff --git a/src/components/OracleVendorBadge.tsx b/src/components/OracleVendorBadge.tsx index d13c79aa..bfb33671 100644 --- a/src/components/OracleVendorBadge.tsx +++ b/src/components/OracleVendorBadge.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Tooltip } from '@heroui/react'; import Image from 'next/image'; -import { IoWarningOutline } from 'react-icons/io5'; -import { OracleVendorIcons, PriceFeedVendors, parsePriceFeedVendors } from '@/utils/oracle'; +import { IoWarningOutline, IoHelpCircleOutline } from 'react-icons/io5'; +import { OracleType, OracleVendorIcons, PriceFeedVendors, getOracleType, parsePriceFeedVendors } from '@/utils/oracle'; import { MorphoChainlinkOracleData } from '@/utils/types'; type OracleVendorBadgeProps = { @@ -16,15 +16,24 @@ const renderVendorIcon = (vendor: PriceFeedVendors) => OracleVendorIcons[vendor] ? ( {vendor} ) : ( - + ); +/** + * IoWarningOutline: Unknown Oracles + * IoHelpCircleOutline: For unknown feeds + */ + function OracleVendorBadge({ oracleData, chainId, showText = false, useTooltip = true, }: OracleVendorBadgeProps) { + + // check whether it's standard oracle or not. + const isCustom = getOracleType(oracleData) === OracleType.Custom + const { vendors, hasUnknown } = parsePriceFeedVendors(oracleData, chainId); const content = ( @@ -34,7 +43,7 @@ function OracleVendorBadge({ {hasUnknown ? 'Unknown' : vendors.join(', ')} )} - {hasUnknown ? ( + {isCustom ? ( ) : ( vendors.map((vendor, index) => ( @@ -45,22 +54,46 @@ function OracleVendorBadge({ ); if (useTooltip) { - return ( - { + if (isCustom) { + return (
    -

    - {hasUnknown ? 'Unknown Oracle' : 'Oracle Vendors:'} -

    -
      - {vendors.map((vendor, index) => ( -
    • - {vendor} -
    • - ))} -
    +

    Custom Oracle

    +

    Uses an unrecognized oracle contract.

    + ); + } + + if (hasUnknown) { + const knownVendors = vendors.filter(v => v !== PriceFeedVendors.Unknown); + const unknownCount = vendors.filter(v => v === PriceFeedVendors.Unknown).length; + + let description = ''; + if (knownVendors.length > 0) { + description = `Uses feeds from ${knownVendors.join(', ')}, plus ${unknownCount} unknown feed${unknownCount > 1 ? 's' : ''}.`; + } else { + description = `Uses ${unknownCount} unknown feed${unknownCount > 1 ? 's' : ''} only.`; } + + return ( +
    +

    Standard Oracle

    +

    {description}

    +
    + ); + } + + return ( +
    +

    Standard Oracle

    +

    Uses feeds from {vendors.join(', ')}.

    +
    + ); + }; + + return ( + {content} diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index a1ce2337..4866a351 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -197,7 +197,7 @@ export const getMarketWarningsWithDetail = ( if (oracleType === OracleType.Custom) result.push(UNRECOGNIZED_ORACLE); // if any of the feeds are not null but also not recognized, return feed warning - if (market.oracle?.data) { + if (oracleType === OracleType.Standard && market.oracle?.data) { const vendorInfo = parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id); if (vendorInfo.hasUnknown) { result.push(UNRECOGNIZED_FEEDS); From f2b97d412287a159b3c16232a1b730acacacba29 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 16:56:19 +0800 Subject: [PATCH 12/19] chore: market row oracle info styling --- app/markets/components/MarketRowDetail.tsx | 57 ++------- src/components/FeedInfo/OracleFeedInfo.tsx | 114 ------------------ src/components/MarketOracle/FeedEntry.tsx | 5 +- .../MarketOracle/MarketOracleFeedInfo.tsx | 16 +-- .../MarketOracle/OracleTypeInfo.tsx | 25 +++- .../MarketOracle/UnknownFeedTooltip.tsx | 26 +--- src/utils/types.ts | 2 - 7 files changed, 44 insertions(+), 201 deletions(-) delete mode 100644 src/components/FeedInfo/OracleFeedInfo.tsx diff --git a/app/markets/components/MarketRowDetail.tsx b/app/markets/components/MarketRowDetail.tsx index 7eb6ad28..036c75db 100644 --- a/app/markets/components/MarketRowDetail.tsx +++ b/app/markets/components/MarketRowDetail.tsx @@ -1,66 +1,27 @@ -import { Tooltip } from '@heroui/react'; -import { ExternalLinkIcon, QuestionMarkCircledIcon } from '@radix-ui/react-icons'; -import { OracleFeedInfo } from '@/components/FeedInfo/OracleFeedInfo'; import { Info } from '@/components/Info/info'; -import OracleVendorBadge from '@/components/OracleVendorBadge'; -import { TooltipContent } from '@/components/TooltipContent'; +import { OracleTypeInfo } from '@/components/MarketOracle'; import { useMarketWarnings } from '@/hooks/useMarketWarnings'; import { formatReadable } from '@/utils/balance'; -import { getExplorerURL } from '@/utils/external'; import { Market } from '@/utils/types'; export function ExpandedMarketDetail({ market }: { market: Market }) { const oracleData = market.oracle ? market.oracle.data : null; const warningsWithDetail = useMarketWarnings(market, true); - const hasFeeds = - oracleData && - (oracleData.baseFeedOne || - oracleData.baseFeedTwo || - oracleData.quoteFeedOne || - oracleData.quoteFeedTwo); - return (
    - {/* Oracle info */}

    Oracle Info

    -
    -

    Vendors:

    - - - - -
    - {hasFeeds && ( -
    -
    -

    Feed Routes:

    - } - title="Feed Routes" - detail="Feed routes show how asset prices are derived from different oracle providers" - /> - } - className="max-w-[400px] rounded-sm p-2" - > - - -
    - - - - -
    - )} + + {/* contains: Oracle Info: Standard (Custom...etc) */} +
    {/* market info */} diff --git a/src/components/FeedInfo/OracleFeedInfo.tsx b/src/components/FeedInfo/OracleFeedInfo.tsx deleted file mode 100644 index d23131c1..00000000 --- a/src/components/FeedInfo/OracleFeedInfo.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { useMemo } from 'react'; -import { Tooltip } from '@heroui/react'; -import { ExternalLinkIcon } from '@radix-ui/react-icons'; -import Image from 'next/image'; -import Link from 'next/link'; -import { IoIosSwap } from 'react-icons/io'; -import { IoWarningOutline } from 'react-icons/io5'; -import { Address } from 'viem'; -import { ChainlinkFeedTooltip } from '@/components/MarketOracle/ChainlinkFeedTooltip'; -import { CompoundFeedTooltip } from '@/components/MarketOracle/CompoundFeedTooltip'; -import { GeneralFeedTooltip } from '@/components/MarketOracle/GeneralFeedTooltip'; -import { TooltipContent } from '@/components/TooltipContent'; -import { getSlicedAddress } from '@/utils/address'; -import { getExplorerURL } from '@/utils/external'; -import { detectFeedVendor, PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; -import { OracleFeed } from '@/utils/types'; - -export function OracleFeedInfo({ - feed, - chainId, -}: { - feed: OracleFeed | null; - chainId: number; -}): JSX.Element | null { - // Use centralized feed detection - moved before early return to avoid conditional hook calls - const feedVendorResult = useMemo(() => { - if (!feed?.address) return null; - return detectFeedVendor(feed.address as Address, chainId); - }, [feed?.address, chainId, feed?.pair]); - - if (!feed) return null; - - if (!feedVendorResult) return null; - - const { vendor, data, assetPair } = feedVendorResult; - const { fromAsset, toAsset } = assetPair; - - const vendorIcon = OracleVendorIcons[vendor] ?? OracleVendorIcons[PriceFeedVendors.Unknown]; - - const content = ( -
    -
    - {fromAsset} - - {toAsset} -
    - {vendorIcon ? ( - {feed.vendor - ) : ( - - )} -
    - ); - - const getTooltipContent = () => { - // Use discriminated union for type-safe tooltip selection - switch (vendor) { - case PriceFeedVendors.Chainlink: - return ; - - case PriceFeedVendors.Compound: - return ; - - case PriceFeedVendors.Redstone: - case PriceFeedVendors.PythNetwork: - case PriceFeedVendors.Oval: - case PriceFeedVendors.Lido: - return ; - - case PriceFeedVendors.Unknown: - // For unknown feeds, check if we have general feed data or fallback to default - if (data) { - return ; - } - return ( - - ); - - default: - return ( - - ); - } - }; - - return ( - - - {content} - - - - ); -} diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index 49ed641d..7fda9395 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -28,11 +28,12 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null return detectFeedVendor(feed.address as Address, chainId); }, [feed?.address, chainId, feed?.pair]); + console.log('feedVendorResult', feedVendorResult) + if (!feed) return null; if (!feedVendorResult) return null; - console.log('feedVendorResult', feedVendorResult) const { vendor, data, assetPair } = feedVendorResult; const { fromAsset, toAsset } = { @@ -96,7 +97,7 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null )} {(isChainlink || isCompound) && vendorIcon ? ( - {feed.vendor + {'Oracle'} ) : ( )} diff --git a/src/components/MarketOracle/MarketOracleFeedInfo.tsx b/src/components/MarketOracle/MarketOracleFeedInfo.tsx index cc1f913b..b03f6184 100644 --- a/src/components/MarketOracle/MarketOracleFeedInfo.tsx +++ b/src/components/MarketOracle/MarketOracleFeedInfo.tsx @@ -9,6 +9,12 @@ type MarketOracleFeedInfoProps = { chainId: number; }; +function EmptyFeedSlot() { + return
    + -- +
    +} + export function MarketOracleFeedInfo({ baseFeedOne, baseFeedTwo, @@ -26,12 +32,6 @@ export function MarketOracleFeedInfo({ ); } - function EmptyFeedSlot() { - return
    - -- -
    -} - const renderFeed = (feed: OracleFeed | null | undefined) => feed ? (
    @@ -45,7 +45,7 @@ export function MarketOracleFeedInfo({
    {(baseFeedOne || baseFeedTwo) && (
    - Base Feeds: + Base:
    {renderFeed(baseFeedOne)}
    {renderFeed(baseFeedTwo)}
    @@ -55,7 +55,7 @@ export function MarketOracleFeedInfo({ {(quoteFeedOne || quoteFeedTwo) && (
    - Quote Feeds: + Quote:
    {renderFeed(quoteFeedOne)}
    {renderFeed(quoteFeedTwo)}
    diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index f7122a3c..8787364d 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -1,22 +1,39 @@ import { MarketOracleFeedInfo } from '@/components/MarketOracle'; +import { getExplorerURL } from '@/utils/external'; import { getOracleType, getOracleTypeDescription, OracleType } from '@/utils/oracle'; import { MorphoChainlinkOracleData } from '@/utils/types'; +import Link from 'next/link'; +import { FiExternalLink } from 'react-icons/fi'; type OracleTypeInfoProps = { oracleData: MorphoChainlinkOracleData | null | undefined; oracleAddress: string; chainId: number; + showLink?: boolean; }; -export function OracleTypeInfo({ oracleData, oracleAddress, chainId }: OracleTypeInfoProps) { +export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink }: OracleTypeInfoProps) { const oracleType = getOracleType(oracleData); const typeDescription = getOracleTypeDescription(oracleType); return ( <> -
    +
    Oracle Type: - {oracleType} + { + showLink ? ( + ( + {oracleType} + + ) + ): + ({oracleType}) + }
    {oracleType === OracleType.Standard ? ( @@ -31,7 +48,7 @@ export function OracleTypeInfo({ oracleData, oracleAddress, chainId }: OracleTyp
    {typeDescription}
    - This market uses a custom oracle implementation that doesn't follow the standard Morpho + This market uses a custom oracle implementation that doesn't follow the standard feed structure.
    diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx index c365738f..eb27b906 100644 --- a/src/components/MarketOracle/UnknownFeedTooltip.tsx +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -1,10 +1,10 @@ import Image from 'next/image'; import Link from 'next/link'; import { Address } from 'viem'; +import { IoHelpCircleOutline } from 'react-icons/io5'; import etherscanLogo from '@/imgs/etherscan.png'; import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; -import { PriceFeedVendors, OracleVendorIcons } from '@/utils/oracle'; import { OracleFeed } from '@/utils/types'; type UnknownFeedTooltipProps = { @@ -16,23 +16,13 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { const baseAsset = feed.pair?.[0] ?? 'Unknown'; const quoteAsset = feed.pair?.[1] ?? 'Unknown'; - const vendorIcon = OracleVendorIcons[feed.vendor as PriceFeedVendors]; - return (
    {/* Header with icon and title */}
    - {vendorIcon ? ( -
    - {feed.vendor -
    - ) : ( -
    - ? -
    - )} -
    Oracle Feed Details
    + +
    Unknown Feed Details
    {/* Feed pair name */} @@ -44,22 +34,12 @@ export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { {/* Oracle Information */}
    -
    - Provider: - {feed.vendor ?? 'Unknown'} -
    Address: {getSlicedAddress(feed.address as Address)}
    - {feed.description && ( -
    - Description: - {feed.description} -
    - )}
    {/* External Links */} diff --git a/src/utils/types.ts b/src/utils/types.ts index c149ddf4..a2a907a9 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -245,10 +245,8 @@ export type OracleFeed = { chain: { id: number; }; - description: string | null; id: string; pair: string[] | null; - vendor: string | null; }; export type MorphoChainlinkOracleData = { From 8bf5a18e156344606dc466f8991934a9bac1a451 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 18:33:49 +0800 Subject: [PATCH 13/19] feat: tier system on oracles --- .../[marketid]/components/PositionStats.tsx | 2 + app/market/[chainId]/[marketid]/content.tsx | 1 + app/markets/components/MarketRowDetail.tsx | 1 + src/components/MarketOracle/FeedEntry.tsx | 33 +++++---- .../MarketOracle/GeneralFeedTooltip.tsx | 29 -------- .../MarketOracle/OracleTypeInfo.tsx | 7 +- .../MarketOracle/UnknownFeedTooltip.tsx | 27 ++------ src/components/OracleVendorBadge.tsx | 42 ++++++++--- src/components/TokenIcon.tsx | 6 +- src/utils/oracle.ts | 69 ++++++++++++++++--- src/utils/warnings.ts | 22 +++++- 11 files changed, 147 insertions(+), 92 deletions(-) diff --git a/app/market/[chainId]/[marketid]/components/PositionStats.tsx b/app/market/[chainId]/[marketid]/components/PositionStats.tsx index 22175426..9517a40b 100644 --- a/app/market/[chainId]/[marketid]/components/PositionStats.tsx +++ b/app/market/[chainId]/[marketid]/components/PositionStats.tsx @@ -66,6 +66,7 @@ export function PositionStats({ symbol={market.loanAsset.symbol} width={16} height={16} + truncated /> {formatBalance( @@ -85,6 +86,7 @@ export function PositionStats({ symbol={market.loanAsset.symbol} width={16} height={16} + truncated /> {formatBalance( diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index 1d2342a6..1b26ff86 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -284,6 +284,7 @@ function MarketContent() { symbol={market.collateralAsset.symbol} width={20} height={20} + truncated />
    diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index 7fda9395..14765902 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -2,7 +2,7 @@ import { useMemo } from 'react'; import { Tooltip } from '@heroui/react'; import Image from 'next/image'; import { IoIosSwap } from 'react-icons/io'; -import { IoWarningOutline } from 'react-icons/io5'; +import { IoHelpCircleOutline } from 'react-icons/io5'; import { Address } from 'viem'; import { detectFeedVendor, @@ -28,8 +28,6 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null return detectFeedVendor(feed.address as Address, chainId); }, [feed?.address, chainId, feed?.pair]); - console.log('feedVendorResult', feedVendorResult) - if (!feed) return null; if (!feedVendorResult) return null; @@ -40,6 +38,9 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null fromAsset: getTruncatedAssetName(assetPair.fromAsset), toAsset: getTruncatedAssetName(assetPair.toAsset), }; + + // Don't show asset pair if it's unknown + const showAssetPair = !(assetPair.fromAsset === 'Unknown' && assetPair.toAsset === 'Unknown'); const vendorIcon = OracleVendorIcons[vendor]; const isChainlink = vendor === PriceFeedVendors.Chainlink; @@ -83,23 +84,29 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null content={getTooltipContent()} >
    -
    - {fromAsset} - - {toAsset} -
    - -
    + {showAssetPair ? ( +
    + {fromAsset} + + {toAsset} +
    + ) : ( +
    + Unknown Feed +
    + )} + +
    {isSVR && ( - + SVR )} {(isChainlink || isCompound) && vendorIcon ? ( - {'Oracle'} + {'Oracle'} ) : ( - + )}
    diff --git a/src/components/MarketOracle/GeneralFeedTooltip.tsx b/src/components/MarketOracle/GeneralFeedTooltip.tsx index 2053d4d5..a88791f2 100644 --- a/src/components/MarketOracle/GeneralFeedTooltip.tsx +++ b/src/components/MarketOracle/GeneralFeedTooltip.tsx @@ -21,26 +21,6 @@ export function GeneralFeedTooltip({ feed, feedData, chainId }: GeneralFeedToolt OracleVendorIcons[feedData.vendor as PriceFeedVendors] || OracleVendorIcons[PriceFeedVendors.Unknown]; - // Get vendor badge variant based on vendor type - const getVendorBadge = (vendor: string) => { - const variantMap = { - redstone: 'danger' as const, - 'pyth network': 'primary' as const, - pyth: 'primary' as const, - oval: 'warning' as const, - lido: 'success' as const, - pendle: 'secondary' as const, - }; - - const variant = variantMap[vendor.toLowerCase() as keyof typeof variantMap] || 'primary'; - - return ( - - {vendor.toUpperCase()} - - ); - }; - return (
    @@ -59,7 +39,6 @@ export function GeneralFeedTooltip({ feed, feedData, chainId }: GeneralFeedToolt
    {baseAsset} / {quoteAsset}
    - {getVendorBadge(feedData.vendor)}
    {/* Feed Details */} @@ -68,14 +47,6 @@ export function GeneralFeedTooltip({ feed, feedData, chainId }: GeneralFeedToolt Vendor: {feedData.vendor}
    -
    - Decimals: - {feedData.decimals} -
    -
    - Chain ID: - {feedData.chainId} -
    {/* Description */} diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index 8787364d..c0c9ffc6 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -10,9 +10,10 @@ type OracleTypeInfoProps = { oracleAddress: string; chainId: number; showLink?: boolean; + showCustom?: boolean }; -export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink }: OracleTypeInfoProps) { +export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink, showCustom }: OracleTypeInfoProps) { const oracleType = getOracleType(oracleData); const typeDescription = getOracleTypeDescription(oracleType); @@ -44,7 +45,7 @@ export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink }: quoteFeedTwo={oracleData?.quoteFeedTwo} chainId={chainId} /> - ) : ( + ) : showCustom ? (
    {typeDescription}
    @@ -52,7 +53,7 @@ export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink }: feed structure.
    - )} + ) : (<>)} ); } diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx index eb27b906..55b28f80 100644 --- a/src/components/MarketOracle/UnknownFeedTooltip.tsx +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -13,39 +13,24 @@ type UnknownFeedTooltipProps = { }; export function UnknownFeedTooltip({ feed, chainId }: UnknownFeedTooltipProps) { - const baseAsset = feed.pair?.[0] ?? 'Unknown'; - const quoteAsset = feed.pair?.[1] ?? 'Unknown'; - return ( -
    +
    {/* Header with icon and title */}
    -
    Unknown Feed Details
    -
    - - {/* Feed pair name */} -
    -
    - {baseAsset} / {quoteAsset} -
    +
    Unknown Price Feed
    - {/* Oracle Information */} -
    -
    - Address: - - {getSlicedAddress(feed.address as Address)} - -
    + {/* Description */} +
    + This oracle uses an unrecognized price feed contract.
    {/* External Links */}
    - View on: + View contract:
    @@ -45,8 +46,17 @@ function OracleVendorBadge({ )} {isCustom ? ( + ) : hasCompletelyUnknown || hasTaggedUnknown ? ( + // Show core vendor icons plus question mark for any unknown types + <> + {coreVendors.map((vendor, index) => ( + {renderVendorIcon(vendor)} + ))} + + ) : ( - vendors.map((vendor, index) => ( + // Only core vendors, show their icons + coreVendors.map((vendor, index) => ( {renderVendorIcon(vendor)} )) )} @@ -64,17 +74,25 @@ function OracleVendorBadge({ ); } - if (hasUnknown) { - const knownVendors = vendors.filter(v => v !== PriceFeedVendors.Unknown); - const unknownCount = vendors.filter(v => v === PriceFeedVendors.Unknown).length; - + if (hasCompletelyUnknown || hasTaggedUnknown) { let description = ''; - if (knownVendors.length > 0) { - description = `Uses feeds from ${knownVendors.join(', ')}, plus ${unknownCount} unknown feed${unknownCount > 1 ? 's' : ''}.`; - } else { - description = `Uses ${unknownCount} unknown feed${unknownCount > 1 ? 's' : ''} only.`; + const parts = []; + + if (coreVendors.length > 0) { + parts.push(`${coreVendors.join(', ')}`); + } + + if (taggedVendors.length > 0) { + parts.push(`${taggedVendors.join(', ')} (third-party)`); } + if (hasCompletelyUnknown) { + const unknownCount = 1; // Simplified for now + parts.push(`${unknownCount} unrecognized feed${unknownCount > 1 ? 's' : ''}`); + } + + description = `Uses feeds from: ${parts.join(', ')}.`; + return (

    Standard Oracle

    @@ -83,10 +101,12 @@ function OracleVendorBadge({ ); } + // All core vendors - clean case + const allVendors = [...coreVendors, ...taggedVendors]; return (

    Standard Oracle

    -

    Uses feeds from {vendors.join(', ')}.

    +

    Uses feeds from {allVendors.join(', ')}.

    ); }; diff --git a/src/components/TokenIcon.tsx b/src/components/TokenIcon.tsx index 790a2bb8..a9a26ad1 100644 --- a/src/components/TokenIcon.tsx +++ b/src/components/TokenIcon.tsx @@ -3,6 +3,7 @@ import { Tooltip } from '@heroui/react'; import Image from 'next/image'; import { useTokens } from '@/components/providers/TokenProvider'; import { TooltipContent } from './TooltipContent'; +import { getTruncatedAssetName } from '@/utils/oracle'; type TokenIconProps = { address: string; chainId: number; @@ -10,9 +11,10 @@ type TokenIconProps = { height: number; opacity?: number; symbol?: string; + truncated?: boolean }; -export function TokenIcon({ address, chainId, width, height, opacity }: TokenIconProps) { +export function TokenIcon({ address, chainId, width, height, opacity, truncated }: TokenIconProps) { const { findToken } = useTokens(); const token = useMemo(() => findToken(address, chainId), [address, chainId, findToken]); @@ -34,7 +36,7 @@ export function TokenIcon({ address, chainId, width, height, opacity }: TokenIco : `This token is whitelisted by Monarch`; return ( - }> + }> (); - let hasUnknown = false; + const coreVendors = new Set(); + const taggedVendors = new Set(); + let hasCompletelyUnknown = false; + let hasTaggedUnknown = false; for (const feed of feeds) { if (feed?.address) { const feedResult = detectFeedVendor(feed.address, chainId); - vendors.add(feedResult.vendor); + if (feedResult.vendor === PriceFeedVendors.Unknown) { - hasUnknown = true; + // Check if this unknown feed actually has data (tagged by Morpho) + if (feedResult.data) { + // It's tagged by Morpho but not in our core vendors enum + taggedVendors.add(feedResult.data.vendor); + hasTaggedUnknown = true; + } else { + // Completely unknown feed + hasCompletelyUnknown = true; + } + } else { + // It's a core vendor + coreVendors.add(feedResult.vendor); } } } - // If we have no feeds with addresses, that should be considered as having unknown feeds + // If we have no feeds with addresses, that should be considered as completely unknown const hasFeeds = feeds.some(feed => feed?.address); + if (!hasFeeds) { + hasCompletelyUnknown = true; + } + + // Legacy support - combine all vendors for backward compatibility + const legacyVendors = Array.from(coreVendors); + const legacyHasUnknown = hasCompletelyUnknown || hasTaggedUnknown; return { - vendors: Array.from(vendors), - hasUnknown: hasUnknown || !hasFeeds, + coreVendors: Array.from(coreVendors), + taggedVendors: Array.from(taggedVendors), + hasCompletelyUnknown, + hasTaggedUnknown, + // Legacy properties for backward compatibility + vendors: legacyVendors, + hasUnknown: legacyHasUnknown, }; } diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 4866a351..70ecaa49 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -125,10 +125,19 @@ const INCOMPATIBLE_ORACLE_FEEDS: WarningWithDetail = { category: WarningCategory.oracle, }; +// not on any list: Danger (alert level) const UNRECOGNIZED_FEEDS: WarningWithDetail = { code: 'unknown feeds', level: 'alert', - description: 'This market oracle has feed(s) that are not part of our recognized feeds list.', + description: 'This market oracle has feed(s) that are not part of any recognized feeds list.', + category: WarningCategory.oracle, +}; + +// morpho config list +const UNRECOGNIZED_FEEDS_TAGGED: WarningWithDetail = { + code: 'unknown feeds tagged', + level: 'warning', + description: 'This market oracle has feeds that were tagged by Morpho but not verified by Monarch', category: WarningCategory.oracle, }; @@ -196,12 +205,19 @@ export const getMarketWarningsWithDetail = ( ); if (oracleType === OracleType.Custom) result.push(UNRECOGNIZED_ORACLE); - // if any of the feeds are not null but also not recognized, return feed warning + // if any of the feeds are not null but also not recognized, return appropriate feed warning if (oracleType === OracleType.Standard && market.oracle?.data) { const vendorInfo = parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id); - if (vendorInfo.hasUnknown) { + + // Completely unknown feeds get the stronger warning + if (vendorInfo.hasCompletelyUnknown) { result.push(UNRECOGNIZED_FEEDS); } + + // Tagged but not core vendors get the milder warning + if (vendorInfo.hasTaggedUnknown) { + result.push(UNRECOGNIZED_FEEDS_TAGGED); + } } return result; From f2325dadb17e572ef9a1147b6a5f38690c700771 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 18:48:28 +0800 Subject: [PATCH 14/19] chore: styling the unknwon feed display --- src/components/MarketOracle/FeedEntry.tsx | 12 ++--- src/utils/oracle.ts | 57 +++++++++++------------ 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index 14765902..6eb9036d 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -34,13 +34,13 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null const { vendor, data, assetPair } = feedVendorResult; - const { fromAsset, toAsset } = { - fromAsset: getTruncatedAssetName(assetPair.fromAsset), - toAsset: getTruncatedAssetName(assetPair.toAsset), + const { baseAsset, quoteAsset } = { + baseAsset: getTruncatedAssetName(assetPair.baseAsset), + quoteAsset: getTruncatedAssetName(assetPair.quoteAsset), }; // Don't show asset pair if it's unknown - const showAssetPair = !(assetPair.fromAsset === 'Unknown' && assetPair.toAsset === 'Unknown'); + const showAssetPair = !(assetPair.baseAsset === 'Unknown' && assetPair.quoteAsset === 'Unknown'); const vendorIcon = OracleVendorIcons[vendor]; const isChainlink = vendor === PriceFeedVendors.Chainlink; @@ -86,9 +86,9 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null
    {showAssetPair ? (
    - {fromAsset} + {baseAsset} - {toAsset} + {quoteAsset}
    ) : (
    diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index ec3b43b7..c28288b3 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -214,13 +214,8 @@ function getFeedPath( ): { base: string; quote: string } { if (!feed || !feed.address) return { base: 'EMPTY', quote: 'EMPTY' }; - const chainlinkData = getChainlinkOracle(chainId, feed.address); - if (!chainlinkData) return { base: 'EMPTY', quote: 'EMPTY' }; - - return { - base: chainlinkData.baseAsset.toLowerCase(), - quote: chainlinkData.quoteAsset.toLowerCase(), - }; + const data = detectFeedVendor(feed.address, chainId); + return { base: data.assetPair.baseAsset, quote: data.assetPair.quoteAsset } } // Discriminated union types for feed detection results @@ -228,8 +223,8 @@ export type ChainlinkFeedResult = { vendor: PriceFeedVendors.Chainlink; data: ChainlinkOracleEntry; assetPair: { - fromAsset: string; - toAsset: string; + baseAsset: string; + quoteAsset: string; }; }; @@ -237,8 +232,8 @@ export type CompoundFeedResult = { vendor: PriceFeedVendors.Compound; data: CompoundFeedEntry; assetPair: { - fromAsset: string; - toAsset: string; + baseAsset: string; + quoteAsset: string; }; }; @@ -250,8 +245,8 @@ export type GeneralFeedResult = { | PriceFeedVendors.Lido; data: GeneralPriceFeed; assetPair: { - fromAsset: string; - toAsset: string; + baseAsset: string; + quoteAsset: string; }; }; @@ -259,8 +254,8 @@ export type UnknownFeedResult = { vendor: PriceFeedVendors.Unknown; data: GeneralPriceFeed | null; assetPair: { - fromAsset: string; - toAsset: string; + baseAsset: string; + quoteAsset: string; }; }; @@ -288,8 +283,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Chainlink, data: chainlinkData, assetPair: { - fromAsset: chainlinkData.baseAsset, - toAsset: chainlinkData.quoteAsset, + baseAsset: chainlinkData.baseAsset, + quoteAsset: chainlinkData.quoteAsset, }, } satisfies ChainlinkFeedResult; } @@ -303,8 +298,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Compound, data: compoundData, assetPair: { - fromAsset: compoundData.base, - toAsset: compoundData.quote, + baseAsset: compoundData.base, + quoteAsset: compoundData.quote, }, } satisfies CompoundFeedResult; } @@ -323,8 +318,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Redstone, data: generalFeedData, assetPair: { - fromAsset: generalFeedData.pair[0], - toAsset: generalFeedData.pair[1], + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], }, } satisfies GeneralFeedResult; } @@ -334,8 +329,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.PythNetwork, data: generalFeedData, assetPair: { - fromAsset: generalFeedData.pair[0], - toAsset: generalFeedData.pair[1], + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], }, } satisfies GeneralFeedResult; } @@ -345,8 +340,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Oval, data: generalFeedData, assetPair: { - fromAsset: generalFeedData.pair[0], - toAsset: generalFeedData.pair[1], + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], }, } satisfies GeneralFeedResult; } @@ -356,8 +351,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Lido, data: generalFeedData, assetPair: { - fromAsset: generalFeedData.pair[0], - toAsset: generalFeedData.pair[1], + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], }, } satisfies GeneralFeedResult; } @@ -367,8 +362,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Unknown, data: generalFeedData, assetPair: { - fromAsset: generalFeedData.pair[0], - toAsset: generalFeedData.pair[1], + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], }, } satisfies UnknownFeedResult; } @@ -379,8 +374,8 @@ export function detectFeedVendor(feedAddress: Address | string, chainId: number) vendor: PriceFeedVendors.Unknown, data: null, assetPair: { - fromAsset: 'Unknown', - toAsset: 'Unknown', + baseAsset: 'Unknown', + quoteAsset: 'Unknown', }, } satisfies UnknownFeedResult; } From 3e054ac0c7e5bd143990ca6ae7bc749c08a3f9ee Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 19:08:36 +0800 Subject: [PATCH 15/19] feat: asset paring warnings --- .../[marketid]/components/PositionStats.tsx | 7 +- app/market/[chainId]/[marketid]/content.tsx | 4 +- app/markets/components/MarketRowDetail.tsx | 2 +- src/components/TokenIcon.tsx | 5 +- src/utils/oracle.ts | 169 +++++++++++++++--- src/utils/warnings.ts | 40 ++++- 6 files changed, 185 insertions(+), 42 deletions(-) diff --git a/app/market/[chainId]/[marketid]/components/PositionStats.tsx b/app/market/[chainId]/[marketid]/components/PositionStats.tsx index 9517a40b..2663dc28 100644 --- a/app/market/[chainId]/[marketid]/components/PositionStats.tsx +++ b/app/market/[chainId]/[marketid]/components/PositionStats.tsx @@ -8,6 +8,7 @@ import { Spinner } from '@/components/common/Spinner'; import { TokenIcon } from '@/components/TokenIcon'; import { formatBalance, formatReadable } from '@/utils/balance'; import { Market, MarketPosition } from '@/utils/types'; +import { getTruncatedAssetName } from '@/utils/oracle'; type PositionStatsProps = { market: Market; @@ -66,14 +67,13 @@ export function PositionStats({ symbol={market.loanAsset.symbol} width={16} height={16} - truncated /> {formatBalance( BigInt(userPosition.state.supplyAssets || 0), market.loanAsset.decimals, ).toString()}{' '} - {market.loanAsset.symbol} + {getTruncatedAssetName(market.loanAsset.symbol)}
    @@ -86,14 +86,13 @@ export function PositionStats({ symbol={market.loanAsset.symbol} width={16} height={16} - truncated /> {formatBalance( BigInt(userPosition.state.borrowAssets || 0), market.loanAsset.decimals, ).toString()}{' '} - {market.loanAsset.symbol} + {getTruncatedAssetName(market.loanAsset.symbol)}
    diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index 1b26ff86..ecba9973 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -33,6 +33,7 @@ import { PositionStats } from './components/PositionStats'; import { SuppliesTable } from './components/SuppliesTable'; import RateChart from './RateChart'; import VolumeChart from './VolumeChart'; +import { getTruncatedAssetName } from '@/utils/oracle'; const NOW = Math.floor(Date.now() / 1000); const DAY_IN_SECONDS = 24 * 60 * 60; @@ -284,7 +285,6 @@ function MarketContent() { symbol={market.collateralAsset.symbol} width={20} height={20} - truncated /> - {market.collateralAsset.symbol} + {getTruncatedAssetName(market.collateralAsset.symbol)}
    diff --git a/app/markets/components/MarketRowDetail.tsx b/app/markets/components/MarketRowDetail.tsx index 01cdc81c..ea03fbf5 100644 --- a/app/markets/components/MarketRowDetail.tsx +++ b/app/markets/components/MarketRowDetail.tsx @@ -64,7 +64,7 @@ export function ExpandedMarketDetail({ market }: { market: Market }) {
    { // if no warning - market.warnings.length === 0 && ( + warningsWithDetail.length === 0 && ( ) } diff --git a/src/components/TokenIcon.tsx b/src/components/TokenIcon.tsx index a9a26ad1..1a260f79 100644 --- a/src/components/TokenIcon.tsx +++ b/src/components/TokenIcon.tsx @@ -11,10 +11,9 @@ type TokenIconProps = { height: number; opacity?: number; symbol?: string; - truncated?: boolean }; -export function TokenIcon({ address, chainId, width, height, opacity, truncated }: TokenIconProps) { +export function TokenIcon({ address, chainId, width, height, opacity }: TokenIconProps) { const { findToken } = useTokens(); const token = useMemo(() => findToken(address, chainId), [address, chainId, findToken]); @@ -36,7 +35,7 @@ export function TokenIcon({ address, chainId, width, height, opacity, truncated : `This token is whitelisted by Monarch`; return ( - }> + }> { + const path = getFeedPath(feed, chainId); + return { path, type, hasData: !!feed?.address }; + }); + + // Check for unknown assets + const hasUnknownAssets = feedPaths.some( + ({ path }) => path.base === 'Unknown' || path.quote === 'Unknown' + ); + + if (hasUnknownAssets) { + return { + isValid: false, + hasUnknownFeed: true, + }; + } + + // Count asset occurrences in numerator and denominator + const numeratorCounts = new Map(); + const denominatorCounts = new Map(); + + // Helper function to increment count with normalized symbols + const incrementCount = (map: Map, asset: string) => { + if (asset !== 'EMPTY') { + const normalizedAsset = normalizeSymbol(asset); + map.set(normalizedAsset, (map.get(normalizedAsset) ?? 0) + 1); + } + }; + + feedPaths.forEach(({ path, type, hasData }) => { + if (!hasData) return; + + if (type === 'base1' || type === 'base2') { + // For base feeds: base goes to numerator, quote goes to denominator + incrementCount(numeratorCounts, path.base); + incrementCount(denominatorCounts, path.quote); + } else { + // For quote feeds: base goes to denominator, quote goes to numerator + incrementCount(denominatorCounts, path.base); + incrementCount(numeratorCounts, path.quote); + } + }); + + // Cancel out matching terms + const cancelOut = (num: Map, den: Map) => { + const assets = new Set([...num.keys(), ...den.keys()]); + + for (const asset of assets) { + const numCount = num.get(asset) ?? 0; + const denCount = den.get(asset) ?? 0; + const minCount = Math.min(numCount, denCount); + + if (minCount > 0) { + num.set(asset, numCount - minCount); + den.set(asset, denCount - minCount); + + // Remove zeros + if (num.get(asset) === 0) num.delete(asset); + if (den.get(asset) === 0) den.delete(asset); } } - // no matched denominator + }; + + cancelOut(numeratorCounts, denominatorCounts); + + // Check if remaining terms match expected collateral/loan path + const remainingNumeratorAssets = Array.from(numeratorCounts.keys()).filter( + asset => (numeratorCounts.get(asset) ?? 0) > 0 + ); + const remainingDenominatorAssets = Array.from(denominatorCounts.keys()).filter( + asset => (denominatorCounts.get(asset) ?? 0) > 0 + ); + + // Normalize the expected collateral and loan symbols for comparison + const normalizedCollateralSymbol = normalizeSymbol(collateralSymbol); + const normalizedLoanSymbol = normalizeSymbol(loanSymbol); + + const expectedPath = `${normalizedCollateralSymbol}/${normalizedLoanSymbol}`; + + // Perfect match: exactly one asset in numerator (collateral) and one in denominator (loan) + const isValid = + remainingNumeratorAssets.length === 1 && + remainingDenominatorAssets.length === 1 && + remainingNumeratorAssets[0] === normalizedCollateralSymbol && + remainingDenominatorAssets[0] === normalizedLoanSymbol && + (numeratorCounts.get(normalizedCollateralSymbol) ?? 0) === 1 && + (denominatorCounts.get(normalizedLoanSymbol) ?? 0) === 1; + + if (isValid) { + return { isValid: true }; + } + + // Generate helpful error message + let missingPath = ''; + if (remainingNumeratorAssets.length === 0 && remainingDenominatorAssets.length === 0) { + missingPath = 'All assets canceled out - no price path found'; + } else { + const actualPath = `${remainingNumeratorAssets.join('*')}/${remainingDenominatorAssets.join('*')}`; + missingPath = `Path mismatch: got ${actualPath}, expected ${expectedPath}`; } - return false; + + return { + isValid: false, + missingPath, + expectedPath, + }; } /** * * @param feed * @param chainId - * @returns { base: "ETH", qutoe: "USD" } + * @returns { base: "ETH", quote: "USD" } */ function getFeedPath( feed: OracleFeed | null | undefined, diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 70ecaa49..1388d71b 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -1,6 +1,6 @@ import { MarketWarning, MorphoChainlinkOracleData } from '@/utils/types'; import { monarchWhitelistedMarkets } from './markets'; -import { getOracleType, OracleType, parsePriceFeedVendors } from './oracle'; +import { getOracleType, OracleType, parsePriceFeedVendors, checkFeedsPath } from './oracle'; import { WarningCategory, WarningWithDetail } from './types'; // Subgraph Warnings @@ -120,8 +120,15 @@ const UNRECOGNIZED_ORACLE: WarningWithDetail = { const INCOMPATIBLE_ORACLE_FEEDS: WarningWithDetail = { code: 'incompatible_oracle_feeds', - level: 'alert', - description: 'The market is using oracle feeds which do not match with each other.', + level: 'warning', + description: 'The oracle feeds cannot produce a valid price path for this market.', + category: WarningCategory.oracle, +}; + +const UNKNOWN_FEED_FOR_PAIR_MATCHING: WarningWithDetail = { + code: 'unknown_oracle_feeds', + level: 'warning', + description: 'The oracle contains feeds with unknown asset pairs.', category: WarningCategory.oracle, }; @@ -162,6 +169,8 @@ export const getMarketWarningsWithDetail = ( oracle?: { data: MorphoChainlinkOracleData }; oracleAddress?: string; morphoBlue: { chain: { id: number } }; + loanAsset?: { symbol: string }; + collateralAsset?: { symbol: string }; }, considerWhitelist = false, ) => { @@ -218,6 +227,31 @@ export const getMarketWarningsWithDetail = ( if (vendorInfo.hasTaggedUnknown) { result.push(UNRECOGNIZED_FEEDS_TAGGED); } + + // Check if oracle feeds can produce a valid price path + if (market.collateralAsset?.symbol && market.loanAsset?.symbol) { + const feedsPathResult = checkFeedsPath( + market.oracle.data, + market.morphoBlue.chain.id, + market.collateralAsset.symbol, + market.loanAsset.symbol + ); + + if (feedsPathResult.hasUnknownFeed) { + + // only append this error if it's doesn't already have "UNRECOGNIZED_FEEDS" + if (result.find(w => w === UNRECOGNIZED_FEEDS) === undefined) { + result.push(UNKNOWN_FEED_FOR_PAIR_MATCHING); + } + } else if (!feedsPathResult.isValid) { + // Create a dynamic warning with the specific error message + const incompatibleFeedsWarning: WarningWithDetail = { + ...INCOMPATIBLE_ORACLE_FEEDS, + description: feedsPathResult.missingPath ?? INCOMPATIBLE_ORACLE_FEEDS.description, + }; + result.push(incompatibleFeedsWarning); + } + } } return result; From e12909132ae8282805f3dff18b83b43050e63168 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 19:15:48 +0800 Subject: [PATCH 16/19] chore: lint --- src/config/oracle-whitelist.ts | 14 -------------- src/data-sources/subgraph/market.ts | 2 -- src/utils/warnings.ts | 9 ++++----- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/config/oracle-whitelist.ts b/src/config/oracle-whitelist.ts index 3037cd6c..2bf43758 100644 --- a/src/config/oracle-whitelist.ts +++ b/src/config/oracle-whitelist.ts @@ -17,10 +17,8 @@ export const oracleWhitelist: Partial w === UNRECOGNIZED_FEEDS) === undefined) { - result.push(UNKNOWN_FEED_FOR_PAIR_MATCHING); - } + // only append this error if it doesn't already have "UNRECOGNIZED_FEEDS" + if (result.find((w) => w === UNRECOGNIZED_FEEDS) === undefined) { + result.push(UNKNOWN_FEED_FOR_PAIR_MATCHING); + } } else if (!feedsPathResult.isValid) { // Create a dynamic warning with the specific error message const incompatibleFeedsWarning: WarningWithDetail = { From 05d57527c4a40e0d24ec536f5dac268ab2d74f90 Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 20:55:34 +0800 Subject: [PATCH 17/19] feat: lint --- .../[marketid]/components/PositionStats.tsx | 2 +- app/market/[chainId]/[marketid]/content.tsx | 5 +- app/markets/components/MarketTableBody.tsx | 1 - .../MarketOracle/CompoundFeedTooltip.tsx | 1 - src/components/MarketOracle/FeedEntry.tsx | 2 +- .../MarketOracle/GeneralFeedTooltip.tsx | 1 - .../MarketOracle/OracleTypeInfo.tsx | 6 +- .../MarketOracle/UnknownFeedTooltip.tsx | 3 +- src/components/TokenIcon.tsx | 1 - src/utils/oracle.ts | 358 +++++++++--------- src/utils/positions.ts | 1 - 11 files changed, 187 insertions(+), 194 deletions(-) diff --git a/app/market/[chainId]/[marketid]/components/PositionStats.tsx b/app/market/[chainId]/[marketid]/components/PositionStats.tsx index 2663dc28..7ae5a41c 100644 --- a/app/market/[chainId]/[marketid]/components/PositionStats.tsx +++ b/app/market/[chainId]/[marketid]/components/PositionStats.tsx @@ -7,8 +7,8 @@ import { HiOutlineGlobeAsiaAustralia } from 'react-icons/hi2'; import { Spinner } from '@/components/common/Spinner'; import { TokenIcon } from '@/components/TokenIcon'; import { formatBalance, formatReadable } from '@/utils/balance'; -import { Market, MarketPosition } from '@/utils/types'; import { getTruncatedAssetName } from '@/utils/oracle'; +import { Market, MarketPosition } from '@/utils/types'; type PositionStatsProps = { market: Market; diff --git a/app/market/[chainId]/[marketid]/content.tsx b/app/market/[chainId]/[marketid]/content.tsx index ecba9973..eb50dea6 100644 --- a/app/market/[chainId]/[marketid]/content.tsx +++ b/app/market/[chainId]/[marketid]/content.tsx @@ -14,8 +14,7 @@ import { BorrowModal } from '@/components/BorrowModal'; import { Button } from '@/components/common'; import { Spinner } from '@/components/common/Spinner'; import Header from '@/components/layout/header/Header'; -import { MarketOracleFeedInfo, OracleTypeInfo } from '@/components/MarketOracle'; -import OracleVendorBadge from '@/components/OracleVendorBadge'; +import { OracleTypeInfo } from '@/components/MarketOracle'; import { SupplyModalV2 } from '@/components/SupplyModalV2'; import { TokenIcon } from '@/components/TokenIcon'; import { useMarketData } from '@/hooks/useMarketData'; @@ -26,6 +25,7 @@ import MORPHO_LOGO from '@/imgs/tokens/morpho.svg'; import { getExplorerURL, getMarketURL } from '@/utils/external'; import { getIRMTitle } from '@/utils/morpho'; import { getNetworkImg, getNetworkName, SupportedNetworks } from '@/utils/networks'; +import { getTruncatedAssetName } from '@/utils/oracle'; import { TimeseriesOptions } from '@/utils/types'; import { BorrowsTable } from './components/BorrowsTable'; import { LiquidationsTable } from './components/LiquidationsTable'; @@ -33,7 +33,6 @@ import { PositionStats } from './components/PositionStats'; import { SuppliesTable } from './components/SuppliesTable'; import RateChart from './RateChart'; import VolumeChart from './VolumeChart'; -import { getTruncatedAssetName } from '@/utils/oracle'; const NOW = Math.floor(Date.now() / 1000); const DAY_IN_SECONDS = 24 * 60 * 60; diff --git a/app/markets/components/MarketTableBody.tsx b/app/markets/components/MarketTableBody.tsx index 9dfaa8ae..b7926507 100644 --- a/app/markets/components/MarketTableBody.tsx +++ b/app/markets/components/MarketTableBody.tsx @@ -13,7 +13,6 @@ import logo from '../../../imgs/logo.png'; import { ExpandedMarketDetail } from './MarketRowDetail'; import { TDAsset, TDTotalSupplyOrBorrow } from './MarketTableUtils'; import { MarketAssetIndicator, MarketOracleIndicator, MarketDebtIndicator } from './RiskIndicator'; -import { IoGitMerge } from 'react-icons/io5'; type MarketTableBodyProps = { currentEntries: Market[]; diff --git a/src/components/MarketOracle/CompoundFeedTooltip.tsx b/src/components/MarketOracle/CompoundFeedTooltip.tsx index a18ec203..dfa36ee0 100644 --- a/src/components/MarketOracle/CompoundFeedTooltip.tsx +++ b/src/components/MarketOracle/CompoundFeedTooltip.tsx @@ -4,7 +4,6 @@ import Link from 'next/link'; import { Address } from 'viem'; import { Badge } from '@/components/common/Badge'; import { - ChainlinkOracleEntry, getChainlinkFeedUrl, getChainlinkOracle, } from '@/constants/oracle/chainlink-data'; diff --git a/src/components/MarketOracle/FeedEntry.tsx b/src/components/MarketOracle/FeedEntry.tsx index 6eb9036d..fc27cc79 100644 --- a/src/components/MarketOracle/FeedEntry.tsx +++ b/src/components/MarketOracle/FeedEntry.tsx @@ -104,7 +104,7 @@ export function FeedEntry({ feed, chainId }: FeedEntryProps): JSX.Element | null )} {(isChainlink || isCompound) && vendorIcon ? ( - {'Oracle'} + Oracle ) : ( )} diff --git a/src/components/MarketOracle/GeneralFeedTooltip.tsx b/src/components/MarketOracle/GeneralFeedTooltip.tsx index a88791f2..8daa7fec 100644 --- a/src/components/MarketOracle/GeneralFeedTooltip.tsx +++ b/src/components/MarketOracle/GeneralFeedTooltip.tsx @@ -1,7 +1,6 @@ import Image from 'next/image'; import Link from 'next/link'; import { Address } from 'viem'; -import { Badge } from '@/components/common/Badge'; import { GeneralPriceFeed } from '@/constants/oracle/general-feeds'; import etherscanLogo from '@/imgs/etherscan.png'; import { getExplorerURL } from '@/utils/external'; diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index c0c9ffc6..48d8d06d 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -1,9 +1,9 @@ +import Link from 'next/link'; +import { FiExternalLink } from 'react-icons/fi'; import { MarketOracleFeedInfo } from '@/components/MarketOracle'; import { getExplorerURL } from '@/utils/external'; import { getOracleType, getOracleTypeDescription, OracleType } from '@/utils/oracle'; import { MorphoChainlinkOracleData } from '@/utils/types'; -import Link from 'next/link'; -import { FiExternalLink } from 'react-icons/fi'; type OracleTypeInfoProps = { oracleData: MorphoChainlinkOracleData | null | undefined; @@ -53,7 +53,7 @@ export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink, s feed structure.
    - ) : (<>)} + ) : null} ); } diff --git a/src/components/MarketOracle/UnknownFeedTooltip.tsx b/src/components/MarketOracle/UnknownFeedTooltip.tsx index 55b28f80..fd581e43 100644 --- a/src/components/MarketOracle/UnknownFeedTooltip.tsx +++ b/src/components/MarketOracle/UnknownFeedTooltip.tsx @@ -1,9 +1,8 @@ import Image from 'next/image'; import Link from 'next/link'; -import { Address } from 'viem'; import { IoHelpCircleOutline } from 'react-icons/io5'; +import { Address } from 'viem'; import etherscanLogo from '@/imgs/etherscan.png'; -import { getSlicedAddress } from '@/utils/address'; import { getExplorerURL } from '@/utils/external'; import { OracleFeed } from '@/utils/types'; diff --git a/src/components/TokenIcon.tsx b/src/components/TokenIcon.tsx index 1a260f79..790a2bb8 100644 --- a/src/components/TokenIcon.tsx +++ b/src/components/TokenIcon.tsx @@ -3,7 +3,6 @@ import { Tooltip } from '@heroui/react'; import Image from 'next/image'; import { useTokens } from '@/components/providers/TokenProvider'; import { TooltipContent } from './TooltipContent'; -import { getTruncatedAssetName } from '@/utils/oracle'; type TokenIconProps = { address: string; chainId: number; diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index 6c2073a3..be46e525 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -50,6 +50,184 @@ export function getOracleTypeDescription(oracleType: OracleType): string { return 'Custom Oracle'; } +// Discriminated union types for feed detection results +export type ChainlinkFeedResult = { + vendor: PriceFeedVendors.Chainlink; + data: ChainlinkOracleEntry; + assetPair: { + baseAsset: string; + quoteAsset: string; + }; +}; + +export type CompoundFeedResult = { + vendor: PriceFeedVendors.Compound; + data: CompoundFeedEntry; + assetPair: { + baseAsset: string; + quoteAsset: string; + }; +}; + +export type GeneralFeedResult = { + vendor: + | PriceFeedVendors.Redstone + | PriceFeedVendors.PythNetwork + | PriceFeedVendors.Oval + | PriceFeedVendors.Lido; + data: GeneralPriceFeed; + assetPair: { + baseAsset: string; + quoteAsset: string; + }; +}; + +export type UnknownFeedResult = { + vendor: PriceFeedVendors.Unknown; + data: GeneralPriceFeed | null; + assetPair: { + baseAsset: string; + quoteAsset: string; + }; +}; + +// Discriminated union - ensures vendor and data types are always matched correctly +export type FeedVendorResult = + | ChainlinkFeedResult + | CompoundFeedResult + | GeneralFeedResult + | UnknownFeedResult; + +/** + * Centralized function to detect feed vendor and retrieve corresponding data + * @param feedAddress - The feed contract address + * @param chainId - The chain ID + * @returns FeedVendorResult with vendor, data, and asset pair information + */ +export function detectFeedVendor(feedAddress: Address | string, chainId: number): FeedVendorResult { + const address = feedAddress as Address; + + // Check if it's a Chainlink feed + if (isChainlinkOracle(chainId, address)) { + const chainlinkData = getChainlinkOracle(chainId, address); + if (chainlinkData) { + return { + vendor: PriceFeedVendors.Chainlink, + data: chainlinkData, + assetPair: { + baseAsset: chainlinkData.baseAsset, + quoteAsset: chainlinkData.quoteAsset, + }, + } satisfies ChainlinkFeedResult; + } + } + + // Check if it's a Compound feed + if (isCompoundFeed(address)) { + const compoundData = getCompoundFeed(address); + if (compoundData) { + return { + vendor: PriceFeedVendors.Compound, + data: compoundData, + assetPair: { + baseAsset: compoundData.base, + quoteAsset: compoundData.quote, + }, + } satisfies CompoundFeedResult; + } + } + + // Check if it's a general price feed (from various vendors via Morpho's API data) + if (isGeneralFeed(address, chainId)) { + const generalFeedData = getGeneralFeed(address, chainId); + if (generalFeedData) { + // Map the vendor name from the general feed data to our enum + const vendorName = generalFeedData.vendor.toLowerCase(); + + // Return proper discriminated union based on vendor + if (vendorName === 'redstone') { + return { + vendor: PriceFeedVendors.Redstone, + data: generalFeedData, + assetPair: { + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], + }, + } satisfies GeneralFeedResult; + } + + if (vendorName === 'pyth network' || vendorName === 'pyth') { + return { + vendor: PriceFeedVendors.PythNetwork, + data: generalFeedData, + assetPair: { + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], + }, + } satisfies GeneralFeedResult; + } + + if (vendorName === 'oval') { + return { + vendor: PriceFeedVendors.Oval, + data: generalFeedData, + assetPair: { + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], + }, + } satisfies GeneralFeedResult; + } + + if (vendorName === 'lido') { + return { + vendor: PriceFeedVendors.Lido, + data: generalFeedData, + assetPair: { + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], + }, + } satisfies GeneralFeedResult; + } + + // For vendors not in our enum (like Pendle), return as unknown but with data + return { + vendor: PriceFeedVendors.Unknown, + data: generalFeedData, + assetPair: { + baseAsset: generalFeedData.pair[0], + quoteAsset: generalFeedData.pair[1], + }, + } satisfies UnknownFeedResult; + } + } + + // Unknown feed - use fallback pair or default to Unknown + return { + vendor: PriceFeedVendors.Unknown, + data: null, + assetPair: { + baseAsset: 'Unknown', + quoteAsset: 'Unknown', + }, + } satisfies UnknownFeedResult; +} + +/** + * + * @param feed + * @param chainId + * @returns { base: "ETH", quote: "USD" } + */ +function getFeedPath( + feed: OracleFeed | null | undefined, + chainId: number, +): { base: string; quote: string } { + if (!feed || !feed.address) return { base: 'EMPTY', quote: 'EMPTY' }; + + const data = detectFeedVendor(feed.address, chainId); + return { base: data.assetPair.baseAsset, quote: data.assetPair.quoteAsset } +} + export function getOracleType( oracleData: MorphoChainlinkOracleData | null | undefined, oracleAddress?: string, @@ -303,7 +481,7 @@ export function checkFeedsPath( missingPath = 'All assets canceled out - no price path found'; } else { const actualPath = `${remainingNumeratorAssets.join('*')}/${remainingDenominatorAssets.join('*')}`; - missingPath = `Path mismatch: got ${actualPath}, expected ${expectedPath}`; + missingPath = `Feed path mismatch: got ${actualPath}, expected ${expectedPath}`; } return { @@ -313,184 +491,6 @@ export function checkFeedsPath( }; } -/** - * - * @param feed - * @param chainId - * @returns { base: "ETH", quote: "USD" } - */ -function getFeedPath( - feed: OracleFeed | null | undefined, - chainId: number, -): { base: string; quote: string } { - if (!feed || !feed.address) return { base: 'EMPTY', quote: 'EMPTY' }; - - const data = detectFeedVendor(feed.address, chainId); - return { base: data.assetPair.baseAsset, quote: data.assetPair.quoteAsset } -} - -// Discriminated union types for feed detection results -export type ChainlinkFeedResult = { - vendor: PriceFeedVendors.Chainlink; - data: ChainlinkOracleEntry; - assetPair: { - baseAsset: string; - quoteAsset: string; - }; -}; - -export type CompoundFeedResult = { - vendor: PriceFeedVendors.Compound; - data: CompoundFeedEntry; - assetPair: { - baseAsset: string; - quoteAsset: string; - }; -}; - -export type GeneralFeedResult = { - vendor: - | PriceFeedVendors.Redstone - | PriceFeedVendors.PythNetwork - | PriceFeedVendors.Oval - | PriceFeedVendors.Lido; - data: GeneralPriceFeed; - assetPair: { - baseAsset: string; - quoteAsset: string; - }; -}; - -export type UnknownFeedResult = { - vendor: PriceFeedVendors.Unknown; - data: GeneralPriceFeed | null; - assetPair: { - baseAsset: string; - quoteAsset: string; - }; -}; - -// Discriminated union - ensures vendor and data types are always matched correctly -export type FeedVendorResult = - | ChainlinkFeedResult - | CompoundFeedResult - | GeneralFeedResult - | UnknownFeedResult; - -/** - * Centralized function to detect feed vendor and retrieve corresponding data - * @param feedAddress - The feed contract address - * @param chainId - The chain ID - * @returns FeedVendorResult with vendor, data, and asset pair information - */ -export function detectFeedVendor(feedAddress: Address | string, chainId: number): FeedVendorResult { - const address = feedAddress as Address; - - // Check if it's a Chainlink feed - if (isChainlinkOracle(chainId, address)) { - const chainlinkData = getChainlinkOracle(chainId, address); - if (chainlinkData) { - return { - vendor: PriceFeedVendors.Chainlink, - data: chainlinkData, - assetPair: { - baseAsset: chainlinkData.baseAsset, - quoteAsset: chainlinkData.quoteAsset, - }, - } satisfies ChainlinkFeedResult; - } - } - - // Check if it's a Compound feed - if (isCompoundFeed(address)) { - const compoundData = getCompoundFeed(address); - if (compoundData) { - return { - vendor: PriceFeedVendors.Compound, - data: compoundData, - assetPair: { - baseAsset: compoundData.base, - quoteAsset: compoundData.quote, - }, - } satisfies CompoundFeedResult; - } - } - - // Check if it's a general price feed (from various vendors via Morpho's API data) - if (isGeneralFeed(address, chainId)) { - const generalFeedData = getGeneralFeed(address, chainId); - if (generalFeedData) { - // Map the vendor name from the general feed data to our enum - const vendorName = generalFeedData.vendor.toLowerCase(); - - // Return proper discriminated union based on vendor - if (vendorName === 'redstone') { - return { - vendor: PriceFeedVendors.Redstone, - data: generalFeedData, - assetPair: { - baseAsset: generalFeedData.pair[0], - quoteAsset: generalFeedData.pair[1], - }, - } satisfies GeneralFeedResult; - } - - if (vendorName === 'pyth network' || vendorName === 'pyth') { - return { - vendor: PriceFeedVendors.PythNetwork, - data: generalFeedData, - assetPair: { - baseAsset: generalFeedData.pair[0], - quoteAsset: generalFeedData.pair[1], - }, - } satisfies GeneralFeedResult; - } - - if (vendorName === 'oval') { - return { - vendor: PriceFeedVendors.Oval, - data: generalFeedData, - assetPair: { - baseAsset: generalFeedData.pair[0], - quoteAsset: generalFeedData.pair[1], - }, - } satisfies GeneralFeedResult; - } - - if (vendorName === 'lido') { - return { - vendor: PriceFeedVendors.Lido, - data: generalFeedData, - assetPair: { - baseAsset: generalFeedData.pair[0], - quoteAsset: generalFeedData.pair[1], - }, - } satisfies GeneralFeedResult; - } - - // For vendors not in our enum (like Pendle), return as unknown but with data - return { - vendor: PriceFeedVendors.Unknown, - data: generalFeedData, - assetPair: { - baseAsset: generalFeedData.pair[0], - quoteAsset: generalFeedData.pair[1], - }, - } satisfies UnknownFeedResult; - } - } - - // Unknown feed - use fallback pair or default to Unknown - return { - vendor: PriceFeedVendors.Unknown, - data: null, - assetPair: { - baseAsset: 'Unknown', - quoteAsset: 'Unknown', - }, - } satisfies UnknownFeedResult; -} - /** * Helper function to get truncated asset names (max 5 chars) */ diff --git a/src/utils/positions.ts b/src/utils/positions.ts index 5d4d5cdc..cc969842 100644 --- a/src/utils/positions.ts +++ b/src/utils/positions.ts @@ -10,7 +10,6 @@ import { PositionEarnings, UserTransaction, GroupedPosition, - WarningWithDetail, UserRebalancerInfo, } from './types'; From 966d5f0d31ca9f586740501e4761884c56c5c6be Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 21:38:32 +0800 Subject: [PATCH 18/19] chore: review fixes --- app/markets/components/utils.ts | 16 ++++++++++------ src/components/MarketOracle/OracleTypeInfo.tsx | 6 +++--- src/components/common/MarketInfoBlock.tsx | 4 ++-- src/hooks/useUserPositions.ts | 2 +- src/utils/oracle.ts | 4 +++- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/markets/components/utils.ts b/app/markets/components/utils.ts index 199e4ce4..5d214b4a 100644 --- a/app/markets/components/utils.ts +++ b/app/markets/components/utils.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { SupportedNetworks } from '@/utils/networks'; -import { parsePriceFeedVendors, PriceFeedVendors } from '@/utils/oracle'; +import { parsePriceFeedVendors, PriceFeedVendors, getOracleType, OracleType } from '@/utils/oracle'; import { ERC20Token } from '@/utils/tokens'; import { Market } from '@/utils/types'; import { SortColumn } from './constants'; @@ -89,11 +89,15 @@ export function applyFilterAndSort( return false; } - if ( - !showUnknownOracle && - (!market.oracle || parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id)) - ) { - return false; + if (!showUnknownOracle) { + const info = market.oracle + ? parsePriceFeedVendors(market.oracle.data, market.morphoBlue.chain.id) + : null; + const isCustom = + getOracleType(market.oracle?.data, market.oracleAddress, market.morphoBlue.chain.id) === + OracleType.Custom; + const isUnknown = isCustom || (info?.hasUnknown ?? false); + if (!market.oracle || isUnknown) return false; } if ( diff --git a/src/components/MarketOracle/OracleTypeInfo.tsx b/src/components/MarketOracle/OracleTypeInfo.tsx index 48d8d06d..d70b3ac6 100644 --- a/src/components/MarketOracle/OracleTypeInfo.tsx +++ b/src/components/MarketOracle/OracleTypeInfo.tsx @@ -14,7 +14,7 @@ type OracleTypeInfoProps = { }; export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink, showCustom }: OracleTypeInfoProps) { - const oracleType = getOracleType(oracleData); + const oracleType = getOracleType(oracleData, oracleAddress, chainId); const typeDescription = getOracleTypeDescription(oracleType); return ( @@ -29,11 +29,11 @@ export function OracleTypeInfo({ oracleData, oracleAddress, chainId, showLink, s rel="noopener noreferrer" className="flex items-center text-sm font-medium no-underline hover:underline" > - {oracleType} + {typeDescription} ) ): - ({oracleType}) + ({typeDescription}) }
    diff --git a/src/components/common/MarketInfoBlock.tsx b/src/components/common/MarketInfoBlock.tsx index 3d0c65c7..37dd408d 100644 --- a/src/components/common/MarketInfoBlock.tsx +++ b/src/components/common/MarketInfoBlock.tsx @@ -34,7 +34,7 @@ export function MarketInfoBlock({ market, amount, className }: MarketInfoBlockPr {formatUnits(BigInt(market.lltv), 16)}% LTV
    - {amount && amount !== maxUint256 ? ( + {amount !== undefined && amount !== maxUint256 ? ( {formatBalance(amount, market.loanAsset.decimals)} {market.loanAsset.symbol} @@ -125,7 +125,7 @@ export function MarketInfoBlockCompact({
    - {amount && amount !== maxUint256 ? ( + {amount !== undefined && amount !== maxUint256 ? ( {formatBalance(amount, market.loanAsset.decimals)} {market.loanAsset.symbol} diff --git a/src/hooks/useUserPositions.ts b/src/hooks/useUserPositions.ts index cc3da63f..0a3c130c 100644 --- a/src/hooks/useUserPositions.ts +++ b/src/hooks/useUserPositions.ts @@ -203,7 +203,7 @@ const useUserPositions = (user: string | undefined, showEmpty = false) => { } const publicClient = getClient( - marketInfo.chainId, + marketInfo.chainId as SupportedNetworks, customRpcUrls[marketInfo.chainId as SupportedNetworks] ?? undefined, ); if (!publicClient) { diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index be46e525..ca0c9d76 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -225,7 +225,9 @@ function getFeedPath( if (!feed || !feed.address) return { base: 'EMPTY', quote: 'EMPTY' }; const data = detectFeedVendor(feed.address, chainId); - return { base: data.assetPair.baseAsset, quote: data.assetPair.quoteAsset } + const base = data.assetPair.baseAsset || 'Unknown'; + const quote = data.assetPair.quoteAsset || 'Unknown'; + return { base, quote }; } export function getOracleType( From bc984ab7ed9a2e7912b30ef35d68e4d261294bbf Mon Sep 17 00:00:00 2001 From: antoncoding Date: Sat, 6 Sep 2025 21:57:23 +0800 Subject: [PATCH 19/19] chore: shorten name --- src/utils/oracle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts index ca0c9d76..ec75663c 100644 --- a/src/utils/oracle.ts +++ b/src/utils/oracle.ts @@ -45,7 +45,7 @@ export const OracleVendorIcons: Record = { }; export function getOracleTypeDescription(oracleType: OracleType): string { - if (oracleType === OracleType.Standard) return 'Standard Oracle from Price Feeds'; + if (oracleType === OracleType.Standard) return 'Standard Oracle'; return 'Custom Oracle'; }