From b77efa23163fc64c617638c261001c0c64fd1014 Mon Sep 17 00:00:00 2001 From: Vasilis Xouris Date: Mon, 2 Dec 2024 18:31:01 -0800 Subject: [PATCH] fix(subgraph): include all VIRTUAL/* pools in V2 Base subgraph --- src/providers/v2/subgraph-provider.ts | 60 ++--------- .../providers/v2/subgraph-provider.test.ts | 99 ++++++------------- 2 files changed, 38 insertions(+), 121 deletions(-) diff --git a/src/providers/v2/subgraph-provider.ts b/src/providers/v2/subgraph-provider.ts index 6b344557f..231636c82 100644 --- a/src/providers/v2/subgraph-provider.ts +++ b/src/providers/v2/subgraph-provider.ts @@ -251,7 +251,7 @@ export class V2SubgraphProvider implements IV2SubgraphProvider { (pool) => pool.token0.id == FEI || pool.token1.id == FEI || - this.isVirtualPairBaseV2Pool(pool.id) || + this.isVirtualPairBaseV2Pool(pool) || parseFloat(pool.trackedReserveETH) > this.trackedEthThreshold ); @@ -270,7 +270,7 @@ export class V2SubgraphProvider implements IV2SubgraphProvider { return ( pool.token0.id == FEI || pool.token1.id == FEI || - this.isVirtualPairBaseV2Pool(pool.id) || + this.isVirtualPairBaseV2Pool(pool) || parseFloat(pool.trackedReserveETH) > this.trackedEthThreshold || parseFloat(pool.reserveUSD) > this.untrackedUsdThreshold ); @@ -315,58 +315,14 @@ export class V2SubgraphProvider implements IV2SubgraphProvider { return poolsSanitized; } - // This method checks if a given pool is part of the Virtual Pair Base V2 Pool IDs. - public isVirtualPairBaseV2Pool(poolId: string): boolean { + // This method checks if a given pool contains the VIRTUAL token. + public isVirtualPairBaseV2Pool(pool: RawV2SubgraphPool): boolean { + const virtualTokenAddress = + '0x0b3e328455c4059eeb9e3f84b5543f74e24e7e1b'.toLowerCase(); return ( this.chainId === ChainId.BASE && - V2SubgraphProvider.VirtualPairBaseV2PoolIds.has(poolId.toLowerCase()) + (pool.token0.id.toLowerCase() === virtualTokenAddress || + pool.token1.id.toLowerCase() === virtualTokenAddress) ); } - - // TODO: Remove. Temporary fix to allow VIRTUAL/* V2 top pools to be included in the list until the subgraph is re-indexed. - // Note: All addresses here should be in lowercase. - private static readonly VirtualPairBaseV2PoolIds: Set = new Set([ - // Pool ID for VIRTUAL / GAME - '0xd418dfe7670c21f682e041f34250c114db5d7789', - // Pool ID for VIRTUAL / AIXBT - '0x7464850cc1cfb54a2223229b77b1bca2f888d946', - // Pool ID for VIRTUAL / LUNA - '0xa8e64fb120ce8796594670bae72279c8aa1e5359', - // Pool ID for VIRTUAL / TOSHI - '0x368ea6f645deb6d1a8692fe93c550d2834150865', - // Pool ID for VIRTUAL / KEYCAT - '0x3b9ddad7459fdfcfdb7117d53301182dd46b7042', - // Pool ID for VIRTUAL / VADER - '0xa1dddb82501e8fe2d92ad0e8ba331313f501de72', - // Pool ID for VIRTUAL / SEKOIA - '0x9e046c706f9ea6ce8f9287d30a15438c07f42d64', - // Pool ID for VIRTUAL / SAINT - '0x93d65a935e7c0f1aa153780e0db3ad08b9448c89', - // Pool ID for VIRTUAL / $mfer - '0xcaabcb34b48d29631c2b2c1d947d669fd8117a51', - // Pool ID for VIRTUAL / AIINU - '0xd2d670c91d14d9abcca7749f65e3181b2124e12d', - // Pool ID for VIRTUAL / CONVO - '0x3268d7efa254e648ffe968664e47ca226e27cd04', - // Pool ID for VIRTUAL / POLY - '0xde40586745a4e21efc0e8e0073cdd431ae88876a', - // Pool ID for VIRTUAL / GUAN - '0xff5bbda63e87210edd0ab9bc424086589d92e0af', - // Pool ID for VIRTUAL / SAM - '0xd72a82022134ba0d417c8d733139057e9bb9ea3f', - // Pool ID for VIRTUAL / VIRTU - '0xd9436bdaaf364181f1a39bb4c5e0a307c7353a01', - // Pool ID for VIRTUAL / CYI - '0x9d89c0cb73143927761534143747e26c47a1589f', - // Pool ID for VIRTUAL / VU - '0xfa65a76655f3c0641b79e89de3f51459c3727823', - // Pool ID for VIRTUAL / ECHO - '0x75cf1180ceb1cbef7508a4a4a0de940e2db4f087', - // Pool ID for VIRTUAL / MUSIC - '0xcef84d17513ede0ab951f7be9829e638a20bfba4', - // Pool ID for VIRTUAL / MISATO - '0x863e3a73c604d5038d41e2512272a73585f70017', - // Pool ID for VIRTUAL / NIKITA - '0xb9d782f2cfb755d47e2a5fa1350100c2ce3287ee', - ]); } diff --git a/test/unit/providers/v2/subgraph-provider.test.ts b/test/unit/providers/v2/subgraph-provider.test.ts index 88c16d143..714e15f69 100644 --- a/test/unit/providers/v2/subgraph-provider.test.ts +++ b/test/unit/providers/v2/subgraph-provider.test.ts @@ -1,19 +1,28 @@ +import { ChainId } from '@uniswap/sdk-core'; import dotenv from 'dotenv'; import { GraphQLClient } from 'graphql-request'; import sinon from 'sinon'; -import { - V2SubgraphProvider, -} from '../../../../src'; -import { ChainId } from '@uniswap/sdk-core'; +import { V2SubgraphProvider } from '../../../../src'; dotenv.config(); describe('SubgraphProvider V2', () => { - // VIRTUAL / AIXBT v2 pool - const virtualPairAddress = '0x7464850cc1cfb54a2223229b77b1bca2f888d946'; - // Random non-virtual pair address - const nonVirtualPairAddress = '0x7464850cc1cfb54a2223229b77b1bca2f888d947'; + const virtualTokenAddress = '0x0b3e328455c4059eeb9e3f84b5543f74e24e7e1b'; + function constructPool(withVirtualToken: boolean, trackedReservedEth: string) { + return { + id: '0xAddress1', + token0: { + id: withVirtualToken ? virtualTokenAddress : '0xToken0', + symbol: withVirtualToken ? 'VIRTUAL' : 'TOKEN0' + }, + token1: { id: '0xToken1', symbol: 'TOKEN1' }, + totalSupply: '100000', + trackedReserveETH: trackedReservedEth, + reserveETH: trackedReservedEth, + reserveUSD: '0.001', + }; + } let requestStubMainnet: sinon.SinonStub; let requestStubBase: sinon.SinonStub; @@ -32,15 +41,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: nonVirtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '1', - reserveETH: '1', - reserveUSD: '0.001', - }, + constructPool(false, '1'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -51,7 +52,7 @@ describe('SubgraphProvider V2', () => { const pools = await subgraphProviderBase.getPools(); expect(pools.length).toEqual(1); - expect(pools[0]!.id).toEqual(nonVirtualPairAddress); + expect(pools[0]!.token0.id).not.toEqual(virtualTokenAddress); }); it('fetches 0 subgraph pools if trackedReserveETH is below 0.025 threshold on Base', async () => { @@ -60,15 +61,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: nonVirtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '0.001', - reserveETH: '0.001', - reserveUSD: '0.001', - }, + constructPool(false, '0.001'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -87,15 +80,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: virtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '0.001', - reserveETH: '0.001', - reserveUSD: '0.001', - }, + constructPool(true, '0.001'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -106,7 +91,7 @@ describe('SubgraphProvider V2', () => { const pools = await subgraphProviderBase.getPools(); expect(pools.length).toEqual(1); - expect(pools[0]!.id).toEqual(virtualPairAddress); + expect(pools[0]!.token0.id).toEqual(virtualTokenAddress); }); @@ -116,15 +101,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: nonVirtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '1', - reserveETH: '1', - reserveUSD: '0.001', - }, + constructPool(false, '1'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -135,7 +112,7 @@ describe('SubgraphProvider V2', () => { const pools = await subgraphProviderMainnet.getPools(); expect(pools.length).toEqual(1); - expect(pools[0]!.id).toEqual(nonVirtualPairAddress); + expect(pools[0]!.token0.id).not.toEqual(virtualTokenAddress); }); it('fetches 0 subgraph pools if trackedReserveETH is below 0.025 threshold on Mainnet', async () => { @@ -144,15 +121,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: nonVirtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '0.001', - reserveETH: '0.001', - reserveUSD: '0.001', - }, + constructPool(false, '0.001'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -171,15 +140,7 @@ describe('SubgraphProvider V2', () => { const firstCallResponse = { pairs: [ - { - id: virtualPairAddress, - token0: { id: '0xToken0', symbol: 'TOKEN0' }, - token1: { id: '0xToken1', symbol: 'TOKEN1' }, - totalSupply: '100000', - trackedReserveETH: '0.001', - reserveETH: '0.001', - reserveUSD: '0.001', - }, + constructPool(true, '0.001'), ], }; const subsequentCallsResponse = { pairs: [] }; @@ -195,12 +156,12 @@ describe('SubgraphProvider V2', () => { it('isVirtualPairBaseV2Pool tests', async () => { // virtual / non-virtual pair address on mainnet fails const mainnetSubgraphProviderV2 = new V2SubgraphProvider(ChainId.MAINNET, 2, 30000, true, 1000, 0.01, Number.MAX_VALUE, 'test_url'); - expect(mainnetSubgraphProviderV2.isVirtualPairBaseV2Pool(virtualPairAddress)).toBe(false); - expect(mainnetSubgraphProviderV2.isVirtualPairBaseV2Pool(nonVirtualPairAddress)).toBe(false); + expect(mainnetSubgraphProviderV2.isVirtualPairBaseV2Pool(constructPool(true, '1'))).toBe(false); + expect(mainnetSubgraphProviderV2.isVirtualPairBaseV2Pool(constructPool(false, '1'))).toBe(false); // virtual pair address on base succeeds / non-virtual fails const baseSubgraphProviderV2 = new V2SubgraphProvider(ChainId.BASE, 2, 30000, true, 1000, 0.01, Number.MAX_VALUE, 'test_url'); - expect(baseSubgraphProviderV2.isVirtualPairBaseV2Pool(virtualPairAddress)).toBe(true); - expect(baseSubgraphProviderV2.isVirtualPairBaseV2Pool(nonVirtualPairAddress)).toBe(false); + expect(baseSubgraphProviderV2.isVirtualPairBaseV2Pool(constructPool(true, '1'))).toBe(true); + expect(baseSubgraphProviderV2.isVirtualPairBaseV2Pool(constructPool(false, '1'))).toBe(false); }); })