Clamp negative subgraph liquidity to 0 in pool-indexer seeding#4616
Clamp negative subgraph liquidity to 0 in pool-indexer seeding#4616AryanGodara wants to merge 5 commits into
Conversation
|
Claude finished @AryanGodara's task in 1m 33s —— View job PR Review: Warn for negative subgraph liquidity in pool-indexer seeding
Verdict: LGTM ✅ — a clean, minimal, well-reasoned robustness fix. The change correctly turns a bootstrap-aborting
I left one inline comment with two non-blocking notes (a suggested regression unit test, and a wording nit that |
There was a problem hiding this comment.
Code Review
This pull request modifies the subgraph seeder to handle unparseable liquidity values by skipping the pool's seed state instead of aborting the bootstrap process. However, skipping the pool state entirely causes these pools to be omitted from queries due to an inner join on the pool states table. It is recommended to parse the liquidity as an i128 and clamp negative values to 0 to preserve the pool state.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Description
Rolling out the pool-indexer on polygon staging, the bootstrap init container paniced after seeding ~12k pools due to
subgraph seeding failed: parse liquidity. Caused by:invalid digit found in stringRoot cause: the Uniswap V3 subgraph's liquidity is not the on-chain uint128 getter. the subgraph derives it incrementally, and it's reset to absolute on swaps.
The in-range check keys off
pool.tick, which is only refreshed on swaps, so the running sum drifts and can go negative. The Graph serializes BigInt as a signed decimal string, so a value like"-967991328"fails.parse::<u128>(), and that error was aborting the initial seed.Receipts: negative-liquidity pools from the polygon subgraph:
Each has a real tick + non-zero sqrtPrice, so it reaches the liquidity parse.
Changes
apply_position_delta_to_pool_liq(which already clamps negative to 0). The pool keeps a state row and stays visible via theget_poolsjoin, with its correct on-chain sqrtPrice/tick.sqrtPrice/tickstay strict. Ticks were already fine (liquidityNet → i128).Safe because clamp-to-0 produces the same DB state the live indexer already writes in prod, and the same 0 the subgraph itself now returns for these pools; liquidity=0 is unusable for routing (a solver won't pick it) and the driver simulates before executing.
Testing
get_pools_by_ids.