Approaches to Support Setting Primary Names for All Contracts

Exploring New Ideas to Address the Concerns Raised by the Community

By @nick.eth

However, I don’t believe it’s safe in general to allow the deployer to set the primary name on a contract. Often, dedicated or shared deployment accounts are used, and ownership of the contracts is then transferred elsewhere post-deployment - if there’s any ownership at all. Not infrequently, these deployment accounts get compromised, in which case anyone who obtains the leaked credentials would now also be in a position to set an arbitrary primary name for all the contracts the account deployed.


Proposed Solution

To address the concerns raised by the Nick, we’re introducing a tiered permission system for setting a contract’s primary ENS name:

Level 1 - Contract is Ownable/ERC-173

  • If the contract implements Ownable or ERC-173, only the owner() should be allowed to claim the reverseNode.
  • In this case, do not proceed to check the deployer.

Level 2 - Contract Deployed via ReverseClaimable Mechanism

  • If the reverseNode has already been claimed by another account, and the sender is not that account, then reject the attempt to claim the reverse record by the deployer or set a primary name.
  • Do not check further conditions.

Level 3 - Fallback for Non-Ownable Contracts

  • If the contract is neither Ownable/ERC-173 nor has its reverseNode claimed during deployment,
  • Then allow the sender to set the primary name only if they are the original deployer of the contract.

By @raffy

I don’t think it is safe in general for contracts to be claimed by their deployer.

If we can eliminate the risk where the reverse resolution of a contract address doesn’t match its forward resolution, we effectively remove the primary incentive for a scammer to manipulate the contract’s primary name.

I’ll discuss how to mitigate this risk further at the end of the proposed solution.

Currently, only a small fraction of contracts are eligible to set primary names.
If we can increase that eligibility to 80–90% of contracts (for now eliminating contracts deployed thorugh factory contracts), it would be a significant win for both the ENS and broader Ethereum communities.


By @gregskril

To explore further:

  • AA deployers
  • Burner/compromised key deployments

Burner/Compromised Key Deployments

While this is a broader Ethereum issue, if a private key is compromised, there’s no truly safe recovery path, such contracts shouldn’t be considered safe to interact with in the first place.
However, if we can eliminate the risk where reverse resolution does not match forward resolution, then the motivation for a scammer to set or manipulate a primary name disappears.

Account Abstraction (AA) Deployers

Since these contract deployments occur through fixed EntryPoint contracts, we can reliably filter them.
We can enforce a rule that contracts deployed via EntryPoint are not allowed to have their primary name set via the EntryPoint address, thereby preventing misuse.


Revised Solution After Considering the Concerns

We need to understand the motivation of a hacker or scammer for changing the primary name of a contract, whether by gaining access to the deployer’s private key or exploiting permissions.

Legitimate Scenario (Genuine Contract Deployer)

  • Contract: 0x123abc

  • ENS Name: genuine.original.eth
  • Reverse Resolution: 0x123abc
.addr.reverse → genuine.original.eth
  • Forward Resolution: genuine.original.eth → 0x123abc


Attack Scenario (Scammer/Hacker)

  • Contract: 0x123abc

  • ENS Name: fake.scammer.eth
  • Reverse Resolution: 0x123abc
.addr.reverse → fake.scammer.eth
  • Forward Resolution: fake.scammer.eth → 0x456def


This creates a misleading link where reverse and forward resolutions don’t align, enabling scam potential.


If we can eliminate this mismatch, ensuring that reverse and forward resolution always align then we remove the scammer’s motivation to change the primary name in the first place.

Rephrasing in more technical terms - If we disallow setting any name as a contract’s primary name unless it forward-resolves to that contract address, and also prevent any name from changing its forward resolution unless it is set as the reverse resolution of a contract, we can effectively eliminate the scammer’s motivation to manipulate a contract’s primary name.

Take the previous example again:

Genuine Contract Deployer

The legitimate deployer claims the reverse node and sets the primary name for the contract:

  • Contract: 0x123abc

  • ENS Name: genuine.original.eth
  • Reverse Resolution: 0x123abc
.addr.reverse → genuine.original.eth
  • Forward Resolution: genuine.original.eth → 0x123abc


Scammer/Hacker Scenario

A scammer gains the ability to change the primary name of the contract and sets it to their own ENS name:

  • Contract: 0x123abc

  • ENS Name: fake.scammer.eth

They then:

  • Set the forward resolution of fake.scammer.eth to 0x123abc

  • Set the reverse resolution of 0x123abc
.addr.reverse to fake.scammer.eth

Resulting in:

  • Reverse Resolution: 0x123abc
.addr.reverse → fake.scammer.eth
  • Forward Resolution: fake.scammer.eth → 0x123abc


Now, under the proposed constraints, the scammer cannot change the forward resolution of fake.scammer.eth to any other address.

This effectively neutralizes the scam vector, as the ENS name becomes locked to the contract, unless a new name first forward-resolves to the contract and then replaces the old primary name through reverse resolution. This removes the incentive to exploit primary name assignments.


Implementation Plan

To achieve this, we need to create a new ContractResolver and make some changes to the ReverseRegistrar.

Changes in ReverseRegistrar

  • Only allow a custom ContractResolver to be used as the resolver address when setting names via claimForAddr and claimWithResolver.
  • Update the authorised modifier to include the deployer of the contract can also claim reverseNode.

ContractResolver — Updates to NameResolver Logic

  • Check that the name forward-resolves to the contract address using the addr() function from AddrResolver.

ContractResolver — Updates to AddrResolver Logic

  • Ensure the name/node is also set as a reverse record by checking the name() function from NameResolver.

The Enscribe team is keen and already working to address issues with smart contract naming. We believe that with the Namechain release and support for L2 primary names, if we can implement changes to allow all contracts to have a primary name, it would be a win for both us and the ENS community.

2 Likes