NameWrapper updates (including testnet deployment addresses)

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: https://goerli.etherscan.io/address/0xEe1F756aCde7E81B2D8cC6aB3c8A1E2cE6db0F39#code, 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

24 Likes