From 7131da3f59254b8029047318e1373a01630b4a5c Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Sun, 26 Jan 2025 16:46:46 +0100 Subject: [PATCH] fix: fix tanstack query caching with price calculations --- lib/price/AbstractPriceStrategy.ts | 6 +++--- lib/price/AggregatePriceStrategy.ts | 4 ++-- lib/price/PriceStrategy.ts | 4 ++-- lib/price/UniswapV2PriceStrategy.ts | 2 +- lib/price/UniswapV3PriceStrategy.ts | 2 +- lib/price/UniswapV3ReadonlyPriceStrategy.ts | 2 +- lib/price/utils.ts | 16 ++++++++-------- lib/utils/formatting.ts | 10 ++++++++-- lib/utils/tokens.ts | 4 ++-- 9 files changed, 28 insertions(+), 22 deletions(-) diff --git a/lib/price/AbstractPriceStrategy.ts b/lib/price/AbstractPriceStrategy.ts index 7e431f27a..eb3eb8baf 100644 --- a/lib/price/AbstractPriceStrategy.ts +++ b/lib/price/AbstractPriceStrategy.ts @@ -18,7 +18,7 @@ export abstract class AbstractPriceStrategy implements PriceStrategy { this.supportedAssets = options.supportedAssets; } - public async calculateNativeTokenPrice(publicClient: PublicClient): Promise { + public async calculateNativeTokenPrice(publicClient: PublicClient): Promise { if (!this.nativeAsset) { throw new Error('Native token type is not supported by this price strategy'); } @@ -32,7 +32,7 @@ export abstract class AbstractPriceStrategy implements PriceStrategy { return tokenPrice; } - public calculateTokenPrice(tokenContract: TokenContract): Promise { + public calculateTokenPrice(tokenContract: TokenContract): Promise { if (!strategySupportsToken(this, tokenContract)) { throw new Error('Token type is not supported by this price strategy'); } @@ -40,5 +40,5 @@ export abstract class AbstractPriceStrategy implements PriceStrategy { return this.calculateTokenPriceInternal(tokenContract); } - protected abstract calculateTokenPriceInternal(tokenContract: TokenContract): Promise; + protected abstract calculateTokenPriceInternal(tokenContract: TokenContract): Promise; } diff --git a/lib/price/AggregatePriceStrategy.ts b/lib/price/AggregatePriceStrategy.ts index 7146ac24e..065c4a6a9 100644 --- a/lib/price/AggregatePriceStrategy.ts +++ b/lib/price/AggregatePriceStrategy.ts @@ -31,12 +31,12 @@ export class AggregatePriceStrategy implements PriceStrategy { // Note: we only use the first strategy to calculate the native token price, so we only need to make sure that // the first strategy is able to calculate the native token price - public async calculateNativeTokenPrice(publicClient: PublicClient): Promise { + public async calculateNativeTokenPrice(publicClient: PublicClient): Promise { if (this.strategies.length === 0) throw new Error('No strategies provided'); return this.strategies[0].calculateNativeTokenPrice(publicClient); } - public async calculateTokenPrice(tokenContract: TokenContract): Promise { + public async calculateTokenPrice(tokenContract: TokenContract): Promise { const supportedStrategies = this.getSupportedStrategies(tokenContract); if (supportedStrategies.length === 0) throw new Error('No supported strategies provided for this token type'); diff --git a/lib/price/PriceStrategy.ts b/lib/price/PriceStrategy.ts index c4a337a8d..8ae34e443 100644 --- a/lib/price/PriceStrategy.ts +++ b/lib/price/PriceStrategy.ts @@ -3,6 +3,6 @@ import type { PublicClient } from 'viem'; export interface PriceStrategy { supportedAssets: TokenStandard[]; - calculateNativeTokenPrice: (publicClient: PublicClient) => Promise; - calculateTokenPrice: (tokenContract: TokenContract) => Promise; + calculateNativeTokenPrice: (publicClient: PublicClient) => Promise; + calculateTokenPrice: (tokenContract: TokenContract) => Promise; } diff --git a/lib/price/UniswapV2PriceStrategy.ts b/lib/price/UniswapV2PriceStrategy.ts index d6c88cb2b..6d42e0961 100644 --- a/lib/price/UniswapV2PriceStrategy.ts +++ b/lib/price/UniswapV2PriceStrategy.ts @@ -50,7 +50,7 @@ export class UniswapV2PriceStrategy extends AbstractPriceStrategy implements Pri this.fee = options.feeParameters?.fee ?? []; } - protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { + protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { if (tokenContract.address === this.path.at(-1)) { return 1; } diff --git a/lib/price/UniswapV3PriceStrategy.ts b/lib/price/UniswapV3PriceStrategy.ts index 3601d3cac..c9030d358 100644 --- a/lib/price/UniswapV3PriceStrategy.ts +++ b/lib/price/UniswapV3PriceStrategy.ts @@ -30,7 +30,7 @@ export class UniswapV3PriceStrategy extends AbstractPriceStrategy implements Pri this.decimals = options.decimals ?? 18; } - protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { + protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { if (tokenContract.address === this.path.at(-1)) { // return parseUnits(String(1), this.decimals); diff --git a/lib/price/UniswapV3ReadonlyPriceStrategy.ts b/lib/price/UniswapV3ReadonlyPriceStrategy.ts index b0e9e07bc..3e9c492be 100644 --- a/lib/price/UniswapV3ReadonlyPriceStrategy.ts +++ b/lib/price/UniswapV3ReadonlyPriceStrategy.ts @@ -43,7 +43,7 @@ export class UniswapV3ReadonlyPriceStrategy extends UniswapV3PriceStrategy { this.minLiquidity = options.liquidityParameters?.minLiquidity ?? 10n ** 17n; } - protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { + protected async calculateTokenPriceInternal(tokenContract: Erc20TokenContract): Promise { if (tokenContract.address === this.path.at(-1)) { return 1; } diff --git a/lib/price/utils.ts b/lib/price/utils.ts index 3200a5058..49dfe13d8 100644 --- a/lib/price/utils.ts +++ b/lib/price/utils.ts @@ -4,30 +4,30 @@ import { type TokenContract, isErc721Contract } from 'lib/utils/tokens'; import { type PublicClient, formatUnits } from 'viem'; import type { PriceStrategy } from './PriceStrategy'; -export const calculateTokenPrice = (inversePrice: bigint | null, tokenDecimals: number): number | undefined => { - return isNullish(inversePrice) ? undefined : 1 / Number.parseFloat(formatUnits(inversePrice, tokenDecimals)); +export const calculateTokenPrice = (inversePrice: bigint | null, tokenDecimals: number): number | null => { + return isNullish(inversePrice) ? null : 1 / Number.parseFloat(formatUnits(inversePrice, tokenDecimals)); }; -export const getNativeTokenPrice = async (chainId: number, publicClient: PublicClient): Promise => { +export const getNativeTokenPrice = async (chainId: number, publicClient: PublicClient): Promise => { const strategy = getChainPriceStrategy(chainId); - if (!strategy) return undefined; + if (!strategy) return null; try { return await strategy.calculateNativeTokenPrice(publicClient); } catch { - return undefined; + return null; } }; -export const getTokenPrice = async (chainId: number, tokenContract: TokenContract): Promise => { +export const getTokenPrice = async (chainId: number, tokenContract: TokenContract): Promise => { const strategy = getChainPriceStrategy(chainId); - if (!strategy || !strategySupportsToken(strategy, tokenContract)) return undefined; + if (!strategy || !strategySupportsToken(strategy, tokenContract)) return null; try { return await strategy.calculateTokenPrice(tokenContract); } catch { - return undefined; + return null; } }; diff --git a/lib/utils/formatting.ts b/lib/utils/formatting.ts index a8898684c..30b9ab3c2 100644 --- a/lib/utils/formatting.ts +++ b/lib/utils/formatting.ts @@ -48,10 +48,16 @@ export const formatBalance = (symbol: string, balance: TokenBalance, decimals?: return `${formatFixedPointBigInt(balance, decimals)} ${symbol}`; }; -export const formatFiatBalance = (balance: TokenBalance, price?: number, decimals?: number, fiatSign: string = '$') => { +export const formatFiatBalance = ( + balance: TokenBalance, + price?: Nullable, + decimals?: number, + fiatSign: string = '$', +) => { if (balance === 'ERC1155') return null; if (isNullish(price)) return null; - return formatFiatAmount(Number(formatUnits(fixedPointMultiply(balance, price, decimals ?? 18), decimals ?? 18))); + const amount = Number(formatUnits(fixedPointMultiply(balance, price, decimals ?? 18), decimals ?? 18)); + return formatFiatAmount(amount, decimals, fiatSign); }; export const formatFiatAmount = ( diff --git a/lib/utils/tokens.ts b/lib/utils/tokens.ts index c1c80461f..b5bb3c44c 100644 --- a/lib/utils/tokens.ts +++ b/lib/utils/tokens.ts @@ -1,6 +1,6 @@ import { ERC20_ABI, ERC721_ABI } from 'lib/abis'; import { DUMMY_ADDRESS, DUMMY_ADDRESS_2, WHOIS_BASE_URL } from 'lib/constants'; -import type { Contract } from 'lib/interfaces'; +import type { Contract, Nullable } from 'lib/interfaces'; import ky from 'lib/ky'; import { getTokenPrice } from 'lib/price/utils'; import { @@ -47,7 +47,7 @@ export interface TokenMetadata { icon?: string; decimals?: number; totalSupply?: bigint; - price?: number; + price?: Nullable; } export type TokenBalance = bigint | 'ERC1155';