From ca93d8d3979ce359593b6856b5ddeaaeb2244f87 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:52:58 +0100 Subject: [PATCH] sync FX quote tokens --- modules/actions/pool/v2/add-pools.ts | 8 ++++ .../pool/v2/sync-pool-type-onchain-data.ts | 45 +++++++++++++++++++ modules/controllers/fx-pools-controller.ts | 9 ++++ tasks/index.ts | 4 ++ 4 files changed, 66 insertions(+) create mode 100644 modules/actions/pool/v2/sync-pool-type-onchain-data.ts diff --git a/modules/actions/pool/v2/add-pools.ts b/modules/actions/pool/v2/add-pools.ts index afc382550..a98f363b8 100644 --- a/modules/actions/pool/v2/add-pools.ts +++ b/modules/actions/pool/v2/add-pools.ts @@ -6,6 +6,7 @@ import { BalancerPoolFragment } from '../../../subgraphs/balancer-subgraph/gener import { subgraphToPrismaCreate } from '../../../pool/subgraph-mapper'; import { upsertBptBalancesV2 } from '../../user/upsert-bpt-balances-v2'; import _ from 'lodash'; +import { syncPoolTypeOnchainData } from './sync-pool-type-onchain-data'; export const addPools = async (subgraphService: V2SubgraphClient, chain: Chain): Promise => { const { block } = await subgraphService.legacyService.getMetadata(); @@ -28,6 +29,13 @@ export const addPools = async (subgraphService: V2SubgraphClient, chain: Chain): const created = await createPoolRecord(subgraphPool, chain, block.number, allNestedTypePools); if (created) { createdPools.push(subgraphPool.id); + // When new FX pool is added, we need to get the quote token + if (subgraphPool.poolType === 'FX') { + await syncPoolTypeOnchainData( + [{ id: subgraphPool.id, address: subgraphPool.address, type: subgraphPool.poolType }], + chain, + ); + } } } diff --git a/modules/actions/pool/v2/sync-pool-type-onchain-data.ts b/modules/actions/pool/v2/sync-pool-type-onchain-data.ts new file mode 100644 index 000000000..26e976361 --- /dev/null +++ b/modules/actions/pool/v2/sync-pool-type-onchain-data.ts @@ -0,0 +1,45 @@ +import { Abi } from 'abitype'; +import FX from '../../../pool/abi/FxPool.json'; +import { getViemClient, ViemClient } from '../../../sources/viem-client'; +import { Chain, PrismaPoolType } from '@prisma/client'; +import { update } from '../v3/type-data/update'; + +export const syncPoolTypeOnchainData = async ( + pools: { id: string; address: string; type: PrismaPoolType }[], + chain: Chain, +) => { + const viemClient = getViemClient(chain); + + // Get FX pools + const fxPools = pools.filter((pool) => pool.type === 'FX'); + const quoteTokens = await fetchFxQuoteTokens(fxPools, viemClient); + await update(quoteTokens); + + return true; +}; + +export const fetchFxQuoteTokens = async (pools: { id: string; address: string }[], viemClient: ViemClient) => { + // Fetch the tokens from the subgraph + const contracts = pools.map(({ address }) => { + return { + address: address as `0x${string}`, + abi: FX as Abi, + functionName: 'derivatives', + args: [1], + }; + }); + + const results = await viemClient.multicall({ contracts, allowFailure: true }); + + return results + .map((call, index) => { + // If the call failed, return null + if (call.status === 'failure') return null; + + return { + id: pools[index].id, + typeData: { quoteToken: (call.result as string).toLowerCase() }, + }; + }) + .filter((quoteToken): quoteToken is { id: string; typeData: { quoteToken: string } } => quoteToken !== null); +}; diff --git a/modules/controllers/fx-pools-controller.ts b/modules/controllers/fx-pools-controller.ts index 64a95346c..2d15a46e5 100644 --- a/modules/controllers/fx-pools-controller.ts +++ b/modules/controllers/fx-pools-controller.ts @@ -1,4 +1,6 @@ import config from '../../config'; +import { prisma } from '../../prisma/prisma-client'; +import { syncPoolTypeOnchainData } from '../actions/pool/v2/sync-pool-type-onchain-data'; import { syncLatestFXPrices } from '../token/latest-fx-price'; import { Chain } from '@prisma/client'; @@ -11,5 +13,12 @@ export function FXPoolsController() { return syncLatestFXPrices(balancer, chain); }, + async syncQuoteTokens(chain: Chain) { + const pools = await prisma.prismaPool.findMany({ + where: { chain, type: 'FX' }, + }); + + return syncPoolTypeOnchainData(pools, chain); + }, }; } diff --git a/tasks/index.ts b/tasks/index.ts index e97b7f49d..f3e2109aa 100644 --- a/tasks/index.ts +++ b/tasks/index.ts @@ -128,6 +128,10 @@ async function run(job: string = process.argv[2], chainId: string = process.argv } else if (job === 'sync-hook-data') { return PoolController().syncHookData(chain); } + // Maintenance + else if (job === 'sync-fx-quote-tokens') { + return FXPoolsController().syncQuoteTokens(chain); + } return Promise.reject(new Error(`Unknown job: ${job}`)); }