From 731d200bf54e43d3d4246b5410d4836cd6cf4944 Mon Sep 17 00:00:00 2001 From: immasandwich Date: Sun, 10 Dec 2023 21:45:41 -0500 Subject: [PATCH] feat(studio): Eliminate dependencies on subgraphs for volume (#3120) --- src/apps/balancer-v1/balancer-v1.module.ts | 7 +- .../common/balancer-v1.volume.data-loader.ts | 58 --------- .../balancer-v1.pool.token-fetcher.ts | 23 +--- .../balancer-v1.volume.data-loader.ts | 11 -- ...curve.factory-crypto-pool.token-fetcher.ts | 2 - ...curve.factory-stable-pool.token-fetcher.ts | 2 - .../curve.tricrypto-pool.token-fetcher.ts | 2 - .../curve.pool-dynamic-v2.token-fetcher.ts | 26 +--- .../curve.pool-dynamic.token-fetcher.ts | 15 +-- ...tic.liquidity.contract-position-fetcher.ts | 11 +- ...v2.pool.subgraph.template.token-fetcher.ts | 117 +----------------- .../ethereum/uniswap-v2.pool.token-fetcher.ts | 26 ---- src/multicall/impl/multicall.ethers.ts | 2 +- 13 files changed, 11 insertions(+), 291 deletions(-) delete mode 100644 src/apps/balancer-v1/common/balancer-v1.volume.data-loader.ts delete mode 100644 src/apps/balancer-v1/ethereum/balancer-v1.volume.data-loader.ts diff --git a/src/apps/balancer-v1/balancer-v1.module.ts b/src/apps/balancer-v1/balancer-v1.module.ts index 4efbeda51..10bac00aa 100644 --- a/src/apps/balancer-v1/balancer-v1.module.ts +++ b/src/apps/balancer-v1/balancer-v1.module.ts @@ -4,13 +4,8 @@ import { AbstractApp } from '~app/app.dynamic-module'; import { BalancerV1ViemContractFactory } from './contracts'; import { EthereumBalancerV1PoolTokenFetcher } from './ethereum/balancer-v1.pool.token-fetcher'; -import { EthereumBalancerV1PoolSubgraphVolumeDataLoader } from './ethereum/balancer-v1.volume.data-loader'; @Module({ - providers: [ - BalancerV1ViemContractFactory, - EthereumBalancerV1PoolTokenFetcher, - EthereumBalancerV1PoolSubgraphVolumeDataLoader, - ], + providers: [BalancerV1ViemContractFactory, EthereumBalancerV1PoolTokenFetcher], }) export class BalancerV1AppModule extends AbstractApp() {} diff --git a/src/apps/balancer-v1/common/balancer-v1.volume.data-loader.ts b/src/apps/balancer-v1/common/balancer-v1.volume.data-loader.ts deleted file mode 100644 index 6d458de4d..000000000 --- a/src/apps/balancer-v1/common/balancer-v1.volume.data-loader.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Inject } from '@nestjs/common'; -import DataLoader from 'dataloader'; -import { gql } from 'graphql-request'; - -import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; -import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; -import { Network } from '~types/network.interface'; - -const GET_POOL_VOLUMES_QUERY = gql` - query getPoolVolumes($addresses: [String!], $tsYesterday: Int) { - pools(where: { id_in: $addresses }) { - id - totalSwapVolume - swaps(first: 1, orderBy: "timestamp", orderDirection: "desc", where: { timestamp_lte: $tsYesterday }) { - poolTotalSwapVolume - } - } - } -`; - -type GetPoolVolumesResponse = { - pools: { - id: string; - totalSwapVolume: string; - swaps: { - poolTotalSwapVolume: string; - }[]; - }[]; -}; - -export abstract class BalancerV1PoolSubgraphVolumeDataLoader { - abstract network: Network; - abstract subgraphUrl: string; - - constructor(@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit) {} - - getLoader() { - const dataLoaderOptions = { cache: true, maxBatchSize: 1000 }; - return new DataLoader(this.batchGetVolume.bind(this), dataLoaderOptions); - } - - private async batchGetVolume(addresses: string[]) { - const ts = Math.round(new Date().getTime() / 1000); - const tsYesterday = ts - 24 * 3600; - - const volumeResponse = await gqlFetch({ - endpoint: this.subgraphUrl, - query: GET_POOL_VOLUMES_QUERY, - variables: { tsYesterday, addresses }, - }); - - return addresses.map(address => { - const pool = volumeResponse.pools.find(p => p.id === address); - if (!pool || !pool.totalSwapVolume.length) return 0; - return Number(pool.totalSwapVolume) - Number(pool.swaps[0].poolTotalSwapVolume); - }); - } -} diff --git a/src/apps/balancer-v1/ethereum/balancer-v1.pool.token-fetcher.ts b/src/apps/balancer-v1/ethereum/balancer-v1.pool.token-fetcher.ts index e07db50f8..6ae1d0814 100644 --- a/src/apps/balancer-v1/ethereum/balancer-v1.pool.token-fetcher.ts +++ b/src/apps/balancer-v1/ethereum/balancer-v1.pool.token-fetcher.ts @@ -1,5 +1,4 @@ import { Inject } from '@nestjs/common'; -import DataLoader from 'dataloader'; import { gql } from 'graphql-request'; import { sum } from 'lodash'; @@ -25,8 +24,6 @@ import { import { BalancerV1ViemContractFactory } from '../contracts'; import { BalancerPoolToken } from '../contracts/viem'; -import { EthereumBalancerV1PoolSubgraphVolumeDataLoader } from './balancer-v1.volume.data-loader'; - type GetAllPoolsData = { pools: { id: string; @@ -54,13 +51,9 @@ export class EthereumBalancerV1PoolTokenFetcher extends AppTokenTemplatePosition > { groupLabel = 'Pools'; - volumeDataLoader: DataLoader; - constructor( @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, @Inject(BalancerV1ViemContractFactory) protected readonly contractFactory: BalancerV1ViemContractFactory, - @Inject(EthereumBalancerV1PoolSubgraphVolumeDataLoader) - protected readonly volumeDataLoaderBuilder: EthereumBalancerV1PoolSubgraphVolumeDataLoader, ) { super(appToolkit); } @@ -70,8 +63,6 @@ export class EthereumBalancerV1PoolTokenFetcher extends AppTokenTemplatePosition } async getAddresses() { - this.volumeDataLoader = this.volumeDataLoaderBuilder.getLoader(); - const poolsFromSubgraph = await gqlFetch({ endpoint: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer?source=zapper', query: getPoolsQuery, @@ -103,16 +94,6 @@ export class EthereumBalancerV1PoolTokenFetcher extends AppTokenTemplatePosition return liquidity; } - async getApy({ appToken, contract }: GetDataPropsParams) { - const fee = (Number(await contract.read.getSwapFee()) / 10 ** 18) * 100; - const volume = await this.volumeDataLoader.load(appToken.address); - const yearlyFees = volume * fee * 365; - const reserves = (appToken.pricePerShare as number[]).map(pps => pps * appToken.supply); - const liquidity = sum(reserves.map((r, i) => r * appToken.tokens[i].price)); - const apy = yearlyFees / liquidity; - return apy; - } - async getDataProps(params: GetDataPropsParams) { const defaultDataProps = await super.getDataProps(params); @@ -120,9 +101,8 @@ export class EthereumBalancerV1PoolTokenFetcher extends AppTokenTemplatePosition const fee = (Number(await contract.read.getSwapFee()) / 10 ** 18) * 100; const weightsRaw = await Promise.all(appToken.tokens.map(t => contract.read.getNormalizedWeight([t.address]))); const weight = weightsRaw.map(w => Number(w) / 10 ** 18); - const volume = await this.volumeDataLoader.load(appToken.address); - return { ...defaultDataProps, fee, volume, weight }; + return { ...defaultDataProps, fee, weight }; } async getLabel({ @@ -143,7 +123,6 @@ export class EthereumBalancerV1PoolTokenFetcher extends AppTokenTemplatePosition return [ { label: 'Liquidity', value: buildDollarDisplayItem(appToken.dataProps.liquidity) }, { label: 'Supply', value: buildNumberDisplayItem(appToken.supply) }, - { label: 'Volume', value: buildDollarDisplayItem(appToken.dataProps.volume) }, { label: 'Fee', value: buildPercentageDisplayItem(appToken.dataProps.fee) }, { label: 'Ratio', value: appToken.dataProps.weight.map(p => `${Math.round(p * 100)}%`).join(' / ') }, ]; diff --git a/src/apps/balancer-v1/ethereum/balancer-v1.volume.data-loader.ts b/src/apps/balancer-v1/ethereum/balancer-v1.volume.data-loader.ts deleted file mode 100644 index b23421214..000000000 --- a/src/apps/balancer-v1/ethereum/balancer-v1.volume.data-loader.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { Network } from '~types/network.interface'; - -import { BalancerV1PoolSubgraphVolumeDataLoader } from '../common/balancer-v1.volume.data-loader'; - -@Injectable() -export class EthereumBalancerV1PoolSubgraphVolumeDataLoader extends BalancerV1PoolSubgraphVolumeDataLoader { - network = Network.ETHEREUM_MAINNET; - subgraphUrl = 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer?source=zapper'; -} diff --git a/src/apps/curve/base/curve.factory-crypto-pool.token-fetcher.ts b/src/apps/curve/base/curve.factory-crypto-pool.token-fetcher.ts index b549ffadb..3238d2546 100644 --- a/src/apps/curve/base/curve.factory-crypto-pool.token-fetcher.ts +++ b/src/apps/curve/base/curve.factory-crypto-pool.token-fetcher.ts @@ -6,6 +6,4 @@ import { CurveFactoryCryptoPoolTokenFetcher } from '../common/curve.factory-cryp export class BaseCurveFactoryCryptoPoolTokenFetcher extends CurveFactoryCryptoPoolTokenFetcher { groupLabel = 'Pools'; registryAddress = '0x5ef72230578b3e399e6c6f4f6360edf95e83bbfd'; - - skipVolume = true; } diff --git a/src/apps/curve/base/curve.factory-stable-pool.token-fetcher.ts b/src/apps/curve/base/curve.factory-stable-pool.token-fetcher.ts index 3348ade50..2a1ebecba 100644 --- a/src/apps/curve/base/curve.factory-stable-pool.token-fetcher.ts +++ b/src/apps/curve/base/curve.factory-stable-pool.token-fetcher.ts @@ -6,6 +6,4 @@ import { CurveFactoryStablePoolTokenFetcher } from '../common/curve.factory-stab export class BaseCurveFactoryStablePoolTokenFetcher extends CurveFactoryStablePoolTokenFetcher { groupLabel = 'Pools'; registryAddress = '0x3093f9b57a428f3eb6285a589cb35bea6e78c336'; - - skipVolume = true; } diff --git a/src/apps/curve/base/curve.tricrypto-pool.token-fetcher.ts b/src/apps/curve/base/curve.tricrypto-pool.token-fetcher.ts index 36a7ae2ae..d929e9d52 100644 --- a/src/apps/curve/base/curve.tricrypto-pool.token-fetcher.ts +++ b/src/apps/curve/base/curve.tricrypto-pool.token-fetcher.ts @@ -6,6 +6,4 @@ import { CurveFactoryV2PoolTokenFetcher } from '../common/curve.factory-pool-v2. export class BaseCurveTricryptoPoolTokenFetcher extends CurveFactoryV2PoolTokenFetcher { groupLabel = 'Pools'; factoryAddress = '0xa5961898870943c68037f6848d2d866ed2016bcb'; - - skipVolume = true; } diff --git a/src/apps/curve/common/curve.pool-dynamic-v2.token-fetcher.ts b/src/apps/curve/common/curve.pool-dynamic-v2.token-fetcher.ts index e0e27f0b2..8f9d51047 100644 --- a/src/apps/curve/common/curve.pool-dynamic-v2.token-fetcher.ts +++ b/src/apps/curve/common/curve.pool-dynamic-v2.token-fetcher.ts @@ -1,5 +1,4 @@ import { Inject } from '@nestjs/common'; -import DataLoader from 'dataloader'; import { BigNumberish } from 'ethers'; import { compact, range } from 'lodash'; import { Abi, GetContractReturnType, PublicClient } from 'viem'; @@ -61,13 +60,9 @@ export abstract class CurvePoolDynamicV2TokenFetcher extends AppT CurveTricryptoPool, CurvePoolTokenDataProps > { - volumeDataLoader: DataLoader; - abstract factoryAddress: string; blacklistedTokenAddresses: string[] = []; - skipVolume = false; - abstract resolveFactory(address: string): GetContractReturnType; abstract resolvePoolCount(params: ResolvePoolCountParams): Promise; abstract resolveTokenAddress(params: ResolveTokenAddressParams): Promise; @@ -87,10 +82,6 @@ export abstract class CurvePoolDynamicV2TokenFetcher extends AppT } async getDefinitions({ multicall }: GetDefinitionsParams) { - if (!this.skipVolume) { - this.volumeDataLoader = this.curveVolumeDataLoader.getLoader({ network: this.network }); - } - const contract = multicall.wrap(this.resolveFactory(this.factoryAddress)); const poolCount = await this.resolvePoolCount({ contract, multicall }); const poolRange = range(0, Number(poolCount)); @@ -143,20 +134,11 @@ export abstract class CurvePoolDynamicV2TokenFetcher extends AppT async getDataProps(params: GetDataPropsParams) { const defaultDataProps = await super.getDataProps(params); - const { contract, definition } = params; - let fee: number; - - try { - const fees = await contract.read.fee(); - fee = Number(fees) / 10 ** 8; - } catch { - fee = 0; - } - const volume = this.skipVolume == false ? await this.volumeDataLoader.load(definition.address) : 0; - const feeVolume = fee * volume; - const apy = defaultDataProps.liquidity > 0 ? (feeVolume / defaultDataProps.liquidity) * 365 : 0; + const { contract } = params; + const feeRaw = await contract.read.fee().catch(() => 0); + const fee = Number(feeRaw) / 10 ** 10; - return { ...defaultDataProps, fee, volume, apy }; + return { ...defaultDataProps, fee }; } async getLabel({ appToken }: GetDisplayPropsParams) { diff --git a/src/apps/curve/common/curve.pool-dynamic.token-fetcher.ts b/src/apps/curve/common/curve.pool-dynamic.token-fetcher.ts index 43326742c..bb5cd4a04 100644 --- a/src/apps/curve/common/curve.pool-dynamic.token-fetcher.ts +++ b/src/apps/curve/common/curve.pool-dynamic.token-fetcher.ts @@ -1,5 +1,4 @@ import { Inject } from '@nestjs/common'; -import DataLoader from 'dataloader'; import { BigNumberish } from 'ethers'; import { compact, range } from 'lodash'; import { Abi, GetContractReturnType, PublicClient } from 'viem'; @@ -80,13 +79,9 @@ export abstract class CurvePoolDynamicTokenFetcher extends AppTok CurvePoolTokenDataProps, CurvePoolDefinition > { - volumeDataLoader: DataLoader; - abstract registryAddress: string; blacklistedSwapAddresses: string[] = []; - skipVolume = false; - abstract resolveRegistry(address: string): GetContractReturnType; abstract resolvePoolCount(params: ResolvePoolCountParams): Promise; abstract resolveSwapAddress(params: ResolveSwapAddressParams): Promise; @@ -108,10 +103,6 @@ export abstract class CurvePoolDynamicTokenFetcher extends AppTok } async getDefinitions({ multicall }: GetDefinitionsParams) { - if (!this.skipVolume) { - this.volumeDataLoader = this.curveVolumeDataLoader.getLoader({ network: this.network }); - } - const contract = multicall.wrap(this.resolveRegistry(this.registryAddress)); const poolCount = await this.resolvePoolCount({ contract, multicall }); const poolRange = range(0, Number(poolCount)); @@ -175,11 +166,7 @@ export abstract class CurvePoolDynamicTokenFetcher extends AppTok const fees = await this.resolveFees({ contract, swapAddress, multicall }); const fee = Number(fees[0]) / 10 ** 8; - const volume = this.skipVolume == false ? await this.volumeDataLoader.load(definition.swapAddress) : 0; - const feeVolume = fee * volume; - const apy = defaultDataProps.liquidity > 0 ? (feeVolume / defaultDataProps.liquidity) * 365 : 0; - - return { ...defaultDataProps, fee, volume, apy, swapAddress }; + return { ...defaultDataProps, fee, swapAddress }; } async getLabel({ appToken }: GetDisplayPropsParams) { diff --git a/src/apps/kyberswap-elastic/common/kyberswap-elastic.liquidity.contract-position-fetcher.ts b/src/apps/kyberswap-elastic/common/kyberswap-elastic.liquidity.contract-position-fetcher.ts index 21d638fe0..7b6a60a8e 100644 --- a/src/apps/kyberswap-elastic/common/kyberswap-elastic.liquidity.contract-position-fetcher.ts +++ b/src/apps/kyberswap-elastic/common/kyberswap-elastic.liquidity.contract-position-fetcher.ts @@ -1,5 +1,4 @@ import { Inject, NotImplementedException } from '@nestjs/common'; -import DataLoader from 'dataloader'; import { compact, range } from 'lodash'; import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; @@ -65,8 +64,6 @@ export abstract class KyberswapElasticLiquidityContractPositionFetcher extends C abstract blockSubgraphUrl: string; protected poolFeeMapping: Record | null; - apyDataLoader: DataLoader; - constructor( @Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, @Inject(KyberswapElasticViemContractFactory) @@ -84,11 +81,6 @@ export abstract class KyberswapElasticLiquidityContractPositionFetcher extends C } async getDefinitions(): Promise { - this.apyDataLoader = this.apyDataLoaderBuilder.getLoader({ - subgraphUrl: this.subgraphUrl, - blockSubgraphUrl: this.blockSubgraphUrl, - }); - const data = await gqlFetch({ endpoint: this.subgraphUrl, query: GET_TOP_POOLS_QUERY, @@ -141,9 +133,8 @@ export abstract class KyberswapElasticLiquidityContractPositionFetcher extends C const reserves = reservesRaw.map((r, i) => Number(r) / 10 ** tokens[i].decimals); const liquidity = reserves[0] * tokens[0].price + reserves[1] * tokens[1].price; const assetStandard = Standard.ERC_721; - const apy = await this.apyDataLoader.load(poolAddress); - return { feeTier, reserves, liquidity, poolAddress, assetStandard, apy, positionKey: `${feeTier}` }; + return { feeTier, reserves, liquidity, poolAddress, assetStandard, positionKey: `${feeTier}` }; } async getLabel({ diff --git a/src/apps/uniswap-v2/common/uniswap-v2.pool.subgraph.template.token-fetcher.ts b/src/apps/uniswap-v2/common/uniswap-v2.pool.subgraph.template.token-fetcher.ts index dcacbb51b..37d6cb513 100644 --- a/src/apps/uniswap-v2/common/uniswap-v2.pool.subgraph.template.token-fetcher.ts +++ b/src/apps/uniswap-v2/common/uniswap-v2.pool.subgraph.template.token-fetcher.ts @@ -1,34 +1,15 @@ -import DataLoader from 'dataloader'; import { BigNumberish } from 'ethers'; import { difference, range, uniq } from 'lodash'; import { Abi, GetContractReturnType, PublicClient } from 'viem'; -import { BLOCKS_PER_DAY } from '~app-toolkit/constants/blocks'; import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; -import { GetDataPropsParams } from '~position/template/app-token.template.types'; -import { - UniswapV2PoolOnChainTemplateTokenFetcher, - UniswapV2TokenDataProps, -} from './uniswap-v2.pool.on-chain.template.token-fetcher'; -import { - DEFAULT_LAST_BLOCK_SYNCED_ON_GRAPH_QUERY, - DEFAULT_POOLS_BY_ID_QUERY, - DEFAULT_POOLS_QUERY, - DEFAULT_POOL_VOLUMES_BY_ID_AT_BLOCK_QUERY, - DEFAULT_POOL_VOLUMES_BY_ID_QUERY, - FURA_LAST_BLOCK_SYNCED_ON_GRAPH_QUERY, - LastBlockSyncedFuraResponse, - LastBlockSyncedResponse, - PoolsResponse, - PoolVolumesResponse, -} from './uniswap-v2.pool.subgraph.types'; +import { UniswapV2PoolOnChainTemplateTokenFetcher } from './uniswap-v2.pool.on-chain.template.token-fetcher'; +import { DEFAULT_POOLS_BY_ID_QUERY, DEFAULT_POOLS_QUERY, PoolsResponse } from './uniswap-v2.pool.subgraph.types'; export abstract class UniswapV2PoolSubgraphTemplateTokenFetcher< T extends Abi, > extends UniswapV2PoolOnChainTemplateTokenFetcher { - volumeDataLoader: DataLoader | null; - abstract subgraphUrl: string; // Pool Addresses @@ -39,19 +20,7 @@ export abstract class UniswapV2PoolSubgraphTemplateTokenFetcher< requiredPools: string[] = []; ignoredPools: string[] = []; - // Volume - skipVolume = false; - lastBlockSyncedOnGraphQuery = DEFAULT_LAST_BLOCK_SYNCED_ON_GRAPH_QUERY; - poolVolumesByIdQuery = DEFAULT_POOL_VOLUMES_BY_ID_QUERY; - poolVolumesByIdAtBlockQuery = DEFAULT_POOL_VOLUMES_BY_ID_AT_BLOCK_QUERY; - async getAddresses() { - // Initialize volume dataloader - const dataLoaderOptions = { cache: true, maxBatchSize: 1000 }; - if (!this.skipVolume) { - this.volumeDataLoader = new DataLoader(this.batchGetVolume.bind(this), dataLoaderOptions); - } - const chunks = await Promise.all( range(0, this.first, 1000).map(skip => { const count = Math.min(1000, this.first - skip); @@ -91,86 +60,4 @@ export abstract class UniswapV2PoolSubgraphTemplateTokenFetcher< getPoolAddress(_contract: any, _index: number): Promise { throw new Error('Method not implemented.'); } - - async getApy({ appToken }: GetDataPropsParams) { - const liquidity = appToken.supply * appToken.price; - const volume = this.volumeDataLoader ? await this.volumeDataLoader.load(appToken.address) : 0; - const yearlyFees = volume * (this.fee / 100) * 365; - const apy = yearlyFees / liquidity; - return apy * 100; - } - - async getDataProps(params: GetDataPropsParams) { - const defaultDataProps = await super.getDataProps(params); - const volume = this.volumeDataLoader ? await this.volumeDataLoader.load(params.appToken.address) : 0; - return { ...defaultDataProps, volume }; - } - - async batchGetVolume(addresses: string[]) { - // Get block from 1 day ago - const provider = this.appToolkit.getNetworkProvider(this.network); - const block = await provider.getBlockNumber(); - const block1DayAgo = block - BLOCKS_PER_DAY[this.network]; - let blockNumberLastSynced = 0; - - // Get last block synced on graph; if the graph is not caught up to yesterday, exit early - if (this.subgraphUrl.includes('api.fura.org')) { - const subgraphName = this.subgraphUrl.substring(this.subgraphUrl.lastIndexOf('/') + 1); - const graphMetaData = await gqlFetch({ - endpoint: this.subgraphUrl, - query: FURA_LAST_BLOCK_SYNCED_ON_GRAPH_QUERY, - variables: { subgraphName }, - }); - - blockNumberLastSynced = graphMetaData.indexingStatusForCurrentVersion.chains[0].latestBlock.number; - } else { - const graphMetaData = await gqlFetch({ - endpoint: this.subgraphUrl, - query: this.lastBlockSyncedOnGraphQuery, - }); - - blockNumberLastSynced = graphMetaData._meta.block.number; - } - - if (block1DayAgo > blockNumberLastSynced) return addresses.map(() => 0); - - // Retrieve volume data from TheGraph (@TODO Cache this) - const [volumeByIDData, volumeByIDData1DayAgo] = await Promise.all([ - gqlFetch({ - endpoint: this.subgraphUrl, - query: this.poolVolumesByIdQuery, - variables: { ids: addresses }, - }), - gqlFetch({ - endpoint: this.subgraphUrl, - query: this.poolVolumesByIdAtBlockQuery, - variables: { ids: addresses, block: block1DayAgo }, - }), - ]); - - // Merge all volume data for today and merge all volume data for yesterday - const poolVolumes = addresses.map(async address => { - // Find the matching volume entry from yesterday - const pairVolumeToday = volumeByIDData.pairs.find(p => p.id === address); - const poolVolumeYesterday = volumeByIDData1DayAgo.pairs.find(p => p.id === address); - - // Calculate volume chnage between yesterday and today wherever applicable - let volume: number; - if (pairVolumeToday?.volumeUSD && poolVolumeYesterday?.volumeUSD) { - const volumeUSDToday = Number(pairVolumeToday.volumeUSD); - const volumeUSDYesterday = Number(poolVolumeYesterday.volumeUSD); - volume = volumeUSDToday - volumeUSDYesterday; - } else if (pairVolumeToday?.untrackedVolumeUSD && poolVolumeYesterday?.untrackedVolumeUSD) { - const volumeUSDToday = Number(pairVolumeToday.untrackedVolumeUSD); - const volumeUSDYesterday = Number(poolVolumeYesterday.untrackedVolumeUSD); - volume = volumeUSDToday - volumeUSDYesterday; - } else { - volume = 0; - } - - return volume; - }); - - return poolVolumes; - } } diff --git a/src/apps/uniswap-v2/ethereum/uniswap-v2.pool.token-fetcher.ts b/src/apps/uniswap-v2/ethereum/uniswap-v2.pool.token-fetcher.ts index 2af603d8f..18f80b469 100644 --- a/src/apps/uniswap-v2/ethereum/uniswap-v2.pool.token-fetcher.ts +++ b/src/apps/uniswap-v2/ethereum/uniswap-v2.pool.token-fetcher.ts @@ -1,31 +1,7 @@ -import { gql } from 'graphql-request'; - import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; import { UniswapV2DefaultPoolSubgraphTemplateTokenFetcher } from '../common/uniswap-v2.default.subgraph.template.token-fetcher'; -type UniswapV2BalancesData = { - user?: { - liquidityPositions: { - pair: { - id: string; - }; - }[]; - }; -}; - -const UNISWAP_V2_BALANCES_QUERY = gql` - query getBalances($address: String!) { - user(id: $address) { - liquidityPositions { - pair { - id - } - } - } - } -`; - @PositionTemplate() export class EthereumUniswapV2PoolTokenFetcher extends UniswapV2DefaultPoolSubgraphTemplateTokenFetcher { groupLabel = 'Pools'; @@ -35,6 +11,4 @@ export class EthereumUniswapV2PoolTokenFetcher extends UniswapV2DefaultPoolSubgr ignoredPools = ['0x3016a43b482d0480460f6625115bd372fe90c6bf']; orderBy = 'trackedReserveETH'; first = 1000; - // Todo: remove when subgraph isn't throwing when calling volumeUSD - skipVolume = true; } diff --git a/src/multicall/impl/multicall.ethers.ts b/src/multicall/impl/multicall.ethers.ts index 89231c06d..1747a1063 100644 --- a/src/multicall/impl/multicall.ethers.ts +++ b/src/multicall/impl/multicall.ethers.ts @@ -3,11 +3,11 @@ import { Contract, ethers } from 'ethers'; import { FunctionFragment, Interface } from 'ethers/lib/utils'; import { Multicall } from '~contract/contracts'; +import { MulticallCallStruct } from '~multicall/multicall.types'; import { DEFAULT_DATALOADER_OPTIONS } from '../multicall.constants'; import { MulticallContract } from '../multicall.contract'; import { ContractCall, IMulticallWrapper, TargetContract } from '../multicall.interface'; -import { MulticallCallStruct } from '~multicall/multicall.types'; export const isMulticallUnderlyingError = (err: Error) => err.message.includes('Multicall call failed for');