[Executable] Activate ENSv2

Vote onchain: Blockful | Tally

Abstract

This proposal activates ENSv2 on Ethereum mainnet. Once executed, it:

  • freezes new .eth registrations on the v1 registrar;
  • authorises the contracts that keep unmigrated names renewable and clean up after migrated ones;
  • hands ownership of the v1 BaseRegistrar to a renew-only contract;
  • points the Universal Resolver at a proxy that will carry the switch to v2 resolution.

Afterwards, ENS Labs will:

  • run a final pre-migration sync so every live v1 name is reserved for its current owner on v2;
  • open registrations on the v2 ETHRegistrar;
  • cut resolution over to v2;
  • transfer every admin role it holds over the v2 contracts to the DAO.

When that’s done, the DAO controls ENSv2 just as it controls v1 today, and Labs holds no privileged role in either.

Motivation

The ENS registry we deployed in 2017 is a single flat mapping from namehash to owner, resolver and TTL. Everything built since then - the permanent registrar, the NameWrapper, fuses, wildcard resolution, CCIP-read - has been layered on top of that mapping rather than built into it. It’s held up well, but the cost shows: the NameWrapper exists largely to bolt on permissions the registry can’t express, and it’s the single most complex and least well understood part of ENS today.

ENSv2 replaces the flat registry with a hierarchy of registries. Every name can have its own registry for its subnames, and owners can bring their own registry and resolver implementations rather than relying on standard implementations. Permissions are fine-grained roles on each name instead of irreversible fuses, so it’s possible to give a subname owner exactly the rights you intend - set a resolver but not transfer, say - without wrapping anything.

How activation works

Activation runs in five stages, and at the end of them the DAO holds every privileged role over both v1 and v2. Only stage 2 needs a vote; every other stage either has already happened or is something Labs commits to carry out once this proposal executes.

  1. Deployment and initial pre-migration (Labs, done before this vote). Labs has deployed the full v2 contract set to mainnet, with the v2 ETHRegistrar deployed but not authorised to register names. Labs has then reserved every active or in-grace v1 .eth second-level name on v2 for its current owner, via a BatchRegistrar that only Labs controls. Reserved names are owned by the migration controller in v2; they continue to resolve through ENSV1Resolver, which reads their existing v1 records.
  2. This proposal executes (DAO). In a single atomic transaction, the DAO:
    • points the v1 .eth resolver at ENSV2Resolver and authorises the v2 reverse registrar adapters on the v1 reverse registrars;
    • approves the two current v1 PublicResolvers in v2’s PublicResolverSet, so names that use them move to the v2 PublicResolver when they migrate;
    • approves the standalone HCA implementation in the StandaloneHCAFactory, so the factory can deploy HCA accounts;
    • removes every remaining controller from the v1 BaseRegistrar, freezing new v1 registrations;
    • authorises ETHRenewerV1, so names that haven’t migrated yet stay renewable;
    • authorises the Graveyard, which holds migrated v1 tokens and reclaims v1 names once they’ve expired past grace;
    • transfers ownership of the v1 BaseRegistrar to ETHRenewerV1, which can renew but cannot add controllers or register names;
    • points the Universal Resolver proxy at an intermediate proxy that, for now, still serves v1 resolution.
  3. Final pre-migration sync (Labs). Labs exports a fresh snapshot of v1 registrations taken after the freeze and re-runs pre-migration. This picks up any name registered or renewed between the first pre-migration run and the freeze.
  4. v2 goes live (Labs). Labs revokes the BatchRegistrar’s roles, ending pre-migration for good; enables the two migration controllers and grants ETHRegistrar the right to register and renew .eth names. Labs asks the security council to upgrade the UniversalResolver implementation to point at UR v2. From this point, new registrations happen on v2, and resolution of every name goes through the v2 registry.
  5. Handover to the DAO (Labs). Labs transfers every admin role it holds over v2 to the DAO timelock and renounces its own: root roles on the v2 root and .eth registries, and ownership of the BatchRegistrars used for .eth and DNS suffix seeding. Labs transfers the .eth and .reverse tokens in the v2 root registry to a Safe (0x5B716D6587d241166bC8914858640F8684F3A2F3) whose sole owner is the DAO timelock. The tokens go to a Safe rather than to the timelock itself because the timelock can’t receive ERC-1155 tokens. The intermediate Universal Resolver proxy is administered by the security council, not Labs, and stays with the security council. Labs will publish each transaction and a script that checks the deployer holds no remaining role.

The registrar, renewer and other ownable v2 contracts are deployed with the DAO timelock (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7) as owner from the start. Registration and renewal fees on v2, including renewals of unmigrated names through ETHRenewerV1, are paid directly to the ENS Endowment (endowment.ensdao.eth, 0x4F2083f5fBede34C2714aFfb3105539775f7FE64), which is owned by the ENS Foundation and managed by Karpatkey. The fee recipient is fixed at deployment, so nothing about revenue changes hands in stage 5. The time between stages 2 and 4 is set by how long the final sync takes; we expect it to be a few hours. During this time, registrations won’t be possible on either ENSv1 or ENSv2, but all other name operations continue as normal on ENSv1. Renewals of unmigrated names will be possible once the DAO proposal executes, via the new renewer contract.

What changes for name owners

If you own a .eth name and do nothing, it keeps working. It resolves exactly as it does today, and you can keep renewing it as usual; renewing it also extends its reservation on v2. There’s no deadline to migrate.

When you’re ready, you can move your name to v2 using the ENS app. Wrapped names with locked permissions keep them, so any guarantees you’ve given to holders of your subnames carry across. Once a name has moved, it’s managed on v2 from then on.

A few details worth knowing:

  • Expiry. Your name lapses on exactly the same day on v2 as it would have on v1. v2 has a shorter grace period, 28 days rather than 90, so each name’s v2 expiry is extended by 62 days to make up the difference.
  • Expired names. Names that have already lapsed past their grace period aren’t carried across, and become available for anyone to register on v2.
  • New registrations and renewals. Between this proposal executing and v2 going live, new names can’t be registered. Existing names can still be renewed, through ETHRenewerV1.
  • Pricing. Registrations and renewals on v2 use the pricing the DAO approved in EP 6.43, paid in USDC or DAI. This applies from the moment this proposal executes, including to renewals of names that haven’t migrated yet.
  • Apps and integrations. All apps and integrations need to be updated to resolve against the UniversalResolver to make them v2-compatible. The DevRel team have been working hard to get this done and the majority of integrations are already v2-ready.

Risks and rollback

The v1 freeze is reversible; migrating a name is not. Until stage 4, nothing a name owner does on v2 is final, and the DAO can undo stage 2 with a further executable proposal: as owner of ETHRenewerV1, it can call transferRegistrarOwnership to hand the BaseRegistrar back to RegistrarSecurityController and then re-add the v1 controllers. Once owners start migrating, their v1 tokens are held by the Graveyard, which has no means of returning them.

Five things change about how ENS is protected:

  • No emergency disable on v1. Today RegistrarSecurityController lets an emergency controller (0xaA5cD05f6B62C3af58AE9c4F3F7A2aCC2Cdc2Cc7) disable a registrar controller without a vote. Once ETHRenewerV1 owns the BaseRegistrar, that path no longer applies. The only controllers left are ETHRenewerV1, which can only renew names already reserved on v2, and the Graveyard, which can only claim names that have expired past grace.
  • No v1 registrations, ever. ETHRenewerV1 has no function to add a controller, so v1 can’t be reopened for registration without the DAO first reclaiming ownership.
  • Some v2 roles are deliberately broader than v2 needs long-term. For example, the .eth token in the root registry carries every role, including the right to unregister .eth from the root. Keeping these lets the DAO fix any errors found after launch without a full redeployment. Once v2 has run safely, a follow-up executable proposal will revoke the roles that aren’t needed, making v2 as trustless as v1.
  • The security council administers the intermediate Universal Resolver proxy. Once call 15 executes, the canonical Universal Resolver forwards to a proxy the security council can upgrade without a vote. That’s how resolution moves to v2 in stage 4. The DAO keeps the final say, since it can repoint the Universal Resolver proxy itself with an executable proposal.
  • Labs holds admin over v2 between stages 1 and 5. That’s unavoidable if Labs is to run pre-migration without a vote per batch. It’s bounded by stage 5, and the v2 contracts that handle funds are owned by the DAO from deployment.

Specification

The executable makes 15 calls, executed in order from the DAO timelock. Calls 7 to 11 remove every controller currently authorised on the v1 BaseRegistrar, as read from mainnet on 11 October 2026; the previous WrappedETHRegistrarController (0x253553366Da8546fC250F225fe3d25d0C782303b) was never a BaseRegistrar controller. It registers and renews through the NameWrapper, so it stops working once call 8 removes the NameWrapper. Calls 12 and 13 must come before call 14, because the registrar’s owner can’t change controllers once ownership has moved to ETHRenewerV1.

# Target Call Purpose
1 RegistrarSecurityController 0x7dd4d97653A67C2FD7fbA0a84825eC09524D4E1b setRegistrarResolver(0xa6D451C5E283Bdd0a7c193910F55db57512AA7B2) Point .eth at ENSV2Resolver
2 DefaultReverseRegistrar 0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9 setController(0xd86E32499eCAFe9c181dd7410f93A1a9bB61ef0d, true) Let DefaultReverseRegistrarAdapter write v1 default reverse records
3 ReverseRegistrar 0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb setController(0x349151735790269a9C14668B58D7C83b5ecb9607, true) Let ReverseRegistrarAdapter write v1 reverse records
4 PublicResolverSet 0xfFCedA021CBDF20f1a66ebbef32E49d208cAbf62 approve(0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63, true) Mark the 2023 PublicResolver as a v1 public resolver, so migrated names move to the v2 PublicResolver
5 PublicResolverSet approve(0xF29100983E058B709F3D539b0c765937B804AC15, true) Same, for the current v1 PublicResolver
6 StandaloneHCAFactory 0x742bf21897a78e2C98cC5f5C5473A370a081e561 setImplementationApproval(0x116F462FA078ec0009e9b25DCd60309E70aaC4F4, true) Approve the StandaloneSingleOwnerHCA implementation, so the factory can deploy HCA accounts
7 RegistrarSecurityController removeRegistrarController(0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547) Disable current ETHRegistrarController
8 RegistrarSecurityController removeRegistrarController(0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401) Disable NameWrapper
9 RegistrarSecurityController removeRegistrarController(0x60C7C2A24b5e86C38639Fd1586917a8FEF66a56d) Disable 2020 RegistrarMigration
10 RegistrarSecurityController removeRegistrarController(0xCF60916b6CB4753f58533808fA610FcbD4098Ec0) Disable legacy 4-of-7 Safe
11 RegistrarSecurityController removeRegistrarController(0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5) Disable original 2020 ETHRegistrarController
12 RegistrarSecurityController addRegistrarController(0xDa021A2C1C2F99574D861Ef8c6fA745851BEB7F6) Authorise the Graveyard to reclaim expired v1 names
13 RegistrarSecurityController addRegistrarController(0x56c447F308F463A01121C41E72b0E7e7557fCb68) Authorise ETHRenewerV1, keeping unmigrated names renewable
14 RegistrarSecurityController transferRegistrarOwnership(0x56c447F308F463A01121C41E72b0E7e7557fCb68) Hand the v1 BaseRegistrar to ETHRenewerV1, locking down v1
15 Universal Resolver proxy 0xeEeEEEeE14D718C2B47D9923Deab1335E144EeEe upgradeTo(0xcFFd2Ae680CD110D28739a70922636B5937b022B) Route resolution via the managed proxy (administered by the security council), which still serves the v1 UniversalResolver

After execution, anyone can confirm the result by checking that:

  • BaseRegistrarImplementation.owner() returns ETHRenewerV1;
  • BaseRegistrarImplementation.controllers() is true for ETHRenewerV1 and the Graveyard, and false for the five addresses in calls 7 to 11;
  • ENSRegistry.resolver(namehash("eth")) returns ENSV2Resolver;
  • controllers() on the ReverseRegistrar and DefaultReverseRegistrar is true for their respective adapters;
  • PublicResolverSet.includes() is true for both v1 PublicResolver addresses;
  • StandaloneHCAFactory.approvedImplementations() is true for the HCA implementation;
  • the Universal Resolver proxy’s implementation() returns the managed proxy.
15 Likes

FireEyes will be voting yes on this proposal, while still noting; What a shame it is that this proposal/v2 launch has been overshadowed by; a abandoned L2, an under utilized delegation incentive program, a takeover of the ENS DAO (through ENS labs delegation) and a newly instated purely cosmetic foundation.

NOTE to forum moderators; This is our delegate opinion about a pivotal moment in ENS’ history.

6 Likes

Excited for ENSv2, I support this upgrade and look forward to seeing ENS become more powerful, flexible, and accessible.

4 Likes

Exciting. Lot’s to follow and coordinate across people, orgs, projects, sites and apps.

1 Like

Edited 2026-10-13: We identified some configuration issues with the original deployment of the root registry, and have redeployed it and any contracts that depend on it. Further, Blockful identified that funds would have been sent to the DAO wallet rather than the endowment; we’ve redeployed the contracts concerned also. As a result several addresses have been changed above.

Please also be noted that the smart contract audits of the v2 protocol are complete and you can find the report in this PR.

4 Likes

How would migration look like for domains using either a custom or an older public resolver such as 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41?

Wouldn’t it be feasible to expand the list of approved v1 public resolvers? For example, 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41 still to date shows roughly half the daily activity of the 2023 PublicResolver (0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63), and around double the total tx count. It’s probably not an edge case if a domain is still using that resolver.

Other than that, are users encouraged to update their resolver that are not pre-approved before v2 goes live or would it be just fine if they do that later, ie. manually updating the resolver after migration?

This is now live for voting.

1 Like

ENSv2 Activation: Calldata Review

Summary

The 15 calls in the Activate ENSv2 proposal do what the proposal says, with a few trust assumptions described in the findings.

ENS Labs shared the proposal on 8 October. We reviewed it, ENS Labs made several changes, and the proposal was submitted on chain on 18 October. We rebuilt every call on our own, and all 15 match the proposal on chain exactly. Of our nine findings, six are resolved. ENS Labs acknowledged two more and will resolve them: the HCA key and ETH payments in Q4 2026 or Q1 2027. One is open: live code not covered by the audits (L04). One question is also still open: who holds the HCA key until Q4 2026 or Q1 2027 (M01).

ID Issue Severity Status
H01 The handover plan gave control of .eth to the Endowment instead of the DAO High Resolved
M01 One outside key sits behind every HCA account Medium Acknowledged, will resolve
M02 on.eth would stop working Medium Resolved
M03 The HCA audit link was broken Medium Resolved
L01 Fees went to the timelock instead of the Endowment Low Resolved
L02 The description still named the old resolver for call 1 Low Resolved
L03 Code changed after the audits Low Resolved
L04 Live code not covered by the audits Low Open
N01 No ETH payments after the vote Note Acknowledged, will resolve

What the proposal does

  • Stops new .eth registrations on the current system (v1). Existing names keep working.
  • Keeps renewals open for existing names, paid in USDC or DAI.
  • Connects .eth lookups to the new system (v2).
  • Gives the Security Council the switch that moves lookups to v2 when ENS Labs is ready.
  • Turns on HCA accounts, which let users register a name with one signature.

After the vote, ENS Labs finishes the move in three steps without another vote: a final copy of all names, going live on v2, and handing its admin powers to the DAO. Until that handover, ENS Labs’ deployer key holds the v2 admin roles. We asked whether these roles could go to the Security Council at the vote. ENS Labs explained the migration needs them and that involving the Security Council would make the launch more complex. The proposal limits them to the launch period and commits to publishing each handover transaction, with a script that checks the deployer keeps no role.

How we checked

We rebuilt the 15 calls from the proposal text and the contract code, and compared them byte for byte with the calldata on chain (our test). We re-ran the check against the proposal submitted on chain on 18 October, at Ethereum block 26,221,944. Its calls and description match the version we reviewed, except for the call 1 address in the description, which is now correct (L02). Our test takes the live proposal through the vote, queue and execution on a copy of Ethereum mainnet, checks the result, then runs the next steps to see what changes for name owners.

On 18 October, ENS Labs replaced 10 v2 contracts to fix issues in the DNSSEC and name lookup code. Only call 1 changed: it now points .eth at a new ENSv2Resolver (0x3071AD643cE4Ed8b3D67b289845b45dB82b068A4). The new resolver has the same settings as the old one, and no live v2 contract still points to a replaced one.

Findings

H01. The handover plan gave control of .eth to the Endowment instead of the DAO

Severity: High. Status: Resolved.

In the new system, whoever holds the .eth token decides where every .eth name is looked up. ENS Labs’ plan gave this token to the Endowment Safe, which the ENS Foundation runs through its own timelock. The DAO has no role there.

Fix: give the token to a Safe that only the DAO controls.

Update: The plan now gives the token to a new DAO Safe whose only owner is the DAO timelock, which we checked on chain. The transfer happens at the handover, and we will verify it then.

M01. One outside key sits behind every HCA account

Severity: Medium. Status: Acknowledged, will resolve.

HCA accounts let users register a name with one signature, while a service run by Rhinestone sends the transactions. Every HCA account relies on this service, and a single key can change the service’s code. If that key were stolen or misused, it could move the remaining v1 names of users who approved the migration helper, and set the primary name of addresses that have none. Nobody is exposed before the vote executes.

Fix: put that key behind a timelock and a multisig before call 6 runs, or move call 6 to a later vote. Until then, the ENS app can limit the risk by removing the migration approval right after each migration.

Update: Rhinestone will make the service unchangeable, with new deployments for any upgrade, in Q4 2026 or Q1 2027. Who holds the key until then is still open.

M02. on.eth would stop working

Severity: Medium. Status: Resolved.

on.eth belongs to the DAO and gives apps the ID of each blockchain, for example base.on.eth for Base. It was missing from the names copied to v2. In our test, base.on.eth stopped working once v2 went live, and after the handover only a new DAO vote could fix it. Some other names are also skipped: about 306 whose text ENS Labs could not read, and names longer than 255 bytes.

Fix: copy on.eth before going live. Publish the list of skipped names and let owners add theirs.

Update: On 27 October, ENS Labs registered on.eth in v2 to the DAO Safe, keeping its original resolver, and base.on.eth still resolves after go-live. The other skipped names could not be carried over, since their text is unknown or longer than 255 bytes, which v2 does not accept. An owner who knows a name’s text can register it again on v2.

M03. The HCA audit link was broken

Severity: Medium. Status: Resolved.

Call 6 turns on HCA accounts. ENS Labs’ audit notes pointed to a Rhinestone audit at a link that no longer works.

Fix: publish the audit that covers the HCA code being deployed.

Update: ENS Labs published Nethermind’s report (NM-0965), which covers the HCA code as deployed, including its latest fix.

L01. Fees went to the timelock instead of the Endowment

Severity: Low. Status: Resolved.

Today, name fees go to the Endowment. In the first v2 deployment they went to the DAO timelock instead, and the destination cannot be changed once deployed.

Fix: send fees to the Endowment, or to an address the DAO can change.

Update: ENS Labs redeployed both contracts, and our test confirms a renewal now pays the Endowment. A way to change the destination later is in progress, together with ETH payments (N01).

L02. The description still named the old resolver for call 1

Severity: Low. Status: Resolved.

Call 1 now sets the new ENSv2Resolver (0x3071AD643cE4Ed8b3D67b289845b45dB82b068A4). The call table in the draft description still showed the old one (0xa6D451C5E283Bdd0a7c193910F55db57512AA7B2), so delegates reading it would see an address that will not be used.

Fix: update the call table in the description to the new address.

Update: The proposal submitted on chain shows the new address.

L03. Code changed after the audits

Severity: Low. Status: Resolved.

The new ENSv2Resolver set by call 1, and the other contracts replaced on 18 October, include fixes merged after the published audits (pull requests #470, #471 and #472). ENS Labs reviewed and approved them, but the published audit reports do not cover them.

Fix: have the auditors review these changes, or publish their sign-off, before the proposal executes.

Update: ENS Labs shared an updated Nethermind report whose final commit, 81869c3, includes pull requests #470, #471 and #472.

L04. Live code not covered by the audits

Severity: Low. Status: Open.

Some contracts now live include code that no published audit report covers:

  • WrapperRegistry, LockedMigrationController and UserRegistry, deployed on 26 and 28 October and already in use, include changes merged after the audited code (pull requests #475, #476, #479, #483, #484 and #487).
  • The 18 October contracts include two ens-contracts changes (#579 and #572) that are outside the report’s scope.

ENS Labs reviewed and approved these changes.

Fix: have the auditors review these changes and update the report.

N01. No ETH payments after the vote

Severity: Note. Status: Acknowledged, will resolve.

After the vote, names can only be paid in USDC or DAI. Users who hold only ETH must swap first, in a separate transaction. Renewal tools that pay in ETH stop working.

Fix: let the ENS app handle the swap, or add ETH support.

Update: ENS Labs plans ETH payments for Q4 2026 or Q1 2027.

What we will check next

  • Done on 27 October: the .eth token reached the DAO Safe, on.eth was registered, ENS Labs’ deployer kept no role, and the Security Council switched lookups to the new Universal Resolver v2 (0x06Fdd07F007ADaC667177b46aB2EB9A75132Cfd5).
  • The follow-up vote ENS Labs plans once v2 has run safely, to remove the .eth roles the DAO does not need.

Sources

3 Likes

We support ENSv2 activation and will be voting for it.

Article IV names this among its permissible actions: “ENS governance should grant control of a top-level domain to its owner in the DNS system on request.”

That puts roughly 2,150 strings in play: 1,165 post-2012 gTLDs today, plus up to 980 more as the 2026 round resolves, browsable at stringscout.

The TLD Oracle explores an optimistic path that enables a Registry Operator to assign their own TLD with a DNSSEC proof checked onchain, inside a review window the DAO can veto in, bypassing the governance song and dance.

ENSv2 activation gives Registry Operators a compelling reason to consider ENS, and ENS Labs has been drawing out the implications:

The approved set of PublicResolver’s is only necessary for locked names with locked resolvers. The issue being addressed is that, the NameWrapper-aware PublicResolver only respects V1 NameWrapper ownership for mutation, and that is exchanged for a V2 token when you migrate. In this rare scenario, the locked PublicResolver is swapped with PublicResolverV2 which is abi-compatible but respects the V2 registry.

Outside of that scenario, any resolver will work.

1 Like