From 0fd7a2ab7d7299a91674249ee52fcc042eaec1a8 Mon Sep 17 00:00:00 2001 From: Rusty <219724427+rustyshackleforddoteth@users.noreply.github.com> Date: Wed, 28 Jan 2026 12:05:19 -0700 Subject: [PATCH 1/2] fix v4 migration pool reserves calculation Fetch actual token balances from migration pool using balanceOf() instead of calculating theoretical reserves from liquidity math. This matches the approach used for V3 pools. --- src/indexer/indexer-shared.ts | 1 + src/indexer/shared/entities/v4pools.ts | 3 ++ src/utils/v4-utils/getV4MigrationPoolData.ts | 45 ++++++++++---------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/indexer/indexer-shared.ts b/src/indexer/indexer-shared.ts index 29515b1..0ce3a72 100644 --- a/src/indexer/indexer-shared.ts +++ b/src/indexer/indexer-shared.ts @@ -108,6 +108,7 @@ ponder.on("Airlock:Migrate", async ({ event, context }) => { migratorAddress, assetAddress: assetId, numeraireAddress: assetEntity.numeraire, + migrationPoolAddress, parentPoolAddress: parentPool.address, timestamp, context, diff --git a/src/indexer/shared/entities/v4pools.ts b/src/indexer/shared/entities/v4pools.ts index f21319b..556cee3 100644 --- a/src/indexer/shared/entities/v4pools.ts +++ b/src/indexer/shared/entities/v4pools.ts @@ -239,6 +239,7 @@ export const insertV4MigrationPoolIfNotExists = async ({ migratorAddress, assetAddress, numeraireAddress, + migrationPoolAddress, parentPoolAddress, timestamp, context, @@ -246,6 +247,7 @@ export const insertV4MigrationPoolIfNotExists = async ({ migratorAddress: Address; assetAddress: Address; numeraireAddress: Address; + migrationPoolAddress: Address; parentPoolAddress: Address; timestamp: bigint; context: Context; @@ -256,6 +258,7 @@ export const insertV4MigrationPoolIfNotExists = async ({ migratorAddress, assetAddress, numeraireAddress, + migrationPoolAddress, timestamp, context, }); diff --git a/src/utils/v4-utils/getV4MigrationPoolData.ts b/src/utils/v4-utils/getV4MigrationPoolData.ts index f160593..757ce04 100644 --- a/src/utils/v4-utils/getV4MigrationPoolData.ts +++ b/src/utils/v4-utils/getV4MigrationPoolData.ts @@ -1,6 +1,6 @@ import { Address } from "viem"; import { Context } from "ponder:registry"; -import { V4MigratorABI, V4MigratorABILegacy, StateViewABI } from "@app/abis"; +import { V4MigratorABI, V4MigratorABILegacy, StateViewABI, DERC20ABI } from "@app/abis"; import { PoolKey, Slot0Data } from "@app/types/v4-types"; import { getPoolId } from "./getPoolId"; import { computeV4Price } from "./computeV4Price"; @@ -8,7 +8,6 @@ import { chainConfigs } from "@app/config"; import { getQuoteInfo, QuoteInfo } from "@app/utils/getQuoteInfo"; import { getAssetData } from "@app/utils/getAssetData"; import { zeroAddress } from "viem"; -import { getAmount0Delta, getAmount1Delta } from "@app/utils/v3-utils/computeGraduationThreshold"; export interface BeneficiaryData { beneficiary: Address; @@ -93,12 +92,14 @@ export const getV4MigrationPoolData = async ({ migratorAddress, assetAddress, numeraireAddress, + migrationPoolAddress, timestamp, context, }: { migratorAddress: Address; assetAddress: Address; numeraireAddress: Address; + migrationPoolAddress: Address; timestamp: bigint; context: Context; }): Promise => { @@ -160,28 +161,26 @@ export const getV4MigrationPoolData = async ({ quoteTokenDecimals: quoteInfo.quoteDecimals, }); - const MIN_TICK = -887270; - const MAX_TICK = 887270; - const currentTick = slot0Data.tick; - - let reserves0 = 0n; - let reserves1 = 0n; - - if (liquidity > 0n) { - reserves0 = getAmount0Delta({ - tickLower: currentTick, - tickUpper: MAX_TICK, - liquidity, - roundUp: false, - }); + // Fetch actual reserves from the migration pool (V3 pool where liquidity resides) + const [r0, r1] = await client.multicall({ + contracts: [ + { + abi: DERC20ABI, + address: poolKey.currency0, + functionName: "balanceOf", + args: [migrationPoolAddress], + }, + { + abi: DERC20ABI, + address: poolKey.currency1, + functionName: "balanceOf", + args: [migrationPoolAddress], + }, + ], + }); - reserves1 = getAmount1Delta({ - tickLower: MIN_TICK, - tickUpper: currentTick, - liquidity, - roundUp: false, - }); - } + const reserves0 = r0?.result ?? 0n; + const reserves1 = r1?.result ?? 0n; return { poolKey, From 18664eebb73cd828100b33c941218910f142c445 Mon Sep 17 00:00:00 2001 From: Rusty <219724427+rustyshackleforddoteth@users.noreply.github.com> Date: Wed, 28 Jan 2026 12:05:45 -0700 Subject: [PATCH 2/2] fix v4 swap reserves calculation sign In V4 swap events, positive amounts = tokens in, negative = tokens out. Reserves should be updated with addition (reserves + amount) not subtraction, so that: - tokens coming in (+) increase reserves - tokens going out (-) decrease reserves --- src/indexer/shared/swap-optimizer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/indexer/shared/swap-optimizer.ts b/src/indexer/shared/swap-optimizer.ts index 830f246..17d92a9 100644 --- a/src/indexer/shared/swap-optimizer.ts +++ b/src/indexer/shared/swap-optimizer.ts @@ -120,8 +120,8 @@ export function processSwapCalculations( dollarLiquidity, marketCapUsd: 0n, // Will be calculated after token fetch swapValueUsd, - nextReserves0: reserves0 - amount0, - nextReserves1: reserves1 - amount1, + nextReserves0: reserves0 + amount0, + nextReserves1: reserves1 + amount1, fee0, fee1, swapType,