NameWrapper updates (including testnet deployment addresses)

Ahh got it, thanks! I didn’t realize that the current ETHRegistrarController would remain as a controller for the registrar (that’s what you mean right?). I know that the registrar has a removeController method, and so that would not be performed as a part of the on-chain DAO proposal for these new contracts.

I was going off of what Jeff said in the first post, so that’s where I was confused:

Anyway I think that resolves my concerns then, thanks! Basically the NameWrapper will just not support really long labels, and I think that’s fine. Or at least I can’t think of any problem with that.


Just thinking out loud though, wouldn’t it be better for future maintainability if the new ETHRegistrarController was made a controller for the registrar as well, and then it could have an alternate method (or flag parameter) to register unwrapped names directly?

Otherwise now we’ll have two registrar controllers to maintain. So if we want to change the price oracle we’ll need to do it on both. And if we want to make more complex price structure changes that requires code changes for the registrar controller, then we’ll need to make changes to both contracts, deploy both, and replace both as controllers on the .eth registrar.

Will my name be able to be wrapped?🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇.eth/details

Nope, that label is 400 bytes I believe


Yes this is true for the new .eth registrar controller contract, and also for the new app. Legacy names could be continued to be registered on the old registrar controller contract until the DAO decides to remove it as a controller. We expect to have this contract on there for several months to ensure the stability of the NameWrapper


If the old registrar controller was ever removed, then people would have no way to register .eth names directly anymore, everyone would be forced through the NameWrapper.

Could the new registrar controller have a boolean flag (or alternative function) to register without wrapping?

As it stands we know one limitation already with the NameWrapper: no label greater than 255 bytes will be allowed. So if the old controller was ever removed, that would now effectively be a new contract-level restriction on .eth registrations.


I can’t see us disabling the old controller any time soon; as long as the pricing is the same and there are no known vulnerabilities, I don’t think there’s a compelling reason to disable it.


Hi all,

Myself and @nick.eth have been hard at working fixing the issue that @lcfr.eth initially reported, and also another issue that @Premm.eth reported. For transparency, Premm was also rewarded a bounty similar to the one lcfr.eth received. Thanks Premm!

In the mean time we found things we could optimise and improve on in the NameWrapper. After much discussion, we have decided to proceed with another audit. This will be the 3rd official audit on the NameWrapper in over 2 years. Whilst this wouldn’t be our ideal situation, each time we have found bugs in the NameWrapper we’ve actually found ways to make it more useful and elegant with more features. However with more features comes increased complexity, and the risk is always increased so we’ve decided to go for a private audit with Code4rena starting 22 November.

Despite the setback, I hope the increased transparency shows we’re dedicated to getting this out and we’re definitely not intentionally dragging our feet.


The new NameWrapper docs are live here: ens-contracts/ at master · ensdomains/ens-contracts · GitHub

If anyone has any feedback/questions on the docs, please feel free to contact me. I will work on a less technical in the future about how parent-controlled fuses have implications on NameWrapper usecases as well once things have settled a bit.


I’ve got some notes on the current NameWrapper readme:


Names start out in the unregistered state before they are registered, and return to it after they expire.

To check if a name is Unregistered, verify that NameWrapper.ownerOf returns address(0) and so does Registry.owner .

When an Emancipated/Locked name expires, NameWrapper.ownerOf will return address(0). However the Registry.owner will not return address(0), it will still return the address of the NameWrapper contract. That doc says that names will “return to the Unregistered state after they expire”, but I think that is not necessarily true, at least not how it is defined here.

Maybe it should say like: “To check if a name is Unregistered, verify that NameWrapper.ownerOf returns address(0) and Registry.owner returns either address(0) or the address of the NameWrapper.”

And then for Unwrapped: “To check if a name is Unwrapped, verify that NameWrapper.ownerOf returns address(0) and Registry.owner returns any address except for address(0) or the address of the NameWrapper.”


Wrapped names do not expire…


Expiry is only applicable to names in the Emancipated and Locked states.

Expiry can still be extended even if a name is in the Wrapped state, but does not have any practical effect on the name.

Unless I’m mistaken, a name can be merely Wrapped, and the parent can burn parent-controlled fuses on the name, along with some expiry. So the expiry may still be applicable to Wrapped names.

If the name is Emancipated or Locked, the following changes happen:

  • The NameWrapper returns address(0) as the name owner from ownerOf() or getData() if the name is expired.
  • The NameWrapper treats all fuses as unset and returns uint32(0) from getData() for fuses if the name is expired.

The first bulletpoint there is true. However the second bulletpoint applies to merely Wrapped names too. If parent-controlled fuses were burned, then the expiry will cause those to reset.


Good point, thank you. Would you mind sending a PR to correct this?

It can, but the expiry has no effect unless CANNOT_UNWRAP is burned.

Good point.

1 Like

Will do!

How so?

The expiry can be set on a Wrapped (but not Emancipated) child name along with any custom parent-controlled fuses (“perks”). This allows the parent to burn a “perk” fuse for a limited amount of time. When the expiry is reached, the fuses reset, but the name itself is otherwise unaffected (unlike for Emancipated/Locked names).

I don’t see any place where CANNOT_UNWRAP precludes the expiry from affecting a merely Wrapped (but not Emancipated) name, unless I missed something.

Also the expiry affects merely Emancipated names too, and those do not have CANNOT_UNWRAP burned either.

1 Like

True. I could be mistaken, however, but when a wrapped name expires, only the parent-controlled fuses expire; the name itself remains.

1 Like

Yep that is all true. The “owner = null address” thing only happens for Emancipated/Locked names.

And a merely Wrapped name can only ever have parent-controlled fuses burned anyway, so the expiry will only ever affect PCFs in that case.

I think we’re on the same page! Maybe just semantics around what “affects” means. For a Wrapped (but not Emancipated) name, the expiry only affects fuses, but does not affect the name itself in any other way.


Small update: Created PR here.

You’re right. Expiry should make parent-controlled fuses expire too, which can be burnt without CANNOT_UNWRAP being burnt on the child. I think Nick is thinking of owner-controlled fuses


Mitigations for all the Name Wrapper audit issues found have been written and will be in a mitigations review with the auditors today, which will end next week.


Where is the most up to date contract code for Namewrapper in Github?

I thought it would be the or-fuses-setsubnode or main branch, but the code doesn’t match what is currently deployed in Goerli.

In Goerli contracts PARENT_CANNOT_CONTROL fuse is 64, but in the docs and github PARENT_CANNOT_CONTROL is 65536

Also some of the method signatures on NameWrapper contract are different. For example, expiry parameter is missing from wrapETH2LD function.

The latest code can always be found at

Testnets have not yet been updated with the latest changes.



Is there any plans to deploy back to the testnets?