From 388fe9ea0e9df65405fc65fd99b6b9767a3ddf03 Mon Sep 17 00:00:00 2001 From: Philippe Date: Fri, 1 Dec 2023 12:30:53 +0100 Subject: [PATCH] Improve curve-prices usage Only use prices that arent stale --- pages/api/getPools/index.js | 35 +++++++++++++++++++++++++++++++++-- utils/data/curve-prices.js | 19 +++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/pages/api/getPools/index.js b/pages/api/getPools/index.js index 2710e975..110f3e1f 100644 --- a/pages/api/getPools/index.js +++ b/pages/api/getPools/index.js @@ -78,6 +78,9 @@ const IGNORED_COINS = { polygon: [ '0x8dacf090f8803f53ee3c44f0d7a07b9d70453c42', // spam ].map(lc), + ethereum: [ + '0xc7D9c108D4E1dD1484D3e2568d7f74bfD763d356', // depegged stable, incorrect price on defillama + ].map(lc), }; // Tokens for which to use Defillama as external price oracle @@ -437,6 +440,24 @@ const getPools = async ({ blockchainId, registryId, preventQueryingFactoData }) poolUsdTotalB > poolUsdTotalA ? 1 : 0 ))[0].usdPrice, ])); + } else { + const METAPOOL_REGISTRIES_DEPENDENCIES = { + main: [], + default: ['main'], + }; + + const metapoolRegistryDependencies = ( + METAPOOL_REGISTRIES_DEPENDENCIES[registryId] || + METAPOOL_REGISTRIES_DEPENDENCIES.default + ); + + otherRegistryPoolsData = await sequentialPromiseFlatMap(metapoolRegistryDependencies, async (id) => ( + // eslint-disable-next-line no-use-before-define + (await getPoolsFn.straightCall({ blockchainId, registryId: id, preventQueryingFactoData: true })).poolData.map((poolData) => ({ + ...poolData, + registryId: id, + })) + )); } const poolDataWithTries = await multiCall(flattenArray(poolAddresses.map((address, i) => { @@ -996,7 +1017,13 @@ const getPools = async ({ blockchainId, registryId, preventQueryingFactoData }) let missingCoinPrices; if (USE_CURVE_PRICES_DATA) { - const coinsAddressesWithMissingPrices = uniq(Array.from(Object.values(mergedCoinData)).filter(({ usdPrice }) => usdPrice === null).map(({ address }) => lc(address))); + const coinsAddressesWithMissingPrices = uniq(Array.from(Object.values(mergedCoinData)).filter(({ + address, + usdPrice, + }) => ( + !IGNORED_COINS[blockchainId].includes(lc(address)) && + usdPrice === null + )).map(({ address }) => lc(address))); missingCoinPrices = await getTokensPrices(coinsAddressesWithMissingPrices, blockchainId); } @@ -1123,7 +1150,7 @@ const getPools = async ({ blockchainId, registryId, preventQueryingFactoData }) // here need to be able to retrieve from getPools/ethereum/base-pools, a special endpoint that returns only base pools, so it can be a cheap dependency const underlyingPool = ( isMetaPool ? ( - [...wipMergedPoolData, ...(USE_CURVE_PRICES_DATA ? [] : otherRegistryPoolsData)].find(({ lpTokenAddress, address }) => ( + [...wipMergedPoolData, ...otherRegistryPoolsData].find(({ lpTokenAddress, address }) => ( (lpTokenAddress || address).toLowerCase() === metaPoolBasePoolLpToken.address.toLowerCase() )) ) : undefined @@ -1241,6 +1268,10 @@ const getPools = async ({ blockchainId, registryId, preventQueryingFactoData }) const usesRateOracle = Number(poolInfo.oracleMethod) !== 0; const ethereumLSDAPYs = (blockchainId === 'ethereum') ? (await getETHLSDAPYs()) : {}; + if (isMetaPool && typeof underlyingPool === 'undefined') { + throw new Error(`Pool ${poolInfo.address} is a meta pool, yet we couldn’t retrieve its underlying pool. Please check METAPOOL_REGISTRIES_DEPENDENCIES, its base pool’s registry is likely missing.`) + } + const augmentedPool = { ...poolInfo, poolUrls: detailedPoolUrls, diff --git a/utils/data/curve-prices.js b/utils/data/curve-prices.js index 6d4db13e..80c40da8 100644 --- a/utils/data/curve-prices.js +++ b/utils/data/curve-prices.js @@ -2,6 +2,7 @@ import memoize from 'memoizee'; import Request from 'utils/Request'; import { arrayToHashmap } from 'utils/Array'; import { lc } from 'utils/String'; +import { getNowTimestamp } from 'utils/Date'; const IGNORED_TOKEN_ADDRESSES = { ethereum: [ @@ -25,10 +26,20 @@ const getCurvePrices = memoize(async (blockchainId) => { const { data } = await (await Request.get(`https://prices.curve.fi/v1/usd_price/${blockchainId}`)).json(); return arrayToHashmap( - data.map(({ address, usd_price }) => [ - lc(address), - usd_price, - ]).filter(([lcAddress]) => !(IGNORED_TOKEN_ADDRESSES[blockchainId] || []).includes(lcAddress)) + data + // Only use fresh prices (last updated in the past 7d, i.e. had a trade in the past 7d) + .filter(({ last_updated }) => ( + // Append 'Z' because this is a UTC datetime string + (Date.parse(`${last_updated}Z`) / 1000) > (getNowTimestamp() - (7 * 86400)) + )) + .map(({ + address, + usd_price, + }) => [ + lc(address), + usd_price, + ]) + .filter(([lcAddress]) => !(IGNORED_TOKEN_ADDRESSES[blockchainId] || []).includes(lcAddress)) ); }, { promise: true,