[Executable] Enable L2 Reverse Registrars and new .eth registrar controller

Abstract

This proposal enables five chain-specific reverse resolvers for L2 EVM networks, and one default reverse resolver as a fallback mechanism. The five chains are Arbitrum, Base, Linea, OP Mainnet and Scroll.

This proposal also enables a new .eth registrar controller and sets the reverse record of some currently un-named ENS contracts.

Motivation

The current implementation of reverse resolution is limited to Ethereum Mainnet and assumes that every entity (a generic smart contract or user account) has the same address across every EVM chain. This has been falling out of line with reality given the rise in smart contract accounts, indicating that reverse resolution should be resolved via a namespace for each chain, rather than a single reverse namespace for the Ethereum ecosystem at large.

This functionality defined formally in ENSIP-19, combined with ENSIP-11, enables “L2 Primary Names,” meaning developers can build end-to-end ENS experiences without forcing their users to transact on Ethereum Mainnet.

To support optionally setting the default reverse record at registration time, a new .eth registrar controller must also be enabled. Since new controllers have significant overhead, we are also taking advantage of this opportunity to add a referrer field for registrations and renewals. This field is emitted unchanged from the registration and renewal events and allows clients to convey information about the source of a registration or renewal for potential DAO-based referral reward schemes (not defined in this proposal).

Specification

  1. Call setResolver on the ENS registry (registry.ens.eth ) for reverse with the address of the new default reverse resolver (0xA7d635c8de9a58a228AA69353a1699C7Cc240DCF)

  2. Call setSubnodeRecord on the ENS registry (registry.ens.eth) for each of the following names, derived via [coinTypeAsHex].reverse as specified in ENSIP-19:

    Reverse Namespace Name Owner Resolver
    Arbitrum 8000a4b1.reverse wallet.ensdao.eth 0x4b9572C03AAa8b0Efa4B4b0F0cc0f0992bEDB898
    Base 80002105.reverse wallet.ensdao.eth 0xc800DBc8ff9796E58EfBa2d7b35028DdD1997E5e
    Linea 8000e708.reverse wallet.ensdao.eth 0x0Ce08a41bdb10420FB5Cac7Da8CA508EA313aeF8
    Optimism 8000000a.reverse wallet.ensdao.eth 0xF9Edb1A21867aC11b023CE34Abad916D29aBF107
    Scroll 80082750.reverse wallet.ensdao.eth 0xd38bf7c18c25AC1b4ce2CC077cbC35b2B97f01e7
  3. Call addController on registrar.ens.eth with the address of the new .eth registrar controller (0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547)

  4. Call setController on reverse.ens.eth with the address of the new .eth registrar controller

  5. Call setController on the new default reverse registrar (0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9) with the address of the new .eth registrar controller

  6. Call setInterface on the .eth resolver (0x30200E0cb040F38E474E53EF437c95A1bE723b2B) with the address of the new .eth registrar controller, and the interface ID it implements (0xe4f37f79)

  7. Call setDefaultResolver on reverse.ens.eth with the address of the new public resolver (0xF29100983E058B709F3D539b0c765937B804AC15)

  8. Call setNameForAddr on reverse.ens.eth for each of the following addresses:

    Address Name
    0x0fc3152971714E5ed7723FAFa650F86A4BaF30C5 dnssec.ens.eth
    0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85 registrar.ens.eth
    0xaB528d626EC275E3faD363fF1393A41F581c5897 root.ens.eth
    0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547 controller.ens.eth
    0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9 default.reverse.ens.eth
8 Likes

:clap: Thanks for this Jeff. That’s a clean explanation.
Good to see cross chain reverse resolution seeing the light of day.

I’ve spent a couple of hours on this. High level, no code deep dive.

Four main thoughts:

  • Has the new code been audited? Lots of moving parts here.
  • Can you share insight on the execution of productionized gateways with dRPC?
  • Calldata and Tenderly traces for this would be great, although I appreciate that there have been lots of discussions about governance interfaces supporting this through Drafting process.
  • The naming for contract discovery is a little confusing. The reverse resolver names e.g. 8000a4b1.reverse.ens.eth are subnames of reverse but reverse.ens.eth points to the default reverse registrar.

Some random commentary, and additional info for other readers…

Additional info: Namehash/Node for reverse.ens.eth => 0xc80bb329ad070734e9c503151c00f639f8a6acae8c9e76c730d272547417ce2f
Source

8000a4b1 => 2147525809
80002105 => 2147492101
8000e708 => 2147542792
8000000a => 2147483658
80082750 => 2148018000

These match with a historical source of truth, and my own calculations.

I noticed that the resolvers utilise dRPC gateways and fallback to gateways running on 3668.io. If I recall correctly, this is one of @nick.eth names? I’ve encountered sporadic failures pinging these gateways.

Ownership transferred to DAO Wallet here. :+1:

Comment/curiosity: Is there a plan to ever deprecate old registrar controllers at any point?

:+1:

Additional info: This means that when you register a name you can set the default reverse resolution.

Interface ID validated here.

I assume we that we pass the eth node like in previous transactions e.g. this one.

Query: That said, is this discovery mechanism used?

Looking at IInterfaceResolver here, and the function comment this seems like a really weird and convoluted mechanism.

:+1:


As mentioned, have not done a deep dive into the code but I did notice that the following NatSpec docs are inaccurate.

    /// @notice Registers a name.
    ///
    /// @param registration The registration to register.
    /// @param registration.label The label of the name.
    /// @param registration.owner The owner of the name.
    /// @param registration.duration The duration of the registration.
    /// @param registration.resolver The resolver for the name.
    /// @param registration.data The data for the name.
    /// @param registration.reverseRecord Which reverse record(s) to set.
    /// @param registration.referrer The referrer of the registration.
    function register(
        Registration calldata registration
    ) public payable override {
5 Likes

About time!

Going forward, the DAO can activate new L2s by following this pattern:

[coinType].reverse.ens.eth
➝ mapped to resolver on L1
➝ offchain gateway
➝ queries coinType’s L2
➝ returns reverse name

This implementation is clean and sets a strong precedent by:

  • Forward-deploying a fallback resolver for emergent namespaces and future reverse resolution support
  • Opening a new vector for revenue through referral data emitted by the new .eth controller
  • One-shotting reverse record setup during .eth registration — a big UX win

Brilliant.

1 Like

HYPE! So excited to see this spec on the verge of launch.

@jefflau.eth Two thoughts:

  1. I think that this edit to ENSIP-11 should be formalized before this spec formally lands: Add "default" chain id 0 to ENSIP-11 by stevieraykatz · Pull Request #32 · ensdomains/ensips · GitHub. Unless I’m missing something, I think that it just needs to be merged at this point. It should drastically improve the UX for EOAs and counterfactual contracts leveraging this spec.
  2. Do we have the address of the L2ReverseRegistrars that will be deployed on each of the respective chains yet? Or will those be described/deployed in a followup post?

The Basenames squad has been hard at work getting ready for compliance and we’re working through the last couple snags ensuring that we can formally comply with ENSIP-19 and migrate without any user/integrator downtime. More details to come from our end as we figure out the complete end-to-end picture and timing.

2 Likes

Since I was able to get my hands on ENSIP-19, I added these changes to the ENSIP-19 refactor as that was where I originally thought they should go. Instead of editing ENSIP-11, I was thinking of adding you as a contributor to ENSIP-19.

ENSIP-19 mentions:

  • default EVM chain and chainId = 0
  • default primary name
  • algorithm for coinTypechainId
  • includes the coinType / chainId / EVM table
4 Likes

Sounds like the PR I linked isn’t necessary then! Cheers, appreciate the contributor ack :pray: .

2 Likes

From our perspective:

  • L2 reverse registrars are straightforward and isolated; a vuln in one can’t affect anything other than correct reverse resolution for names on that L2. The’re upgradeable so a vulnerability could be fixed quickly and easily.
  • Registrar controller changes are likewise limited in scope; any modification to the reverse records is checked and limited to msg.sender, so we believe the scope for new issues here is also very limited.

As a result we don’t feel an audit is necessary for these changes.

2 Likes