NameWrapper updates (including testnet deployment addresses)

Any idea when?

Last update from @jefflau.eth was in the Q4 Town Hall on December 15th.

If no further issues are discovered from the latest bug mitigation audit, they would like to deploy to testnet in January for further analysis.


Thanks for the update.

So it might be sometime in the next four weeks, but might be longer… I’ll keep my eye out.

1 Like

Happy new year everyone!

I’m happy to announce we’ve deployed the re-audited NameWrapper back on to Goerli. I’ve updated the addresses above and I’d like to leave it up for a minimum of 2 weeks before we think about deploying to mainnet. We’d really appreciate anyone working on NameWrapper integrations to take a look at the code and play around on Goerli. The master branch of ens-contracts is now up to date with post audit code and you can also take a look at etherscan on Goerli e.g:, which has all of the contracts verified with their solidity code.

The following are the main changes made following the audit:

Being more explicit about the states of subnames

Subnames have fuses that protect them from being replaced. However there was no restriction on unwrapping the name as a subname owner (which is expected since CANNOT_UNWRAP would not have been burnt). This meant that owners of subnames could unwrap and self inflict a situation where a parent could now replace their subname as the name would not have an owner in the NameWrapper any longer. This one of two bugs found by auditors to fine-tune the states of subnames.

Being more explicit about what a wrapped name is

One of the biggest takeaways from the latest audit was being stricter on what constitutes a name being wrapped or not. Previously we were relying on if the NameWrapper contract was the owner in the registry, which gives the NameWrapper enough power to make changes within ENS. However this did not take into account other situations, such as if the name was re-registered on the old controller. This meant the original ERC721 token could be taken over, which then has the power to take back the owner on the registry, unwrapping the name in the process. This meant we needed to take this into account when doing key actions such as burning the fuses of a subname (since these could be undone by unwrapping the parent name).

.eth expiry

We’ve also adjusted the way that .eth expiry works within the wrapper. Originally we had the wrapper expiry always derive .eth name expiry from the .eth registrar. This had some consequences when re-registering a name that was previously wrapped, and then re-registered using the old controller. It meant you could set a trap where a name was seemingly wrapped, but the name could actually be taken back over since the .eth ERC721 was now not owned by the NameWrapper (using the reclaim function on the .eth registrar). To mitigate this we have changed expiry for .eth names in the wrapper to sync when wrapping or renewing. This means that registering on the old controller (which we will keep running indefinitely), will not extend expiry in the wrapper, and the .eth wrapper expiry will remain the same. This means that the name within the wrapper will be considered unwrapped and cannot function again until they call wrapETH2LD() again. This means using the old controller does not create any state inconsistencies and we can safely keep both controllers for as long as required.

Allowing forever subnames

Previously to this, the subname has weaker guarantees to be able to renew their name indefinitely. The parent name had to be renewed for a very long time and the subname had to be registered/renewed/bought for a long period or the parent could remove the registration/renewal contract disallowing further extension.

Thanks to @serenae we’ve also added support for a parent to allow a child to extend expiry. This gives an easy way for a name to have a very strong guarantee for a “forever” subname. The way it works is the parent can now burn a parent controlled fuse (PCF) to enable this functionality. This fuse as any fuse cannot be unburned (unless expired), which means the parent itself would have to expire to unburn this fuse. The parent is incentivised to renew their name if they are selling subnames (and if it’s a .eth name the name can technically be renewed by anyone).

Keep in mind this does not allow forever rentable subnames, however this functionality can still be enabled by moving the ownership of the name to a contract (similar to how the .eth registrar works).

These are the main outward facing changes, but there were also others that are not mentioned above. If you’re trying to implement something using the NameWrapper and these changes don’t make sense, please don’t hesitate to reach out to me.

Edit: Made the .eth expiry explanation more clear


exciting update jeff! thanks for all the hard work!


Great update… Thank you.



As seeing some updates on the NameWrapper contract, I can’t help thinking if there were some similar situations of esf contract that should be updated?

1 Like

esf contracts aren’t even remotely based on namewrapper contracts at all. I wrote them fully from scratch.

Also, the main parts of the contract are not upgradable so they can be fully trusted.

1 Like

Congrats!! :rocket::dizzy:

Hi all. I have questions about availability of 3LD subdomain wrapping using this Namewrapper contract. These are what I want to do:

  • I am owner of 2LD subdomain was not wrapped. (ex: sub.eth)
  • I want to wrap few more 3LD subdomains with my subdomain. (ex: abc.sub.eth, def.sub.eth…)

Is it possible to wrap 3LD now? If yes, what would be the prerequisites for this?

(Let me know if this thread is not appropriate one for this topic.)

1 Like

The latest updates are now on the Goerli testnet, please see Jeff’s post above!

Yes, you can wrap 3LDs on the Goerli testnet. There is no UI for this yet, so if you want to test it out you can go to Etherscan and call the methods directly.

If it’s a .eth 2LD, then you need to setApprovalForAll on the registrar for the NameWrapper contract, then wrap using the wrapETH2LD method. Or you can just send the ERC-721 NFT to the NameWrapper contract directly. You need to be the current Owner (Registrant) in the .eth registrar.

If it’s not a .eth 2LD, then you need to setApprovalForAll on the registry for the NameWrapper contract, then wrap using the wrap method. You need to be the current Manager (Controller) of the name in the registry.


Hey @jefflau.eth, found a potential issue.

Before, the getData method would always get the expiry directly from the registrar for .eth 2LDs.

However it looks like that’s been removed. Instead, the expiry is being set in _wrapETH2LD and then explicitly updated in renew (if it’s wrapped).

This means that if you wrap a .eth 2LD and then renew the name through the old ETHRegistrarController, the expiry returned from NameWrapper.getData will now be incorrect.

Hey Serenae,

This is actually expected behaviour now. The reason is to not let the old controller auto-renew names on the wrapper when they ‘takeover’ the name as the old controller will set the ERC721 name ownership to the msg.sender, when it should be the NameWrapper (if you were to consider the name wrapped). It’s at the bottom of this part of the readme:

I’ll update the post above so it’s more explicit as I didn’t explain it the best!


Interesting, okay then! Glad that was already taken into consideration :+1:

Also, I just didn’t read closely enough.

1 Like

No worries, this is what the public testnet bug bash is about! I’ll think about how I can make the documentation more clear as well.

Thank you. Is also updated as there was previously a bug around burnings fuses on a sub domain (an error occurs)?

Not up to date yet. We’re working on it at the moment

1 Like

Will goerli subgraph also be updated to reference the new contract?

the goerli subgraph has been updated


Thank you @serenae so I tried to set me as a manager in registry ( contract address : 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e), but it gives ‘caller should be the owner’ error.

Do I have to my own registry?