Skip to content

fix: drop zero-address placeholders, merge eth RegistrarControllers#2049

Open
shrugs wants to merge 4 commits intomainfrom
feat/eliminate-zero-address-placeholders
Open

fix: drop zero-address placeholders, merge eth RegistrarControllers#2049
shrugs wants to merge 4 commits intomainfrom
feat/eliminate-zero-address-placeholders

Conversation

@shrugs
Copy link
Copy Markdown
Member

@shrugs shrugs commented May 3, 2026

Reviewer Focus (Read This First)

  • the merged-controller pattern in registrars + subgraph plugins: one Ponder entry per chain using AnyRegistrarControllerABI, dispatch by long-form event signature
  • the chain-id override fix in ensv2/plugin.ts:RegistrarControllercloses ENSv2 plugin silently overrides RegistrarController address per chain #2048; only the last chainConfigForContract(...) spread per chain id was surviving (mainnet was indexing only UnwrappedEthRegistrarController)
  • new helpers mergedChainConfigForContracts and pickContracts in apps/ensindexer/src/lib/ponder-helpers.ts

Problem & Motivation

three problems compound on sepolia-v2:

  • sepolia-v2's ENSRoot datasource carried LegacyEthRegistrarController, WrappedEthRegistrarController, and UniversalRegistrarRenewalWithReferrer as address: zeroAddress, startBlock: 0 placeholders to satisfy the typesystem
  • ponder registered them, dragging each chain's effective indexed startBlock to 0
  • fix(ensnode-sdk): skip zero-address placeholders in indexed blockrange #2045's buildIndexedBlockranges filter raised the public indexedBlockrange.startBlock but didn't fix ponder's view; historicalTotalBlocks - startBlock overshot by ~3.7M, producing Block 14473749 not found on every metadata write

discovered mid-investigation: ensv2 plugin's RegistrarController was silently dropping all but the last chainConfigForContract(...) spread per chain id (#2048).

What Changed (Concrete)

  1. removed LegacyEthRegistrarController, WrappedEthRegistrarController, UniversalRegistrarRenewalWithReferrer placeholder entries from sepolia-v2 ENSRoot; removed UniversalRegistrarRenewalWithReferrer from ens-test-env.
  2. added UniversalRegistrarRenewalWithReferrer to AnyRegistrarControllerABI so its RenewalReferred event is part of the merged dispatch.
  3. registrars + subgraph + ensv2 plugins: replaced per-controller Ponder contract entries with a single RegistrarController entry per chain. addresses combined via new mergedChainConfigForContracts(…, pickContracts(contracts, [names])).
  4. handler files dispatch by long-form event signature (e.g. NameRegistered(string label, bytes32 indexed labelhash, …, bytes32 referrer)); RenewalReferred uses the short form (unique name in merged abi).
  5. consolidated 4 ethnames per-controller handler files into one Ethnames_RegistrarController.ts; updated event-handlers.ts.
  6. fixed ENSv2 plugin silently overrides RegistrarController address per chain #2048: ensv2 RegistrarController now combines per-chain controller addresses via mergedChainConfigForContracts instead of multiple chain-id-keyed spreads that overwrote each other.
  7. reverted the zero-address skip in buildIndexedBlockranges from fix(ensnode-sdk): skip zero-address placeholders in indexed blockrange #2045 (placeholders no longer exist); removed the corresponding test; replaced the changeset.
  8. getContractsByManagedName now uses maybeGetDatasourceContract + .filter(...) for the optional ENSRoot controllers, matching the existing Basenames/Lineanames pattern.

Design & Planning

design was iterated in conversation. key decisions:

  • start by deleting placeholders with no guards and observe what ponder complains about, to validate scope

  • when type errors propagate into unrelated handlers (tokenscope), recognize that contract-name-keyed conditional spreads collapse EventNames inference and route around it

  • prefer the "merge controllers under one Ponder entry" pattern (mirroring apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts) over a maybePonderContractEntry-style cast helper

  • discovery of ENSv2 plugin silently overrides RegistrarController address per chain #2048 mid-flight; folded its fix in via the same mergedChainConfigForContracts helper

  • planning artifacts: none (conversation-driven)

  • reviewed / approved by: not yet

Self-Review

  • bugs caught: ENSv2 plugin silently overrides RegistrarController address per chain #2048 (chain-id override on ensv2 plugin)
  • logic simplified: 4 per-controller entries collapsed to 1 merged entry per chain across 3 plugins
  • naming / terminology improved: mergedChainConfigForContracts, pickContracts
  • dead or unnecessary code removed: per-controller ethnames handler files; an interim maybePonderContractEntry helper; per-controller ABI re-exports added then dropped within this branch

other things caught after first pass:

  • RenewalReferred initially registered with long-form sig — switched to short form (unique name in merged abi)
  • .filter((c): c is ContractConfig => …) predicate failed on union of specific contract types; introduced pickContracts which casts to ContractConfig | undefined first

Cross-Codebase Alignment

  • search terms used: zeroAddress, LegacyEthRegistrarController, WrappedEthRegistrarController, UniversalRegistrarRenewalWithReferrer, chainConfigForContract, AnyRegistrarControllerABI
  • reviewed but unchanged: basenames/lineanames per-controller entries in registrars/plugin.ts (no namespace-conditional issue; no chain-id override). apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts was the precedent for the long-form-signature dispatch
  • deferred alignment: collapsing Basenames + Lineanames into the merged pattern in registrars/plugin.ts for consistency. not load-bearing today

Downstream & Consumer Impact

  • public APIs affected: @ensnode/datasources drops the three placeholder entries on sepolia-v2 + URRWR on ens-test-env. consumers must treat the optional ENSRoot controllers as possibly-absent. AnyRegistrarControllerABI now includes RenewalReferred. ponder contract entry names changed across the three plugins (e.g. Ethnames_LegacyEthRegistrarControllerEthnames_RegistrarController)
  • docs updated: none — internal plugin/contract names
  • naming decisions worth calling out:

Testing Evidence

  • typecheck: pnpm -F ensindexer typecheck clean
  • tests: pnpm test --project ensindexer --project ensnode-sdk --project datasources — 219 / 219
  • lint: pnpm lint clean
  • boot smoke: PLUGINS=subgraph,ensv2,protocol-acceleration pnpm dev against sepolia-v2 — Started backfill indexing chain=99911155111 block_range=[3702721,10771028], cache_rate=100%, indexer progressing without the original Block 14473749 not found crash
  • known gaps: no local mainnet boot-smoke (no mainnet RPC). ENSv2 plugin silently overrides RegistrarController address per chain #2048's behavior change there (Legacy/Wrapped historicals now indexed) is reasoned from the diff
  • what reviewers reason about manually: that the long-form signatures match the on-chain abis exactly. cross-checked against packages/datasources/src/abis/root/*

Scope Reductions

  • did not collapse Basenames + Lineanames per-controller entries in registrars/plugin.ts into the merged pattern — no namespace-conditional issue, no current bug
  • did not include URRWR's address in the ensv2 plugin's controller address array — ensv2 has no RenewalReferred handler today; including its address would index events that no handler consumes

Risk Analysis

  • assumptions: long-form event signatures match each controller's abi exactly. mergeAbis preserves overloaded events with distinct topic hashes. ponder dispatches per long-form signature when an event name has overloads
  • failure modes: a typo in a long-form signature would silently drop that controller's events. boot smoke validates basic dispatch
  • blast radius: any deployment running registrars, subgraph, or ensv2 plugins re-indexes (handler/contract changes are implicit re-index per project convention). the ENSv2 plugin silently overrides RegistrarController address per chain #2048 fix means mainnet ensv2 will pick up Legacy/Wrapped historicals previously dropped, lengthening the first historical phase on those deployments
  • mitigations / rollback: revert the PR; ponder will re-index; schema is unchanged
  • named owner: @shrugs

Pre-Review Checklist (Blocking)

  • I reviewed every line of this diff and understand it end-to-end
  • I'm prepared to defend this PR line-by-line in review
  • I'm comfortable being the on-call owner for this change
  • Relevant changesets are included (or explicitly not required)

…gistrarControllers

Removes `LegacyEthRegistrarController`, `WrappedEthRegistrarController`, and
`UniversalRegistrarRenewalWithReferrer` placeholder entries (`address: zeroAddress,
startBlock: 0`) from sepolia-v2 and `UniversalRegistrarRenewalWithReferrer` from
ens-test-env. These were registered with Ponder, which dragged each chain's effective
startBlock to 0 and caused `historicalTotalBlocks` to overshoot by ~3.7M, producing
`Block 14473749 not found` on sepolia-v2.

In `registrars`, `subgraph`, and `ensv2` plugins, replaces per-controller Ponder
contract entries with a single `RegistrarController` entry per chain that uses
`AnyRegistrarControllerABI` (now also includes `UniversalRegistrarRenewalWithReferrer`).
Controller addresses are combined into one chain entry via the new
`mergedChainConfigForContracts` helper, with `pickContracts` for namespace-conditional
lookup. Handlers dispatch by long-form event signature, mirroring
`ensv2/handlers/ensv1/RegistrarController.ts`.

Reverts the zero-address skip in `buildIndexedBlockranges` from #2045 — the underlying
placeholders no longer exist. `getContractsByManagedName` now treats the optional
ENSRoot controllers as `maybeGetDatasourceContract` lookups and filters absent ones.

Closes #2048: the `ensv2` plugin's previous `chain: { …spread, …spread, …spread }`
pattern silently overwrote each controller's chain-id-keyed config (only the last
spread per chain id survived; on mainnet only `UnwrappedEthRegistrarController` was
indexed). The new `mergedChainConfigForContracts` helper combines addresses correctly
via `address: Address[]`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 3, 2026 20:54
@shrugs shrugs requested a review from a team as a code owner May 3, 2026 20:54
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 3, 2026

🦋 Changeset detected

Latest commit: ff228ca

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
@ensnode/datasources Patch
ensindexer Patch
ensadmin Patch
ensapi Patch
fallback-ensapi Patch
@ensnode/ensnode-sdk Patch
@ensnode/integration-test-env Patch
@namehash/namehash-ui Patch
ensrainbow Patch
@namehash/ens-referrals Patch
@ensnode/ensdb-sdk Patch
@ensnode/ensnode-react Patch
@ensnode/ensrainbow-sdk Patch
@docs/ensnode Patch
@docs/ensrainbow Patch
enssdk Patch
enscli Patch
enskit Patch
ensskills Patch
@ensnode/ponder-sdk Patch
@ensnode/ponder-subgraph Patch
@ensnode/shared-configs Patch
@ensnode/ensindexer-perf-testing Patch
@ensnode/enskit-react-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment May 3, 2026 9:28pm
ensnode-enskit-react-example Ready Ready Preview, Comment May 3, 2026 9:28pm
ensnode.io Ready Ready Preview, Comment May 3, 2026 9:28pm
ensrainbow.io Ready Ready Preview, Comment May 3, 2026 9:28pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

Warning

Rate limit exceeded

@shrugs has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 27 minutes and 30 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 36c5ce27-9a08-4a18-b324-b4b5c3dc86aa

📥 Commits

Reviewing files that changed from the base of the PR and between 5a5f3c0 and ff228ca.

📒 Files selected for processing (3)
  • .changeset/eliminate-zero-address-placeholders.md
  • .changeset/ensv2-registrar-controller-bug.md
  • apps/ensindexer/src/lib/ponder-helpers.ts
📝 Walkthrough

Walkthrough

This PR eliminates zero-address placeholder registrar controller contracts and consolidates their handling into merged per-chain controller configurations. It adds helper functions to unify contract address and blockrange logic, updates event handlers to dispatch from a single merged ABI, removes the zero-address skip workaround from blockrange calculation, and treats optional controllers as maybe-lookups instead of required ones.

Changes

Placeholder Elimination & Controller Consolidation

Layer / File(s) Summary
Data Source Configuration
packages/datasources/src/sepolia-v2.ts, packages/datasources/src/ens-test-env.ts, packages/datasources/src/lib/AnyRegistrarControllerABI.ts
Removed zero-address placeholder entries for LegacyEthRegistrarController, WrappedEthRegistrarController, and UniversalRegistrarRenewalWithReferrer. Extended AnyRegistrarControllerABI to include UniversalRegistrarRenewalWithReferrer for merged event dispatch.
Configuration Helper Functions
apps/ensindexer/src/lib/ponder-helpers.ts
Added pickContracts() to select datasource contract entries by name with optional filtering, and mergedChainConfigForContracts() to merge multiple contract configs into a single chain entry with unioned addresses and constrained blockranges.
Indexer Plugin Configuration
apps/ensindexer/src/plugins/ensv2/plugin.ts, apps/ensindexer/src/plugins/registrars/plugin.ts, apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts
Replaced individual per-contract entries for registrar controller variants with single merged RegistrarController entries per chain using mergedChainConfigForContracts() and pickContracts(), fixing chain-config overwrite bugs.
Event Handler Implementation
apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts, apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts
Updated handlers to listen to unified *RegistrarController:* event signatures (with explicit baseCost/premium/referrer variants) instead of legacy controller-specific names; remapped arguments and integrated RenewalReferred dispatch into merged controller handler.
Handler Registration & Cleanup
apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts, apps/ensindexer/src/plugins/registrars/event-handlers.ts
Removed dedicated Ethnames_UniversalRegistrarRenewalWithReferrer handler file and its plugin attachment; RenewalReferred is now handled by the merged Ethnames_RegistrarController handler.
SDK Blockrange & Optional Controller Logic
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts, packages/ensnode-sdk/src/shared/managed-names.ts
Removed zero-address skip logic from buildIndexedBlockranges() (reverting #2045); updated getContractsByManagedName() to treat LegacyEthRegistrarController and WrappedEthRegistrarController as optional via maybeGetDatasourceContract() and filter absent contracts.
Tests & Documentation
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts, .changeset/eliminate-zero-address-placeholders.md, .changeset/skip-zero-address-placeholders-blockrange.md
Removed zero-address placeholder test case; added changesets documenting the patch changes, blockrange behavior fix, and issue resolutions (#2045, #2048).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 Zero addresses fading fast,
Controllers merge at last!
No more spreads, no placeholders' plight—
One ABI shines so bright!
Blockranges sing, the SDK's content,
Consolidation time well spent! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title precisely summarizes the main change: removing zero-address placeholder contracts and consolidating multiple registrar controller entries into merged implementations.
Description check ✅ Passed The description is comprehensive and well-structured, exceeding template requirements with detailed sections on problem, concrete changes, design decisions, testing, and risk analysis.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/eliminate-zero-address-placeholders

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 27 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes zero-address placeholder contracts from datasource configs and updates indexer plugins to use a single merged RegistrarController Ponder entry per chain (dispatching by long-form event signature), fixing a chain-id spread override bug in the ENSv2 plugin and avoiding startBlock=0 backfill issues.

Changes:

  • Remove zero-address placeholder controller entries from sepolia-v2 (and URRWR from ens-test-env) and update managed-name contract lookups to treat these controllers as optional.
  • Merge ENSRoot RegistrarControllers into a single Ponder contract entry per chain across subgraph, registrars, and ensv2 plugins using AnyRegistrarControllerABI and new helpers pickContracts + mergedChainConfigForContracts.
  • Revert the buildIndexedBlockranges zero-address skip workaround and update tests/changesets accordingly.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/ensnode-sdk/src/shared/managed-names.ts Treat ENSRoot controllers as optional via maybeGetDatasourceContract(...).filter(...).
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Removes zero-address placeholder skipping logic (workaround no longer needed).
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Removes the test that asserted zero-address skipping behavior.
packages/datasources/src/sepolia-v2.ts Drops placeholder controller entries (Legacy/Wrapped/URRWR) from sepolia-v2 ENSRoot datasource.
packages/datasources/src/ens-test-env.ts Removes URRWR placeholder entry from ens-test-env datasource.
packages/datasources/src/lib/AnyRegistrarControllerABI.ts Adds URRWR ABI into merged controller ABI so RenewalReferred is available.
apps/ensindexer/src/lib/ponder-helpers.ts Adds pickContracts and mergedChainConfigForContracts helpers for merged Ponder chain config.
apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts Replaces per-controller entries with a single merged RegistrarController contract entry.
apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts Switches controller handlers to dispatch by long-form event signature under merged entry.
apps/ensindexer/src/plugins/registrars/plugin.ts Replaces four ethnames controller entries with one merged Ethnames_RegistrarController.
apps/ensindexer/src/plugins/registrars/event-handlers.ts Consolidates ethnames controller handler attachment into one file.
apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts Removed; logic moved into merged controller handler.
apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts Consolidates ethnames controller + URRWR event handling with merged dispatch.
apps/ensindexer/src/plugins/ensv2/plugin.ts Fixes #2048 by merging per-chain controller configs instead of overwriting via spreads.
.changeset/skip-zero-address-placeholders-blockrange.md Removed (replaced by new combined changeset).
.changeset/eliminate-zero-address-placeholders.md New changeset covering datasource/indexer/sdk changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/ensindexer/src/lib/ponder-helpers.ts
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 3, 2026

Greptile Summary

This PR fixes two compounding bugs on sepolia-v2: (1) zero-address placeholder contracts were dragging Ponder's effective indexed startBlock to block 0, causing Block 14473749 not found crashes; (2) the ensv2 plugin's multiple chainConfigForContract(...) spreads with the same chain-id key silently overwrote each other, leaving only UnwrappedEthRegistrarController indexed. The fix removes the placeholders and collapses all per-controller Ponder entries into a single RegistrarController entry per chain using the new mergedChainConfigForContracts/pickContracts helpers, dispatching by long-form event signature.

Confidence Score: 5/5

Safe to merge — all long-form signatures were verified against ABIs, arg remappings are correct, and the empty-array guard is in place

All long-form event signatures were cross-checked against the ABI files and are exact matches. The arg remapping in each handler (label↔labelhash, cost vs baseCost+premium) is correct for every controller. The mergedChainConfigForContracts helper guards against empty input. The pickContracts helper correctly handles absent contracts for namespace-conditional entries. The buildIndexedBlockranges revert is safe because zero-address placeholders no longer exist. No P0 or P1 issues found.

No files require special attention. The long-form signature correctness is the only manual-verification risk and has been confirmed against the ABI sources.

Important Files Changed

Filename Overview
apps/ensindexer/src/lib/ponder-helpers.ts Adds pickContracts and mergedChainConfigForContracts helpers; empty-array guard is present; address, startBlock, endBlock merge logic is correct
apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts 6 handlers merged from 4 separate files; long-form signatures match ABIs exactly; arg remapping (label↔labelhash) is correct per each controller's event definition
apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts 5 handlers merged from 6; long-form signatures match ABIs; cost/label/labelHash remapping correct for each controller
apps/ensindexer/src/plugins/ensv2/plugin.ts Fixes #2048: replaces three separate chainConfigForContract spreads (which overwrote each other) with a single mergedChainConfigForContracts call per chain
apps/ensindexer/src/plugins/registrars/plugin.ts Collapses 4 per-controller Ponder entries into one Ethnames_RegistrarController using AnyRegistrarControllerABI and mergedChainConfigForContracts
packages/ensnode-sdk/src/shared/managed-names.ts Legacy/Wrapped/URRWR controllers switched to maybeGetDatasourceContract + filter; UnwrappedEthRegistrarController kept required; pattern matches existing Basenames/Lineanames pattern
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Reverts zero-address skip workaround now that the root cause (placeholder contracts) is fixed

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Ponder: Ethnames_RegistrarController\n(AnyRegistrarControllerABI, merged addresses)"]
    A -->|"NameRegistered(string name, bytes32 indexed label, address indexed owner, uint256 cost, uint256 expires)"| B["LegacyEthRegistrarController handler\n(cost, no premium, no referral)"]
    A -->|"NameRegistered(string name, bytes32 indexed label, address indexed owner, uint256 baseCost, uint256 premium, uint256 expires)"| C["WrappedEthRegistrarController handler\n(baseCost+premium, no referral)"]
    A -->|"NameRegistered(string label, bytes32 indexed labelhash, address indexed owner, uint256 baseCost, uint256 premium, uint256 expires, bytes32 referrer)"| D["UnwrappedEthRegistrarController handler\n(baseCost+premium, with referral)"]
    A -->|"NameRenewed(string name, bytes32 indexed label, uint256 cost, uint256 expires)"| E["Legacy+Wrapped NameRenewed handler\n(cost, no premium, no referral)"]
    A -->|"NameRenewed(string label, bytes32 indexed labelhash, uint256 cost, uint256 expires, bytes32 referrer)"| F["UnwrappedEthRegistrarController NameRenewed\n(cost, no premium, with referral)"]
    A -->|"RenewalReferred (short form)"| G["UniversalRegistrarRenewalWithReferrer handler"]
    subgraph "pickContracts + mergedChainConfigForContracts"
        H["LegacyEthRegistrarController address"] --> I["Merged address[]"]
        J["WrappedEthRegistrarController address"] --> I
        K["UnwrappedEthRegistrarController address"] --> I
        L["URRWR address (optional)"] --> I
    end
    I --> A
Loading

Reviews (4): Last reviewed commit: "fix: bot notes (loop 2) — undefined addr..." | Re-trigger Greptile

Comment thread apps/ensindexer/src/lib/ponder-helpers.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensindexer/src/lib/ponder-helpers.ts`:
- Around line 191-194: The calculation of minStartBlock using contracts.reduce
can yield Number.POSITIVE_INFINITY when contracts is empty; update the function
in ponder-helpers.ts that computes minStartBlock (where minStartBlock and
contracts are used) to defensively handle an empty contracts array by either
throwing a clear error/ assertion or returning early with a sensible default;
specifically check if contracts.length === 0 before the reduce and raise an
explanatory exception or return a configured fallback so the chain config never
receives Infinity.

In `@apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts`:
- Around line 111-128: The premium-registration handlers rebuild event.args from
scratch causing emitted fields like owner and expires to be dropped; in the
addOnchainEventListener callbacks (see namespaceContract(...) match and the
async handler that calls handleNameRegisteredByController) merge the original
event.args with the overrides instead of replacing it — e.g. create args as {
...event.args, label: event.args.name, labelHash: event.args.label, cost:
event.args.baseCost + event.args.premium } so owner/expires and any other
emitted fields are preserved; apply the same merge fix to the other premium
branch (the similar handler around the other occurrence).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 014b5165-eb3a-47e8-afa6-56ce4ad25a34

📥 Commits

Reviewing files that changed from the base of the PR and between f5f4430 and 5a5f3c0.

📒 Files selected for processing (16)
  • .changeset/eliminate-zero-address-placeholders.md
  • .changeset/skip-zero-address-placeholders-blockrange.md
  • apps/ensindexer/src/lib/ponder-helpers.ts
  • apps/ensindexer/src/plugins/ensv2/plugin.ts
  • apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts
  • apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts
  • apps/ensindexer/src/plugins/registrars/event-handlers.ts
  • apps/ensindexer/src/plugins/registrars/plugin.ts
  • apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts
  • apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts
  • packages/datasources/src/ens-test-env.ts
  • packages/datasources/src/lib/AnyRegistrarControllerABI.ts
  • packages/datasources/src/sepolia-v2.ts
  • packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts
  • packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts
  • packages/ensnode-sdk/src/shared/managed-names.ts
💤 Files with no reviewable changes (5)
  • packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts
  • packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts
  • apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts
  • packages/datasources/src/ens-test-env.ts
  • .changeset/skip-zero-address-placeholders-blockrange.md

Comment thread apps/ensindexer/src/lib/ponder-helpers.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

🚀 Preview Packages - feat/eliminate-zero-address-placeholders

NPM Packages:

# Install latest preview for this branch
pnpm add @ensnode/datasources@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ensnode-react@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ensrainbow-sdk@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ensdb-sdk@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ensnode-sdk@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ponder-sdk@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ponder-subgraph@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/ens-referrals@preview-feat-eliminate-zero-address-pl
pnpm add @ensnode/namehash-ui@preview-feat-eliminate-zero-address-pl

# Or install specific version
pnpm add @ensnode/ensnode-sdk@0.0.0-preview-feat-eliminate-zero-address-pl-20260503205708

Lambda Functions:

Published as GitHub Actions artifacts:
- fallback-ensapi-preview-feat-eliminate-zero-address-pl

Download from: https://github.com/namehash/ensnode/actions/runs/25290571331

Docker Images:

docker pull ghcr.io/namehash/ensnode/ensindexer:preview-feat-eliminate-zero-address-pl-5a5f3c0c
docker pull ghcr.io/namehash/ensnode/ensadmin:preview-feat-eliminate-zero-address-pl-5a5f3c0c
docker pull ghcr.io/namehash/ensnode/ensapi:preview-feat-eliminate-zero-address-pl-5a5f3c0c
docker pull ghcr.io/namehash/ensnode/ensrainbow:preview-feat-eliminate-zero-address-pl-5a5f3c0c

Build Info:

  • 🎯 Target: 📦 NPM packages + ⚡ Lambda functions + 🐳 Docker images
  • 📦 Version: 0.0.0-preview-feat-eliminate-zero-address-pl-20260503205708
  • 📝 Commit: 5a5f3c0c
  • 🌿 Branch: feat/eliminate-zero-address-placeholders
  • ⏰ Built: 2026-05-03 21:01:57 UTC
  • 🔗 Workflow Run

🤖 This comment will be updated on subsequent publishing of release previews from the branch associated with this PR

Note: Preview packages are managed by changesets. NPM dist-tags can be cleaned up manually using npm dist-tag rm @ensnode/ensnode-sdk preview-feat-eliminate-zero-address-pl

addOnchainEventListener(
namespaceContract(pluginName, "Ethnames_LegacyEthRegistrarController:NameRenewed"),
namespaceContract(
pluginName,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the deduplication in the diff, this diff is going to look odd, but read the file in isolation for clarity.

… empty input

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 3, 2026 21:16
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 3, 2026 21:16 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 3, 2026 21:16 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 3, 2026 21:16 Inactive
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented May 3, 2026

@greptile review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/ensindexer/src/lib/ponder-helpers.ts Outdated
Comment thread .changeset/ensv2-registrar-controller-bug.md Outdated
…et typo

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented May 3, 2026

@greptile review

Comment on lines +159 to +161
export function pickContracts(
contracts: Record<string, ContractConfig>,
names: readonly string[],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had an idea that maybe it's possible to make something like

contracts: Record<T, ContractConfig>,
names: T[]

But I lost to compiler, I just dont understand how typescript works...

args: {
// this field is the labelhash, not the label
label: labelHash,
// rename to labelHash
Copy link
Copy Markdown
Member

@sevenzing sevenzing May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is TODO, does it make sense to add // TODO: ? At first I thought this is prompt for AI autocompletion 😄

Copy link
Copy Markdown
Member

@sevenzing sevenzing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ENSv2 plugin silently overrides RegistrarController address per chain

3 participants