Skip to content

feat(ensindexer): re-derive Resolver.extended on EIP-1967 proxy upgrade (.box)#2280

Open
shrugs wants to merge 8 commits into
mainfrom
feat/reclassify-extended-on-proxy-upgrade
Open

feat(ensindexer): re-derive Resolver.extended on EIP-1967 proxy upgrade (.box)#2280
shrugs wants to merge 8 commits into
mainfrom
feat/reclassify-extended-on-proxy-upgrade

Conversation

@shrugs

@shrugs shrugs commented Jun 9, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #2275. ENSIndexer classifies a Resolver's IExtendedResolver (ENSIP-10) support once, at the block the resolver is first seen, via an eip-165 supportsInterface probe. For proxy resolvers that activate IExtendedResolver after they're assigned (deploy-then-upgrade), that snapshot is computed against the pre-upgrade implementation and gets stuck false forever.

A stale false silently breaks ENSIP-10 wildcard resolution: affected names don't virtualize into UnindexedDomain and Domain.resolve returns null. The concrete case is the .box TLD (3DNS), whose resolver 0xf97aac6c8dbaebcb54ff166d79706e3af7a813c8 is an EIP-1967 proxy:

block event supportsInterface(0x9061b923)
19128555 proxy deployed + set as box's resolver (impl 0xb4cd…959b) reverts
19128940 EIP-1967 Upgraded → impl 0xee65…4546 true (from here on)

First-visibility probed at 19128555 (pre-upgrade → revert) → cached is_extended = false, never re-checked → mystery.box returned null instead of 0x130EF…7562.

What this does

Keeps extended indexed (no supportsInterface RPC at query / acceleration time) and adds the agreed direction from the issue: classify on first visibility + re-derive on a known proxy upgrade pattern.

  • New minimal UpgradeableProxy ABI (@ensnode/datasources) — just EIP-1967 Upgraded(address indexed implementation).
  • New DotBoxL1Resolver contract in the Mainnet ENSRoot datasource (the 3DNS proxy address).
  • The Protocol Acceleration plugin registers an UpgradableProxyResolver contract over that address and, on each Upgraded, re-runs the eip-165 probe against the new implementation and updates the row (handleResolverImplementationChange). The re-derivation no-ops for any address that isn't already an indexed Resolver, so it never creates junk rows.

Why scoped to a single address (not a chain-wide Upgraded filter)

An address-less Upgraded topic filter would auto-cover every proxy resolver but means fetching/decoding ~5–6M Upgraded logs per full reindex (sampled estimate: ~1M mainnet, ~3M Base, ~0.5M Optimism), dominated by Base + mainnet. Issue #2275 explicitly asked for the narrowest thing that fixes .box, so this watches the one known proxy resolver.

A survey of all 1294 TLDs (root registry domains) via Omnigraph, cross-checked against on-chain supportsInterface + the EIP-1967 impl slot, confirms the scope is sufficient at the TLD level:

  • Every indexed extended value matches on-chain — no stale-false resolvers. The only false TLD is .eth, whose resolver is a plain non-wildcard PublicResolver (correctly false, not a proxy).
  • 0xf97aac… (box / 3DNS) is the only EIP-1967 proxy among all 1294 TLD resolvers. The dominant DNSSEC resolver (1286 TLDs, 0xf142b308…) and the rest are plain non-upgradeable contracts.

Deeper (2LD) wildcard resolvers were not surveyed; the address-allowlist can be extended if a proxy resolver shows up there.

Testing

  • pnpm typecheck (all workspaces), pnpm lint, pnpm test — green.
  • Manual: cast-verified supportsInterface + EIP-1967 impl slot for every distinct TLD resolver.

Notes

  • Schema/handler change → requires a reindex.

shrugs added 6 commits June 9, 2026 11:18
…rade

Resolver `isExtended` (ENSIP-10 IExtendedResolver support) was classified
once at first visibility. Proxy Resolvers that activate IExtendedResolver via
a post-assignment upgrade (e.g. the 3DNS Resolver behind `.box`) were stuck
`false` forever, silently breaking wildcard resolution.

The Protocol Acceleration plugin now watches the 3DNS Resolver's EIP-1967
`Upgraded` events and re-runs the supportsInterface probe against the new
implementation, updating the stored row. Scoped to the `.box` case.

Fixes #2275.
@shrugs shrugs requested a review from a team as a code owner June 9, 2026 21:30
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

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

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

@changeset-bot

changeset-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 212e450

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

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

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@shrugs, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 41 minutes and 28 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: de7545c2-908e-4481-93a9-12033dd603e5

📥 Commits

Reviewing files that changed from the base of the PR and between a801332 and 212e450.

📒 Files selected for processing (4)
  • apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/event-handlers.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/handlers/UpgradeableProxyResolver.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts
📝 Walkthrough

Walkthrough

The PR adds on-chain event detection for proxy resolver upgrades (EIP-1967) and re-derives ENSIP-10 IExtendedResolver support when the implementation changes, fixing cases where proxy resolvers remained incorrectly marked as non-extended after upgrades.

Changes

Proxy Resolver Upgrade Handler

Layer / File(s) Summary
ABI definition and datasource configuration
packages/datasources/src/abis/shared/UpgradeableProxy.ts, packages/datasources/src/index.ts, packages/datasources/src/mainnet.ts
Defines the EIP-1967 Upgraded event ABI, exports it as UpgradeableProxyABI, and adds DotBoxL1Resolver contract configuration to mainnet datasources for indexing.
Plugin and event handler registration
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts, apps/ensindexer/src/plugins/protocol-acceleration/handlers/UpgradableProxyResolver.ts, apps/ensindexer/src/plugins/protocol-acceleration/event-handlers.ts
Imports the ABI into the plugin, configures indexing of the UpgradableProxyResolver contract with conditional chain config, creates the Upgraded event handler, and registers it in the handler initialization.
Resolver extended support recalculation
apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts
Refactors upsertResolver to be idempotent, introduces updateResolverInterfaces helper to recalculate and persist IExtendedResolver support, and updates handleResolverImplementationChange to trigger recalculation for existing resolvers.
Release documentation
.changeset/reclassify-extended-on-proxy-upgrade.md
Documents the patch release and the behavioral fix for proxy resolver extended support derivation.

Sequence Diagram

sequenceDiagram
  participant Chain as On-Chain Proxy
  participant Handler as UpgradableProxyResolver Handler
  participant UpdateLogic as updateResolverInterfaces
  participant DB as Resolver Database
  
  Chain->>Handler: emit Upgraded(implementation)
  Handler->>UpdateLogic: handleResolverImplementationChange
  UpdateLogic->>UpdateLogic: isExtendedResolver check
  UpdateLogic->>DB: update resolver.extended flag
  DB-->>UpdateLogic: confirmation
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • namehash/ensnode#2275: This PR implements the exact fix described—adding Upgraded event detection, UpgradeableProxy ABI, and logic to re-check and update resolver extended support on proxy upgrades.

Possibly related PRs

  • namehash/ensnode#2271: The PR's indexer changes to correctly (re)compute a resolver's isExtended/extended support on proxy Upgraded events are directly required by the related PR's unindexed-domain resolution logic that depends on that extended metadata.

Poem

🐰 A proxy hops and changes coat,
Its extended status lost in the moat,
But now we listen for Upgraded's call,
Re-deriving support through it all!
Wildcard resolution hops once more.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: re-deriving Resolver.extended on EIP-1967 proxy upgrades for the .box resolver, which is the core purpose of the PR.
Description check ✅ Passed The description follows the template structure with Summary, Why, Testing, and Notes sections, providing comprehensive context about the issue, solution, and scope.
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/reclassify-extended-on-proxy-upgrade

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

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

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a stale isExtended = false bug for proxy resolvers (specifically the .box / 3DNS resolver 0xf97aac…) where the EIP-165 supportsInterface probe was run once at first-visibility against the pre-upgrade implementation, which reverts, and the false result was cached forever.

  • New UpgradeableProxy ABI added to @ensnode/datasources and a DotBoxL1Resolver contract entry added to the mainnet ENSRoot datasource.
  • handleResolverImplementationChange is introduced: on each Upgraded event from the known proxy address, it re-runs the EIP-165 probe against the current implementation and updates the row — no-op-ing for addresses not already indexed as a Resolver.
  • upsertResolver refactored into a two-step insert-then-update: row is first inserted with the isExtended default (false), then updateResolverInterfaces makes the RPC probe (which returns false gracefully on revert) and writes the real value.

Confidence Score: 5/5

Safe to merge; the change is narrowly scoped to one known proxy address, all logic paths are correctly guarded, and the RPC probe is always safe to retry via the Upgraded event.

The refactored upsertResolver two-step is safe because isExtendedResolver catches every revert and returns false rather than throwing, so the insert is never left without a subsequent update. The handleResolverImplementationChange guard correctly no-ops for unknown addresses. The optional DotBoxL1Resolver spread mirrors existing codebase patterns and degrades gracefully to an empty chain config when the contract is absent. No callers of upsertResolver consumed its return value, so the void return is non-breaking.

No files require special attention.

Important Files Changed

Filename Overview
apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts Refactors upsertResolver into a two-step insert+update and adds handleResolverImplementationChange; safe because isExtendedResolver never throws (catches reverts and returns false).
apps/ensindexer/src/plugins/protocol-acceleration/handlers/UpgradeableProxyResolver.ts New handler for Upgraded events; correctly uses getThisAccountId to get the proxy address (not the implementation) and delegates to handleResolverImplementationChange.
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Adds UpgradeableProxyResolver contract config using UpgradeableProxyABI; the optional DotBoxL1Resolver guard mirrors the existing pattern for optional contracts and safely produces chain:{} when absent.
packages/datasources/src/abis/shared/UpgradeableProxy.ts Minimal EIP-1967 ABI with only the Upgraded event; definition matches the standard exactly.
packages/datasources/src/mainnet.ts Adds DotBoxL1Resolver contract entry with the correct address and startBlock matching the on-chain proxy deployment block (19128555).
apps/ensindexer/src/plugins/protocol-acceleration/event-handlers.ts Registers the new UpgradeableProxyResolver handler alongside existing handlers; ordering is handler-registration only, no functional impact.
packages/datasources/src/index.ts Re-exports the new UpgradeableProxyABI under the standard ABI alias convention.
.changeset/reclassify-extended-on-proxy-upgrade.md Correctly tagged as a patch change for ensindexer with a clear description of the behavioral fix.

Reviews (5): Last reviewed commit: "refactor: spell UpgradeableProxyResolver..." | Re-trigger Greptile

Comment thread apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 fixes stale Resolver.extended (ENSIP-10 IExtendedResolver support) for the .box TLD resolver by re-deriving the indexed isExtended flag when a known EIP-1967 proxy resolver emits an Upgraded event, rather than freezing the value at first visibility.

Changes:

  • Add a minimal EIP-1967 Upgraded(address) ABI and expose it via @ensnode/datasources.
  • Add the .box resolver proxy address to the ENSRoot mainnet datasource and register a dedicated Protocol Acceleration contract to listen for Upgraded.
  • Update resolver DB helpers to support re-deriving supported-interface flags for already-indexed resolvers on proxy upgrades.

Reviewed changes

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

Show a summary per file
File Description
packages/datasources/src/mainnet.ts Adds DotBoxL1Resolver contract metadata (address + startBlock) for mainnet ENSRoot.
packages/datasources/src/index.ts Re-exports the new UpgradeableProxyABI from datasources.
packages/datasources/src/abis/shared/UpgradeableProxy.ts Introduces minimal EIP-1967 proxy ABI for Upgraded event decoding.
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Registers an Upgraded event source (scoped to .box proxy) for interface re-derivation.
apps/ensindexer/src/plugins/protocol-acceleration/handlers/UpgradableProxyResolver.ts Adds handler that triggers resolver interface re-derivation on Upgraded.
apps/ensindexer/src/plugins/protocol-acceleration/event-handlers.ts Wires the new UpgradableProxyResolver handler into protocol-acceleration.
apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts Refactors resolver upsert + adds handleResolverImplementationChange to update isExtended for indexed resolvers.
.changeset/reclassify-extended-on-proxy-upgrade.md Adds a patch changeset describing the behavior fix.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts`:
- Around line 36-51: The callers in Resolver.ts and Registry.ts expect
upsertResolver to return the resolver row (they access resolver.coinTypes,
resolver.texts, resolver.addrId) but upsertResolver currently returns void;
restore the original behavior by returning the resolver entity: after computing
id and checking/inserting, fetch or construct the inserted/updated resolver
record and return it (use context.ensDb.find or the insert result) while still
calling updateResolverInterfaces(context, resolver); ensure the returned shape
matches the callers' expectations (fields like coinTypes, texts, addrId) and
update the function's Promise return type accordingly.

In `@apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts`:
- Around line 105-119: The namespace key uses the nonstandard spelling
"UpgradableProxyResolver" while the ABI and standards use
"UpgradeableProxyResolver"; update all references to standardize the name:
rename the namespaceContract entry from "UpgradableProxyResolver" to
"UpgradeableProxyResolver", update any handler/file names and exports that
reference that symbol, and adjust any imports/usages (e.g., the handler file and
any call sites referencing UpgradableProxyResolver, plus the UpgradeableProxyABI
and DotBoxL1Resolver references) so the project consistently uses
"UpgradeableProxyResolver" across the codebase.
🪄 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: e7e7d31c-59bc-4639-ba4e-3212bf01e23c

📥 Commits

Reviewing files that changed from the base of the PR and between 0a9d4eb and a801332.

📒 Files selected for processing (8)
  • .changeset/reclassify-extended-on-proxy-upgrade.md
  • apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/event-handlers.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/handlers/UpgradableProxyResolver.ts
  • apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts
  • packages/datasources/src/abis/shared/UpgradeableProxy.ts
  • packages/datasources/src/index.ts
  • packages/datasources/src/mainnet.ts

Comment thread apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts Outdated
Comment thread apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io June 9, 2026 21:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io June 9, 2026 21:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensnode.io June 9, 2026 21:39 Inactive
@shrugs

shrugs commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@greptile review

Copilot AI review requested due to automatic review settings June 9, 2026 21:49
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io June 9, 2026 21:49 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io June 9, 2026 21:49 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensnode.io June 9, 2026 21:49 Inactive
@shrugs

shrugs commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@greptile review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 8 out of 8 changed files in this pull request and generated 1 comment.

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

Labels

None yet

Projects

None yet

2 participants