diff --git a/api/_utils.ts b/api/_utils.ts index ded372730..95bd9659f 100644 --- a/api/_utils.ts +++ b/api/_utils.ts @@ -84,6 +84,7 @@ import { TokenNotFoundError, } from "./_errors"; import { Token } from "./_dexes/types"; +import { CoingeckoQueryParams } from "./coingecko"; import { addMarkupToAmount } from "./_dexes/uniswap/utils"; export { InputError, handleErrorCondition } from "./_errors"; @@ -777,20 +778,16 @@ export const buildDepositForSimulation = (depositArgs: { * @param date An optional date string in the format of `DD-MM-YYYY` to resolve a historical price * @returns The price of the `l1Token` token. */ -export const getCachedTokenPrice = async ( - l1Token: string, - baseCurrency: string = "eth", - historicalDateISO?: string, - chainId?: number -): Promise => { +export const getCachedTokenPrice = async ({ + baseCurrency = "eth", + ...params +}: CoingeckoQueryParams): Promise => { return Number( ( await axios(`${resolveVercelEndpoint()}/api/coingecko`, { params: { - l1Token, - chainId, baseCurrency, - date: historicalDateISO, + ...params, }, }) ).data.price @@ -1775,9 +1772,15 @@ export async function fetchStakingPool( const [acrossTokenAddress, tokenUSDExchangeRate] = await Promise.all([ acceleratingDistributor.rewardToken(), - getCachedTokenPrice(poolUnderlyingTokenAddress, "usd"), + getCachedTokenPrice({ + l1Token: poolUnderlyingTokenAddress, + baseCurrency: "usd", + }), ]); - const acxPriceInUSD = await getCachedTokenPrice(acrossTokenAddress, "usd"); + const acxPriceInUSD = await getCachedTokenPrice({ + l1Token: acrossTokenAddress, + baseCurrency: "usd", + }); const lpTokenERC20 = ERC20__factory.connect(lpTokenAddress, provider); @@ -1968,7 +1971,7 @@ export async function getBalancerV2TokenPrice( tokens.map(async (token: string, i: number): Promise => { const tokenContract = ERC20__factory.connect(token, provider); const [price, decimals] = await Promise.all([ - getCachedTokenPrice(token, "usd"), + getCachedTokenPrice({ l1Token: token, baseCurrency: "usd" }), tokenContract.decimals(), ]); const balance = parseFloat( diff --git a/api/coingecko.ts b/api/coingecko.ts index 5fe4d58f5..ac6358d29 100644 --- a/api/coingecko.ts +++ b/api/coingecko.ts @@ -10,6 +10,7 @@ import { getCachedTokenPrice, parseQuery, positiveInt, + boolStr, } from "./_utils"; import { CG_CONTRACTS_DEFERRED_TO_ID, @@ -35,10 +36,11 @@ const CoingeckoQueryParamsSchema = object({ tokenAddress: optional(validAddress()), chainId: optional(positiveInt), baseCurrency: optional(string()), + findById: optional(boolStr()), // Tells CG client to find the token price by ID (more reliable) date: optional(pattern(string(), /\d{2}-\d{2}-\d{4}/)), }); -type CoingeckoQueryParams = Infer; +export type CoingeckoQueryParams = Infer; const handler = async ( { query }: TypedVercelRequest, @@ -56,6 +58,7 @@ const handler = async ( tokenAddress, chainId, baseCurrency, + findById, date: dateStr, } = parseQuery(query, CoingeckoQueryParamsSchema); @@ -140,16 +143,18 @@ const handler = async ( chainId ); } else { - [, price] = CG_CONTRACTS_DEFERRED_TO_ID.has(address) - ? await coingeckoClient.getCurrentPriceById( - address, - modifiedBaseCurrency - ) - : await coingeckoClient.getCurrentPriceByContract( - address, - modifiedBaseCurrency, - chainId - ); + [, price] = + CG_CONTRACTS_DEFERRED_TO_ID.has(address) || findById + ? await coingeckoClient.getCurrentPriceById( + address, + modifiedBaseCurrency, + chainId + ) + : await coingeckoClient.getCurrentPriceByContract( + address, + modifiedBaseCurrency, + chainId + ); } } @@ -162,10 +167,10 @@ const handler = async ( TOKEN_SYMBOLS_MAP[ baseCurrency.toUpperCase() as keyof typeof TOKEN_SYMBOLS_MAP ]; - quotePrice = await getCachedTokenPrice( - token.addresses[CHAIN_IDs.MAINNET], - "usd" - ); + quotePrice = await getCachedTokenPrice({ + l1Token: token.addresses[CHAIN_IDs.MAINNET], + baseCurrency: "usd", + }); quotePrecision = token.decimals; } price = Number((price / quotePrice).toFixed(quotePrecision)); diff --git a/api/limits.ts b/api/limits.ts index 2714d9d2b..9d39b322d 100644 --- a/api/limits.ts +++ b/api/limits.ts @@ -166,11 +166,13 @@ const handler = async ( const [tokenPriceNative, _tokenPriceUsd, latestBlock, gasUnits, gasPrice] = await Promise.all([ - getCachedTokenPrice( - l1Token.address, - sdk.utils.getNativeTokenSymbol(destinationChainId).toLowerCase() - ), - getCachedTokenPrice(l1Token.address, "usd"), + getCachedTokenPrice({ + l1Token: l1Token.address, + baseCurrency: sdk.utils + .getNativeTokenSymbol(destinationChainId) + .toLowerCase(), + }), + getCachedTokenPrice({ l1Token: l1Token.address, baseCurrency: "usd" }), getCachedLatestBlock(HUB_POOL_CHAIN_ID), // Only use cached gas units if message is not defined, i.e. standard for standard bridges isMessageDefined diff --git a/api/suggested-fees.ts b/api/suggested-fees.ts index ceb724057..67e5808f9 100644 --- a/api/suggested-fees.ts +++ b/api/suggested-fees.ts @@ -188,7 +188,7 @@ const handler = async ( limits, ] = await Promise.all([ callViaMulticall3(provider, multiCalls, { blockTag: quoteBlockNumber }), - getCachedTokenPrice(l1Token.address, "usd"), + getCachedTokenPrice({ l1Token: l1Token.address, baseCurrency: "usd" }), getCachedLimits( inputToken.address, outputToken.address, diff --git a/api/swap/_utils.ts b/api/swap/_utils.ts index bde17a64a..18237320a 100644 --- a/api/swap/_utils.ts +++ b/api/swap/_utils.ts @@ -131,12 +131,12 @@ export async function handleBaseSwapQueryParams({ }); // 3. Calculate fees based for full route - // const fees = await calculateCrossSwapFees(crossSwapQuotes); + const fees = await calculateCrossSwapFees(crossSwapQuotes); return { crossSwapQuotes: { ...crossSwapQuotes, - // fees, + fees, }, integratorId, skipOriginTxEstimation, @@ -178,18 +178,18 @@ async function calculateSwapFee( ): Promise> { const { tokenIn, tokenOut, expectedAmountOut, expectedAmountIn } = swapQuote; const [inputTokenPriceBase, outputTokenPriceBase] = await Promise.all([ - getCachedTokenPrice( - tokenIn.address, + getCachedTokenPrice({ + tokenAddress: tokenIn.address, baseCurrency, - undefined, - tokenIn.chainId - ), - getCachedTokenPrice( - tokenOut.address, + chainId: tokenIn.chainId, + findById: "true", + }), + getCachedTokenPrice({ + tokenAddress: tokenOut.address, baseCurrency, - undefined, - tokenOut.chainId - ), + chainId: tokenOut.chainId, + findById: "true", + }), ]); const normalizedIn = @@ -208,12 +208,12 @@ async function calculateBridgeFee( baseCurrency: string ): Promise> { const { inputToken, suggestedFees } = bridgeQuote; - const inputTokenPriceBase = await getCachedTokenPrice( - inputToken.address, + const inputTokenPriceBase = await getCachedTokenPrice({ + tokenAddress: inputToken.address, baseCurrency, - undefined, - inputToken.chainId - ); + chainId: inputToken.chainId, + findById: "true", + }); const normalizedFee = parseFloat( formatUnits(suggestedFees.totalRelayFee.total, inputToken.decimals) diff --git a/api/swap/allowance.ts b/api/swap/allowance.ts index 43c0013cd..bdace9f82 100644 --- a/api/swap/allowance.ts +++ b/api/swap/allowance.ts @@ -104,7 +104,7 @@ const handler = async ( : bridgeQuote.outputToken; const responseJson = { - // fees: crossSwapQuotes.fees, + fees: crossSwapQuotes.fees, checks: { allowance: { token: inputTokenAddress, diff --git a/scripts/tests/swap-allowance.ts b/scripts/tests/swap-allowance.ts index a32311ccd..9f19edcd7 100644 --- a/scripts/tests/swap-allowance.ts +++ b/scripts/tests/swap-allowance.ts @@ -21,7 +21,7 @@ const MIN_OUTPUT_CASES = [ { labels: ["B2B", "MIN_OUTPUT", "USDC - USDC"], params: { - amount: ethers.utils.parseUnits("1", 6).toString(), + amount: ethers.utils.parseUnits("10", 6).toString(), tradeType: "minOutput", inputToken: TOKEN_SYMBOLS_MAP.USDC.addresses[originChainId], originChainId,