Skip to main content
The NameWrapper wraps ENS names, adding new functionality to them:
  • Makes all ENS names at any level into ERC1155 tokens.
  • Supports ‘emancipating’ names by allowing the owner of a parent name to revoke control over subdomains.
  • Supports ‘locking’ names by allowing the owner of a name to revoke control over changes in resolver, creation of subdomains, and other parameters.
  • Wrapped names can expire; a name that is emancipated or locked has a built in expiration at which the name (and that status) expires.
  • UIs and Smart Contracts can check the status of a name with a single function call, allowing them to ensure security guarantees are upheld.
  • .eth names can be registered and renewed via the wrapper, removing any need to wrap names separately after registration.
  • Owners of names can create wrapped subdomains directly, without having to register-then-wrap.

Glossary of Terms

Wrap

Transfers ownership of the ENS name to the Name Wrapper. The wrapper then issues an ERC1155 token for the name.

Unwrap

Reverses the wrap process and transfers the name to an address of the token owner’s choice.

Fuse

The term for a flag that can be set irreversibly until expiry. Fuses can do many things, including controlling permissions for the name itself.

Emancipation

The process of the owner of a parent name revoking its control over a subname.

Locking

The process of the owner of a name revoking some level of control over its own name.

Owner-controlled Fuses

Fuses that can be burned by the owner of a name or the owner of the parent name if the name is not emancipated.

Parent-controlled Fuses

Fuses that can be burned by the owner of the parent name.

Expiry

Expiry is the date when the name expires and is no longer able to be owned. Expiry only comes into effect when a name is emancipated or locked. Expiry can be extended by parent or approved addresses, and if the parent burnt the parent controlled fuses (PCF), then the subnames can extend their expiry by themselves. However, the PCF can be unburnt later if the parent name expires.
For the latest updates on expiry behavior, refer to the ENS discussion forum.

Checking if a Name is Wrapped

To check if a name has been wrapped, call isWrapped(). This checks that the owner in the NameWrapper is non-zero.
If you transfer your subdomain to the NameWrapper using registry.setSubnodeOwner(), registry.setSubnodeRecord() or registry.setOwner(), the NameWrapper will NOT recognize this as a wrap. There will be no NameWrapped event emitted, and there won’t be an ERC1155 minted for that specific name.For this reason, if you want to check whether or not a name has been wrapped, you must check if the owner in the registry is the NameWrapper AND the owner in the NameWrapper is non-zero.

Registering Wrapped Names

Names can be registered as normal using the current .eth registrar controller. However, the new .eth registrar controller will be a controller on the NameWrapper, and the NameWrapper will be a controller on the .eth base registrar. The NameWrapper exposes a registerAndWrapETH2LD() function that can be called by the new .eth registrar to directly register wrapped names. This new function removes the need to first transfer the owner to the contract itself before transferring it to the final owner, which saves gas. Both .eth registrar controllers will be active during a deprecation period, giving time for front-end clients to switch their code to point at the new and improved .eth registrar controller.

Ownership of the NameWrapper

The NameWrapper is an Ownable() contract and this owner has a few limited admin functions. Most of the functionality of the NameWrapper is trustless and names cannot be interfered with in any way even by the owner of the contract.

The contract owner can:

  • Change the metadata service URL.
  • Add and remove controllers to the NameWrapper.
  • Specify an upgrade target for a new name wrapper instance.

Controllers can call:

  • registerAndWrapETH2LD()
  • renew()
  • setUpgradeContract()

Upgrading the Name Wrapper

The Name Wrapper has a built-in upgrade function that allows the owner of the Name Wrapper to set a new contract for all names to be migrated to as a last resort migration. Upgrading a name is optional and is only able to be done by the owner of the name in the original NameWrapper. A name can only be migrated when the parent has been migrated to the new registrar. By default the ROOT_NODE and ETH_NODE should be wrapped in the constructor of the new Name Wrapper. The upgraded namewrapper must include the interface INameWrapperUpgrade.sol, which mandates two functions that already exist in the new wrapper: wrapETH2LD and setSubnodeRecord. The wrapETH2LD function can be used as-is, however the setSubnodeRecord needs one additional permission, which checks for if the parent of the name you are wrapping has already been wrapped and the msg.sender is the old wrapper.
// Example of that check in solidity
require(isTokenOwnerOrApproved(parentNode) || msg.sender == oldWrapperAddress && registrar.ownerOf(parentLabelHash) == address(this))
It is recommended to have this check after the normal checks, so normal usage in the new wrapper does not cost any additional gas (unless the require actually reverts).
If the function signature of the new NameWrapper changes, there must be an extra function added to the new NameWrapper, that takes the old function signature of wrap() and wrapETH2LD() and then translates them into the new function signatures to avoid a situation where the old NameWrapper cannot call the new NameWrapper.

Build docs developers (and LLMs) love