From 17b0a94c5d97fc7add1da26d0b8e6c2518e05a00 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 17 Mar 2026 14:58:01 +0100 Subject: [PATCH 1/3] fix: fall back to latest stake when L2 block lookup reverts When getL2BlockRangeForL1 reverts (e.g. no Arbitrum batches posted for that L1 block), the returned lastBlock of 0 was passed to getTotalStake, querying the subgraph at block 0 and producing near-zero stake. This could cause incorrect poll status calculations. Now passes undefined instead of 0 so getTotalStake queries latest stake. Also downgrades console.error to console.warn for expected failures. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/api/polls.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/api/polls.ts b/lib/api/polls.ts index 5abcac60..c7042f53 100644 --- a/lib/api/polls.ts +++ b/lib/api/polls.ts @@ -84,17 +84,17 @@ export const getPollExtended = async ( const isActive = l1BlockNumber <= parseInt(poll?.endBlock ?? "0"); - // Get L2 block number corresponding to end of poll - // Create NodeInterface to get L2 block number corresponding to end of poll - const totalStakeString = await getTotalStake( - Number( - isActive - ? undefined - : ( - await getL2BlockRangeForL1(Number(poll?.endBlock ?? "0")) - ).lastBlock - ) - ); + // Get L2 block number corresponding to end of poll using NodeInterface + let l2BlockNumber: number | undefined; + if (!isActive) { + const { lastBlock } = await getL2BlockRangeForL1( + Number(poll?.endBlock ?? "0") + ); + if (lastBlock > 0) { + l2BlockNumber = lastBlock; + } + } + const totalStakeString = await getTotalStake(l2BlockNumber); const totalStake = +(totalStakeString ?? 0); const noVoteStake = +(poll?.tally?.no || 0); @@ -210,10 +210,9 @@ const getL2BlockRangeForL1 = async (l1BlockNumber: number) => { lastBlock: l2BlockRangeForL1.lastBlock.toNumber(), firstBlock: l2BlockRangeForL1.firstBlock.toNumber(), }; - } catch (error) { - console.error( - "Error getting L2 block range for L1 " + l1BlockNumber, - error + } catch { + console.warn( + `Could not resolve L2 block range for L1 block ${l1BlockNumber} — using latest stake` ); return { lastBlock: 0, From 005a60800b90c5f46346f7d0c52a5d5c21d741e3 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Wed, 18 Mar 2026 09:30:25 +0100 Subject: [PATCH 2/3] fix: log error detail in L2 block range fallback warning Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/api/polls.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/api/polls.ts b/lib/api/polls.ts index c7042f53..617259da 100644 --- a/lib/api/polls.ts +++ b/lib/api/polls.ts @@ -210,9 +210,10 @@ const getL2BlockRangeForL1 = async (l1BlockNumber: number) => { lastBlock: l2BlockRangeForL1.lastBlock.toNumber(), firstBlock: l2BlockRangeForL1.firstBlock.toNumber(), }; - } catch { + } catch (err) { + const detail = err instanceof Error ? err.message : String(err); console.warn( - `Could not resolve L2 block range for L1 block ${l1BlockNumber} — using latest stake` + `Could not resolve L2 block range for L1 block ${l1BlockNumber} — using latest stake (${detail})` ); return { lastBlock: 0, From 2060b167a624537549b29711b8bbfa6b33b4ac06 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Wed, 18 Mar 2026 09:32:47 +0100 Subject: [PATCH 3/3] refactor: improve L2 block range conditional formatting --- lib/api/polls.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/api/polls.ts b/lib/api/polls.ts index 617259da..87192da4 100644 --- a/lib/api/polls.ts +++ b/lib/api/polls.ts @@ -90,9 +90,7 @@ export const getPollExtended = async ( const { lastBlock } = await getL2BlockRangeForL1( Number(poll?.endBlock ?? "0") ); - if (lastBlock > 0) { - l2BlockNumber = lastBlock; - } + if (lastBlock > 0) l2BlockNumber = lastBlock; } const totalStakeString = await getTotalStake(l2BlockNumber);