# ENS Documentation
import { Button } from '../components/ui/Button'
## 🪲 Bug Bounty Program
The ENS bug bounty program rewards anyone who finds a bug in covered ENS smart contracts and ENS Labs assets. This page provides a brief overview of the program which is operated by Immunefi and ENS Labs.
[See the full program](https://immunefi.com/bug-bounty/ens)
### Bounties 💸
Reward sizes are guided by the rules below, but are in the end, determined at the sole discretion of the ENS Labs team.
#### Smart Contracts
* **Critical**: up to $250,000 USD
* **High**: up to $150,000 USD
* **Medium**: up to $100,000 USD
#### Websites and Applications
* **Critical**: up to $50,000 USD
* **High**: up to $20,000 USD
* **Medium**: up to $5,000 USD
* **Low**: up to $1,000 USD
The ENS Labs team reserves the right to adjust bounty amounts at any time in the future.
## 📝 Changelog
This page contains a list of changes and events that happened to the ENS protocol & ecosystem.
### Dentity Announcement
On August 21st, 2024 the ENS Labs team announced a new integration with Dentity, an independent identity provider that allows users to verify information and share it on their ENS profile.0
This integration leverages a draft ENSIP that allows for W3C Verifiable Credentials to be stored inside ENS profiles.
### ENSv2 Announcement
On March 28th, 2024 the ENS Labs team announced our plans and roadmap for scaling ENS to the entire internet and beyond.
This involves migrating .eth registrations to a brand new system, in addition to improving support for existing L2 solutions.
You can read more [on our blog](https://blog.ens.domains/post/ensv2), [on X](https://twitter.com/ensdomains/status/1795440186513576318), and [the forums](https://discuss.ens.domains/t/technical-feedback-thread-for-ensv2/19233).
## FAQ
### Which wallets and dApps support ENS?
ENS is supported by a wide range of wallets and dApps, some notable ones can be found on the [integrations page](https://ens.domains/).
This page is currently under construction however a link to add yourself will be put here soon.
### Can I hold my name with one address, and point it at the other?
Yes, you can hold your name with one address and point it at another.
Simply visit the [ENS Manager App](https://ens.app/) and update the appropriate address record (by chain) for your name to point to the address you wish.
### Once I own a name, can I create my own subdomains?
Yes. You can create whatever subdomains you wish and assign ownership of them to other people if you desire. You can even set up your own registrar for your domain.
Some resolvers might provide even more advanced features, read more [about Resolvers](/resolvers/quickstart).
### Can I change the address my name points to after I've bought it?
Yes, you can update the addresses and other resources pointed to by your name at any time.
To update your name checkout the [ENS Manager App](https://ens.app/).
### ETH Registration
#### Why are names registered as hashes?
Hashes provide a fixed length identifier that can easily be passed around between contracts with fixed overhead and no issues passing around variable-length strings.
Read more about [labelhash, namehash, and encodings](/resolution/names).
#### What characters are supported?
ENS names are generally encoded using UTS-46.
This means there is partial support for Unicode characters, including emoji.
However technically possible to register any name, names that are not valid UTS-46 will not be resolvable by most resolvers.
Therefore it is generally recommended for apps that implement registration to limit the characters that can be registered to ensure a smooth experience.
To read more about supported characters [name normalization](/resolution/names).
#### What does it cost to register a .eth domain?
Currently, registration costs are set at the following prices:
* 5+ character .eth names: $5 in ETH per year.
* 4 character .eth names: $160 in ETH per year.
* 3 character .eth names: $640 in ETH per year.
3 and 4 character names have higher pricing to reflect the small number of these names available.
To read more about the pricing structure of .eth names [read more about pricing](/registry/eth)
#### How long can I register a name for?
You can register a name for as long as you would like.
There is no maximum registration duration.
#### What happens if I forget to renew my name?
If you forget to renew your name, it will be released back to the public pool of available names.
Luckily the expiration process has a 90 day grace period.
This means that once the name expires the original owner has 90 days to renew the name before it is released.
After the grace period, the name is released for registration by anyone with a temporary premium which decreases over a 21 days period.
The released name continues to resolve your ETH address until the new owner overwrites it.
#### In what way could I lose access to my name?
The .eth registrar is built to ensure once issued, a name cannot be revoked or taken away from its owner.
Potential loss can occur if the owner loses access to their private key, or if the owner forgets to renew their name.
### Root Registry
#### Who owns the ENS rootnode? What powers does it grant them?
The ENS rootnode is currently owned by the ENS DAO. It used to be owned by the ENS Multi-sig, a group of keyholders from different parts of the ecosystem, however as of [EP4.10](/dao/proposals/4.10) the ownership has been transferred to the ENS DAO.
Ownership of the rootnode grants the ability to do the following:
* Control allocation and replacement of TLDs other than .eth - this is required to implement DNSSEC integration.
* Enable and disable controllers for the .eth registrar, which affect registration and renewal policies for .eth names.
* Update the pricing for .eth names.
* Receive and manage registration revenue.
#### Can I register a TLD of my own within ENS?
Yes and No, We consider ENS to be part of the 'global namespace' in co-existence with DNS, and it is our priority to not pollute the namespace.
ENS-specific TLDs are restricted to only '.eth' on Ethereum Mainnet, or .eth and .test on testnets.
By default ENS allows users to [import their DNS name](/learn/dns) through the use of the [DNS Registrar](/registry/dns).
Existing DNS TLDs can [reach out to us](mailto\:info@ens.domains) to take control of their TLD.
### What are the differences between ENS and other naming services such as Namecoin or Handshake?
ENS complements and extends the usefulness of DNS with decentralised, trustworthy name resolution for web3 resources such as blockchain addresses and distributed content, while Namecoin and Handshake are efforts to replace all or part of DNS with a blockchain-based alternative.
### Governance Token
#### Can I recover tokens accidentally sent to the wrong address?
The answer depends on the address the token was sent to. If you accidentally sent the token to the token.ensdao.eth address (0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72) or the wallet.ensdao.eth address (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7) then the tokens might be recoverable. Contact the [Meta-governance working group](/dao/stewards/) at the [ENS Forum](https://discuss.ens.domains) and explain the situation. Tokens can only be sent back to the address they were sent from, so if it was sent from an exchange, contact your exchange support to make sure the address can receive tokens.
If the tokens were sent to the null address (0x000..) or an address with a typo, then the tokens are unrecoverable and there's nothing that anyone can do. If the tokens were sent to an exchange or a third party, then contact that third party for help.
import { EmbedLink } from '../components/EmbedLink'
## Terminology
This page contains a glossary of terms used in the ENS documentation.
### Name
An ENS identifier such as 'alice.eth'. Names may consist of multiple parts, called labels, separated by dots. This also includes DNS names like `name.xyz`, or subnames like `sub.name.eth`.
### 2LD
Second-level domain.
This refers to a subname/subdomain of a top-level domain.
For example, `name.eth` and `name.com` are both second-level names.
A subname of a 2LD is a third-level domain or 3LD.
### Subname / Subdomain
A child name like `sub.name.eth`, whose parent is `name.eth`. Also referred to as a "subdomain". Every name (except for the root node) has a parent. For example, `name.eth` is a subname of `eth`.
```
sub.name.eth
```
### TLD
Top-level domain. This refers to names like `eth`, `com`, `xyz` which lie at the "top" of the naming hierarchy.
```
.eth .com .xyz
```
### Manager
The account that may edit the records of a name. The Manager may be changed by the Owner.
### Label
An individual component of a name, such as 'alice'.
### Labelhash
The keccak256 hash of an individual label.
### Namehash
The algorithm used to process an ENS name and return a cryptographic hash uniquely identifying that name. Namehash takes a name as input and produces a *node*.
### Node
A cryptographic hash uniquely identifying a name.
### Owner
The owner of a name is the entity referenced in the ENS registry's owner field. An owner may transfer ownership, set a resolver, and create or reassign subdomains.
### Record
A piece of information that an ENS name "resolves" to (points to). The most common record is the ETH Address record, which determines what ETH 0x address an ENS name points to.
### Registration
A registration is a registrar's record of a user's ownership of a name. This is distinct from the owner field in the Registry; registrations are maintained in the registrar contract and additionally store information on expiry date, fees paid, etc.
#### Registrar
A registrar is a contract responsible for allocating subdomains. Registrars can be configured at any level of ENS, and are pointed to by the owner field of the registry.
#### Registry
The core contract of ENS, the registry maintains a mapping from domain name (at any level - x, y.x, z.y.x etc) to owner, resolver, and time-to-live. All lookups start with the Registry.
#### Expiry
The date and time at which an ENS name expires.
The implications of expiration depend on the type of name it is.
When a .eth 2LD expires (and its grace period elapses), then you lose ownership of the name.
When a wrapped subname expires, you may or may not lose ownership, depending on whether the name was emancipated.
#### Grace Period
This is a short window of time after an ENS .eth name expires, in which the owner can still renew and retain the name. Currently this window is 90 days.
#### TTL
Stands for "Time To Live". This is a field in the core registry that can be set alongside the resolver. It can be used as a hint for clients to decide how long to cache resolved data.
### DNS
This is the Domain Name Service used by the internet to resolve addresses and other records from human-readable names. ENS aims to be fully complementary and compatible with DNS, and supports easy importing of DNS names via a special [DNSSEC](#dnssec) registrar.
#### DNSSEC
Stands for Domain Name System Security Extensions. When a particular DNS TLD supports DNSSEC, then the owners of names can cryptographically sign records. This allows ENS to support easy importing of DNS names into the ENS registry, as the owner of the DNS name can prove ownership with those signed records.
### Resolver
A resolver is a contract that maps from name to the resource (e.g., cryptocurrency addresses, content hash, etc). Resolvers are pointed to by the resolver field of the registry.
#### Wildcard Resolver
This refers to a resolver that supports [ENSIP-10](/ensip/10). This scheme allows clients to resolve data for subnames that either don't have a resolver of their own, or subnames that may not even exist onchain at all. For offchain names, this is typically used in conjunction with [CCIP Read](#ccip-read).
### Public Resolver
This is a standard resolver contract implementation written by ENS Labs. It supports all record types and anyone can use it. This is the default resolver used when registering a new name via the official manager app.
### Offchain
This term is typically used with respect to the Ethereum Mainnet blockchain. If data is not posted to the chain via an actual Ethereum Mainnet transaction, then it is "offchain". ENS names can also be offchain. For example names can use a special resolver to resolve records for subnames that don't exist onchain in the Registry. This is also typically done with [CCIP Read](#ccip-read).
#### CCIP Read
The "Cross Chain Interoperability Protocol Read" specification, also known as [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668), authored by Nick Johnson, is a specification that allows for secure and trustless offchain data retrieval.
It allows for an Ethereum call to defer to an [offchain gateway](/resolvers/ccip-read#writing-a-gateway) and then securely verify the resulting data onchain.
With respect to ENS, this is typically used for offchain subnames that don't exist in the core Registry.
### Primary Name
The ENS name that you want a particular ETH account to be associated with. When set, it will be displayed instead of your 0x address on integrating websites/apps. This is also often referred to as the "reverse record".
#### Reverse Node
A node in the Registry that can be claimed for any Ethereum account. The name this node represents is `[addr].addr.reverse`, where `[addr]` is the Ethereum public address (lowercase, without the "0x"). These reverse nodes are typically used to set a [Primary Name](#primary-name) for an account.
#### Reverse Record
Usually, this is referring to the [Primary Name](#primary-name). Technically speaking, a [Reverse Node](#reverse-node) can have multiple records set on it, the same as any node.
### NameWrapper
#### Wrapped Name
The [ENS Name Wrapper](/wrapper/overview) is a contract for ENS that allows you to "wrap" any ENS name into a ERC-1155 NFT. This includes not only .eth 2LDs like `name.eth`, but also DNS names like `name.xyz`, or subnames like `sub.name.eth`.
#### Fuse
The technical term for a specific "permission" bit for a wrapped name. As the name implies, once that bit is flipped on, the fuse is burnt and cannot be unburnt (unless the name expires).
#### Emancipated
A name is considered emancipated if it's parent is unable to replace/delete it. This is typically used to describe trustless subnames.
### Subgraph
An indexed collection of data using TheGraph protocol.
In this documentation portal, "the subgraph" usually refers to the official ENS subgraph maintained by ENS Labs.
This is a useful offchain service that allows clients to query for information about names or accounts.
## Name Wrapper Contract Details
The Name Wrapper contract is deployed on these chains:
* Mainnet: [wrapper.ens.eth](https://etherscan.io/address/0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401#code)
* Sepolia: [wrapper.ens.eth](https://sepolia.etherscan.io/address/0x0635513f179D50A207757E05759CbD106d7dFcE8#code)
### Wrapping and Unwrapping
When wrapping a .eth 2LD, you're effectively transferring the ERC-721 NFT ownership to the Name Wrapper contract, which will take over the [Manager](/terminology#manager) role for the name as well.
You can do this by calling the [wrapETH2LD](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#wrapeth2ld) method. Or, you can directly transfer the ERC-721 NFT to the Name Wrapper contract. In return, the contract issues you an ERC-1155 NFT.
```solidity
NameWrapper.wrapETH2LD(string label, address wrappedOwner, uint16 ownerControlledFuses, address resolver)
// For example
wrapETH2LD(
"myname", // "myname.eth" but only the label
0x1234..., // The address you want to own the wrapped name
0, // The owner-controlled fuse bits OR'd together, that you want to burn
0x1234... // The address of the resolver you want to use
)
```
When wrapping any other ENS name, you transfer the Manager of the name to the Name Wrapper contract. You can do this by calling the [wrap](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#wrap) method. In return, the contract issues you an ERC-1155 NFT.
```solidity
NameWrapper.wrap(bytes name, address wrappedOwner, address resolver)
// For example
wrapETH2LD(
0x03737562046e616d650365746800, // The DNS-encoded version of "sub.myname.eth"
0x1234..., // The address you want to own the wrapped name
0x1234... // The address of the resolver you want to use
)
```
As the owner of the wrapped name, you can unwrap at any time by calling either [unwrapETH2LD](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#unwrapeth2ld) or [unwrap](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#unwrap). You can do this as long as the permission to unwrap has not been revoked.
```solidity
NameWrapper.unwrapETH2LD(bytes32 labelhash, address registrant, address controller)
// For example
unwrapETH2LD(
0x952f..., // "myname.eth" but only the labelhash: keccak256('myname')
0x1234..., // The address you want to own the unwrapped name
0x1234... // The address you want to be the manager of the unwrapped name
)
NameWrapper.unwrap(bytes32 parentNode, bytes32 labelhash, address controller)
// For example
unwrap(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
0xfa1e..., // The labelhash of the child to unwrap, e.g. keccak256('sub')
0x1234... // The address you want to be the manager of the unwrapped name
)
```
### Burning Fuses / Setting Expiry
If you are wrapping an existing .eth 2LD, then you can pass in the owner-controlled fuses at that time, see the above [Wrapping and Unwrapping](#wrapping-and-unwrapping) section. If you are creating a new subname, and you want to burn fuses at the same time, see the below [Creating Subnames](#creating-subnames) section.
For other existing wrapped names, you can burn fuses with either the `setFuses` or `setChildFuses` methods.
The `setFuses` method is used for a name that you own, but you do not necessarily own the parent of. You have the ability to burn any [Owner-Controlled Fuses](/wrapper/fuses#owner-controlled-fuses) you want. Note that your name must first be [Emancipated](/wrapper/states#emancipated) in order for you to be able to burn any owner-controlled fuses. All .eth 2LDs are automatically emancipated upon wrapping.
When burning owner-controlled fuses, at a minimum you must burn the **`CANNOT_UNWRAP`** fuse (if it has not already been burned).
```solidity
NameWrapper.setFuses(bytes32 node, uint16 ownerControlledFuses)
// For example
setFuses(
0x6cbc..., // The namehash of the node, e.g. "myname.eth"
1 // The owner-controlled fuse bits OR'd together, that you want to burn
)
```
The `setChildFuses` method is used for a subname that you own the parent of. As long as the subname has not yet been [Emancipated](/wrapper/states#emancipated), you can burn whatever [Parent-Controlled Fuses](/wrapper/fuses#parent-controlled-fuses) and [Owner-Controlled Fuses](/wrapper/fuses#owner-controlled-fuses) you want. At the same time, you must set an expiry for those fuses, if one is not already set. Note that your name must first be [Locked](/wrapper/states#locked) in order for you to burn fuses on any subnames.
If you are only burning parent-controlled fuses, then there are no further restrictions. However, if you are burning owner-controlled fuses, then you must at a minimum burn both **`PARENT_CANNOT_CONTROL`** and **`CANNOT_UNWRAP`** on the subname to lock it at the same time.
```solidity
NameWrapper.setChildFuses(bytes32 parentNode, bytes32 labelhash, uint32 fuses, uint64 expiry)
// For example
setChildFuses(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
0xfa1e..., // The labelhash of the child, e.g. keccak256('sub')
65537, // The fuse bits OR'd together, that you want to burn
2021232060 // The expiry for the subname
)
```
### Creating Subnames
This is done very similarly to how unwrapped subnames are created. You call either `setSubnodeOwner` or `setSubnodeRecord` on the wrapper contract. When a name is wrapped, all subnames created will also be wrapped by default.
You can also pass in the fuses and expiry at the same time, so that the subname will be created in the fuse/permission state that you want, without needing to perform an extra transaction.
```solidity
NameWrapper.setSubnodeOwner(bytes32 parentNode, string label, address owner, uint32 fuses, uint64 expiry)
// For example
setSubnodeOwner(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
"sub", // The label of the subname to create
0x1234..., // The address you want to be the owner of the new subname
65536, // The fuse bits OR'd together, that you want to burn
2021232060 // The expiry for the subname
)
NameWrapper.setSubnodeRecord(bytes32 parentNode, string label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry)
// For example
setSubnodeRecord(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
"sub", // The label of the subname to create
0x1234..., // The address you want to be the owner of the new subname
0x5678..., // The address of the resolver to set for the new subname
0, // The TTL to set for the new subname
65536, // The fuse bits OR'd together, that you want to burn
2021232060 // The expiry for the subname
)
```
### Approved Operators
#### Full-Control Operator Batch Approvals
Your wrapped name is an ERC-1155 NFT that supports the `setApprovalForAll` method. When you approve an address using this method, it will have **full control** over all wrapped ENS names that you own.
This method is typically used by NFT marketplace contracts.
#### Name-Specific Subname Renewal Manager Approvals
The Name Wrapper also supports the ERC-721 `approve` method. This method is used to approve a single "Subname Renewal Manager" for a specific name.
The "Renewal Manager" does not have full control over your wrapped name, it can only set / extend the expiry on subnames.
Further, if you burn the **`CANNOT_APPROVE`** fuse on your name, then the approved renewal manager can no longer be changed. You can use this to "lock in" that contract, so that you can guarantee to all subname owners that renewals/extensions can always be done.
This approved renewal manager will be reset if the wrapped NFT is burned or re-minted, which happens if you unwrap the name, or if an expired name gets re-registered. It will also be reset if the wrapped NFT is transferred, **unless** the **`CANNOT_APPROVE`** fuse is burned.
#### Example - Subname Registrar Contract
You can use these operator approval methods to setup a separate contract that can take certain actions on your behalf. One example is setting up a "subname registrar" to allow users to register/renew subnames.
That subname registrar contract would act on your behalf and allow users to register subnames. To allow this, you would call `setApprovalForAll` to give that contract full control over your name (and thus the ability to create subnames).
Then, to enable "unruggable renewals", you could call `approve` on that same contract (or a separate one specific to renewals if you wish) and burn **`CANNOT_APPROVE`** to lock in subname renewals for that contract.
If you need to later on, you would still be able to revoke with `setApprovalForAll`. So the contract would lose full control over your name (and the ability to create new subnames), but it would still be able to perpetually renew/extend existing subnames.
And you can do all of this **without** needing to send your wrapped NFT to that contract.
## Creating a Subname Registrar
In the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section, we talked about the ability to stand up your own "registrar" to allow other people to register/claim subnames automatically. Maybe you want to give wrapped subnames out for free, or maybe you want to charge for them. Maybe you want to apply specific rules to the subnames, such as only allowing alphanumeric names. All of this is possible, and this article will break down what you need to do.
It's recommended to first read the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section to get an overview of the decisions you'll need to make.
### Prerequisites
This guide assumes that your parent name (such as `myname.eth`) is already wrapped. If you're not sure whether your name is wrapped, look at the "More" tab on the Manager app. If the name is unwrapped, it will say so, and it will show you a "Wrap Name" button.
If you want to issue [Emancipated](/wrapper/states#emancipated) subnames, or subnames with [any other fuses](/wrapper/fuses) burned, then your parent name must first be [Locked](/wrapper/states#locked). You can do this on the Permissions tab in the ENS manager app.
:::note
With ENSv2 on the horizon, we recommend holding off on locking your name; locked names in the Name Wrapper will only be migratable to L1, so if you want to be able to issue trustless subnames on Namechain your best option is to wait until Namechain is live.
:::
:::warning
Locking your name (in other words revoking the permission to unwrap) is an **irreversible** change. After you lock the name, you will no longer be able to unwrap it. This is a security guarantee for the holders of all subnames. It ensures that the owner of the parent name cannot get around the security guarantees of the Name Wrapper.
For development or testing purposes, it's best to do this on a Sepolia testnet name first.
:::
### Creating and Deploying your Registrar Contract
In order to create a new subname, your contract should call either `setSubnodeOwner` or `setSubnodeRecord` on the [NameWrapper contract](/learn/deployments#deployments). Also pass in the fuses and expiry at the same time, as needed.
```solidity
NameWrapper.setSubnodeOwner(bytes32 parentNode, string label, address owner, uint32 fuses, uint64 expiry)
// For example
setSubnodeOwner(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
"sub", // The label of the subname to create
0x1234..., // The address you want to be the owner of the new subname
65536, // The fuse bits OR'd together, that you want to burn
2021232060 // The expiry for the subname
)
NameWrapper.setSubnodeRecord(bytes32 parentNode, string label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry)
// For example
setSubnodeRecord(
0x6cbc..., // The namehash of the parent node, e.g. "myname.eth"
"sub", // The label of the subname to create
0x1234..., // The address you want to be the owner of the new subname
0x5678..., // The address of the resolver to set for the new subname
0, // The TTL to set for the new subname
65536, // The fuse bits OR'd together, that you want to burn
2021232060 // The expiry for the subname
)
```
Your public-facing registration function would typically take at *least* the parent node (namehash) and subname label as inputs, such as:
```solidity
register(bytes32 parentNode, string calldata label)
```
Then under the hood, your contract will call `setSubnodeRecord` and fill in the rest of the parameters on behalf of the user:
* owner: Typically the caller account, `msg.sender`
* resolver: Typically the default public resolver, `resolver.eth`
* ttl: 0
* fuses: Up to you and your goals. See the [Use Cases](/wrapper/usecases#sell-or-rent-subnames) section for a discussion on this. Typically 65536 for an enamcipated rental subname, or 327680 for an emancipated "forever" name.
* expiry: Up to you and your goals. If you are renting subnames for a particular length of time, this expiry would reflect that. If you are allowing registration of "forever" names, then you can just set the expiry equal to the parent name's current expiry.
Of course, if you want to give the registrant more power/convenience, you could allow some of those parameters to be passed in to your public register function as well.
#### Setting Resolver Records
If you want your subname registrar to set records on a subname in the same registration transaction, then the flow will be slightly different. In that case, perform these steps:
* Call `setSubnodeOwner`, setting the *contract itself* (`address(this)`) as the owner of the subname, temporarily. This first step is needed for the default Public Resolver so that the contract has the authority to set records for the subname.
* Call whatever [resolver methods](/resolvers/interacting) you need to. Perhaps these are records that you want to be pre-set on your subnames (such as an ETH address that the subname points to). Or perhaps these are records that you allow the registrant to pass in, so that they can register their subname and set whatever records they want all in one transaction.
* Call `setSubnodeRecord`, but this time set the owner to the actual intended owner of the subname. This is the point at which you should set the appropriate fuses and expiry you want to, as well.
In addition, you will need to make sure your contract follows the [ERC-1155 Token Receiver rules](https://eips.ethereum.org/EIPS/eip-1155#erc-1155-token-receiver). This means implementing the `onERC1155Received` and `onERC1155BatchReceived` methods, and signaling support for them in your ERC-165 `supportsInterface` method. OpenZeppelin has an easy abstract contract you can include for all this: [ERC1155Holder.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/utils/ERC1155Holder.sol)
#### Taking fees
If you are setting up a "rental" registrar, then your registration function should require a certain amount of ETH to be sent in as well.
Alternatively, you could choose to allow users to spend ERC-20 tokens instead. To accomplish that, you would typically call the ERC-20 method `transferFrom` on the token contract. This also means that the registrant would first need to approve your contract as a spender for that token, meaning they would need to execute a separate approval transaction first (either to approve unlimited spending, or to approve the specific number of tokens needed to register the subname).
#### Reference Implementation
Luckily, you don't need to start from scratch! The ENS Labs devs have created some example contracts you can start from:
[https://github.com/ensdomains/ens-contracts/tree/feature/subdomain-registrar/contracts/subdomainregistrar](https://github.com/ensdomains/ens-contracts/tree/feature/subdomain-registrar/contracts/subdomainregistrar)
These contracts include two different implementations:
##### Forever Subname Registrar
This is a basic FIFS (First in first serve) registrar. The registration can take a fixed fee, or this fee can be set to 0 if you wish for subnames to be free. Names automatically are set to the parent's expiry can the fuse for `CAN_EXTEND_EXPIRY` will be burnt on registration so the user can extend their expiry if the parent also extends theirs. For a better UX, it is recommended that the parent sets their expiration as high as possible to allow their users to not have to think about renewing.
##### Rental Subname Registrar
This is a basic FIFS (First in first serve) registrar. The key difference between this and the ForeverSubdomainRegistrar is that it does not auto-burn the `CAN_EXTEND_EXPIRY` fuse and instead exposes a `renew()` function that allows paid renewal. This registrar also needs to be paired with a rental-based pricing contract. For simplicity, the deployer can deploy this pricing contract and the UI can pass this address through to `setupDomain()` when a new user wants to setup a subname.
### Setting Everything Up
Once you have a parent name ready and a subname registrar contract deployed, then you just need a few extra steps to set everything up:
#### (If needed) Call setupDomain on your contract
This will only apply to you if you have a specific `setupDomain` method or something similar on your contract, such as the [reference implementation](/wrapper/creating-subname-registrar#reference-implementation) contracts do.
Calling this method will "enable" a specific parent name in your subname registrar. It can also allow you to set or update the pricing terms or beneficiary account, if needed.
#### Approve your contract
Call `setApprovalForAll` on the NameWrapper contract, approving your subname registrar contract as an operator for any names you own. This allows you to keep ownership of the parent name, and just delegate subname creation to your contract.
#### (If needed) Approve token spending
If your registrar contract takes ERC-20 tokens as a registration fee, then a potential registrant will need to approve your contract as a spender first.
#### Register a subname
Finally, the registrant will call your public registration method. Upon transaction success, they will own the wrapped name (ERC-1155 NFT) with whatever fuse/expiry guarantees that you setup in your registrar.
If you are allowing "forever" subnames to be registered (meaning that you've burned the `CAN_EXTEND_EXPIRY` fuse on the subnames), then the registrant can extend their own expiry at any time. Note that a subname's expiry can be set up to a maximum of whatever the parent name's expiry is.
And that's it!
import { Card } from '../../components/ui/Card'
## Name Wrapper Expiry
In order to burn any fuses on a name, you must also set an **expiry** on it. This expiry determines how long any burned fuses are active for, and may also determine whether the name itself has expired.
If the name is a .eth 2LD, then the expiry will automatically be set to the same expiry in the .eth Registrar. But for all other names, the parent can choose what expiry to set for a child name.
### Max Expiry for Subnames
By default, the expiry for a name can only be set by the parent, and can only be increased, not decreased. The maximum value for the expiry of a name is the expiry of its parent name.
For example, say a name expires in 5 years. The owner of the name can then set the expiry of its subnames to a maximum of 5 years as well. But the parent could also choose to set the expiry to something less. Let's say the parent sets the expiry of one of its subnames to 2 years.
Then in turn, the owner of the subname can set the expiry of its own subnames up to a maximum of 2 years, but it could also set it to something less, like 1 year.
The parent can set a different expiry for different subnames too, just as it can burn different fuses for different subnames.
### Renewals
When a wrapped .eth second-level name (like `name.eth`) is renewed, that new expiry is automatically set in the Name Wrapper as well as in the .eth Registrar. However, the expiry for any other .eth names (like `sub.name.eth`) will not be automatically extended when the parent expiry is extended.
The parent can extend the expiry for an existing subname at any time, even if the subname has been emancipated.
The parent can also choose to approve a separate contract to allow the expiry for subnames to be extended by the subname owner or other accounts.
That is basically how .eth second-level names work: Since the `eth` node is locked in the registrar contract and has the Name Wrapper (which exposes a renew method) approved as a controller, .eth second-level names can be directly renewed by their owners.
The parent can further lock this approved contract in by burning the **`CANNOT_APPROVE`** fuse.
There is also a special parent-controlled fuse called **`CAN_EXTEND_EXPIRY`**. If the parent burns this fuse on a subname, then the owner of that subname (or any approved controller) can also extend the expiry.
So, if you are running a subname registrar and you want to enable "unruggable renewals", you can use one of the above options (or both).
### Special Cases for .eth 2LDs
For .eth second-level names, the end of the name's grace period (from the .eth Registrar) is used for the expiry inside of the Name Wrapper.
So if the name's expiration date in the Registrar is January 1st, then the expiry in the Name Wrapper will reflect that date *plus* the grace period (currently 90 days, so approximately April 1st, depending on the year).
When the name's expiration date (from the .eth Registrar) has been reached, and the name is now in the grace period, all Name Wrapper operations on the name will be restricted.
The owner will *not* yet lose ownership of the name, but they will also not be able to unwrap or update the name until it has been renewed.
### Expiry Implications
When a name is merely **Wrapped** but not **Emancipated** or **Locked**, parent-controlled fuses can still be burned. This means that the parent can burn a custom fuse for a limited amount of time.
When the expiry (end of grace period for .eth 2LDs) is reached, all fuses will be reset, but the name will otherwise be unaffected.
When a name is **Emancipated** or **Locked**, the expiry has an important additional effect. In this scenario, when the expiry (end of grace period for .eth 2LDs) has been reached, **the name itself will expire**, and the owner **loses ownership** of the name.
## Name Wrapper Fuses
A "fuse" is a permission or perk that can be granted/revoked on a name. As the name implies, once the fuse is "burned", it cannot be unburned.
Fuses will only reset when the **expiry** is reached. In the ENS Manager UI, this is available in the "Permissions" section of the name.
By **wrapped expiry**, we mean that for .eth second-level names (like `name.eth`), this is the end of the 90-day grace period, the time at which the .eth 2LD is truly released. For all other names (such as subnames), there is no grace period, so the expiry is just the expiration date for that specific subname.
For example, by default when you wrap a name, you can transfer that NFT around freely, just as you can with other NFTs. However, if the **`CANNOT_TRANSFER`** fuse is burned, then the NFT becomes non-transferrable. In the ENS Manager UI, you would do this by revoking the "Can send this name" permission.
In order to burn fuses on a name, the parent name must be **Locked** (meaning, you cannot unwrap the name). The reason is, if the parent name was not locked, then the owner of the parent name could simply get around the constraints of the Name Wrapper by unwrapping the name, and replacing/revoking subnames against the core ENS Registry.
There are parent-controlled and owner-controlled fuses:
### Parent-Controlled Fuses
Only the owner of the parent name can burn one of these fuses on a name. These can generally be thought of as "perks" that can be granted to a name, though they can be used in other ways.
| Fuse name | Description |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`PARENT_CANNOT_CONTROL`** | Allows a parent owner to **Emancipate** a child name. After this is burned, the parent will no longer be able to burn any further fuses, and will no longer be able to replace/delete the child name. This fuse must be burned in order for any owner-controlled fuses to be burned on the name. |
| **`IS_DOT_ETH`** | This fuse cannot be burned by users of the Name Wrapper, it is only set internally when a .eth 2LD is wrapped. |
| **`CAN_EXTEND_EXPIRY`** | The owner of the child name will be able to extend their own expiry. Normally, only the parent owner can extend the expiry of a child name. See the [Expiry](/wrapper/expiry) section for more information. |
| **Custom Fuses** | There are 13 other parent-controlled fuses that are not reserved, and can be used in any custom way you want! |
### Owner-Controlled Fuses
Either the owner of the name or the owner of the parent name can burn one of these fuses. These can generally be thought of as "permissions" that can be revoked on a name, though they can be used in other ways.
| Fuse name | Description |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`CANNOT_UNWRAP`** | The name will now be **Locked**, and can no longer be unwrapped. This fuse must be burned in order for any other owner-controlled fuses to be burned on the name. |
| **`CANNOT_BURN_FUSES`** | No further fuses can be burned on the name. |
| **`CANNOT_TRANSFER`** | The name (wrapped NFT) can no longer be transferred. |
| **`CANNOT_SET_RESOLVER`** | The resolver contract for the name can no longer be updated. |
| **`CANNOT_SET_TTL`** | The TTL for the name can no longer be updated. |
| **`CANNOT_CREATE_SUBDOMAIN`** | New subdomains can no longer be created. |
| **`CANNOT_APPROVE`** | The approved "subname renewal manager" for the name can no longer be updated. See the [Approved Operators](#approved-operators) section for more information. |
| **Custom Fuses** | There are 9 other owner-controlled fuses that are not reserved, and can be used in any custom way you want! |
### The Emancipated and Locked States
This is also covered in the [Wrapped States](/wrapper/states) section, but here is a quick recap:
All .eth second-level names (like `name.eth`) are automatically placed into the Emancipated state when wrapped.
**Emancipated** means that the parent no longer has control over the child name. It can no longer burn any fuses or replace the subname, up until the expiry.
A name is Emancipated when the parent burns the **`PARENT_CANNOT_CONTROL`** (PCC) fuse. The parent must first be in the Locked state to be able to do this.
**Locked** means that the name cannot be unwrapped. This provides assurance to subnames that the parent owner cannot unwrap and then, for example, start replacing subnames directly against the registry.
An Emancipated name is Locked when the **`CANNOT_UNWRAP`** (CU) fuse is burned.
Think of the special PCC / CU fuses recursively:
* To burn owner-controlled or subname fuses, CU must be burned.
* To burn CU, PCC must be burned.
* Only the parent can burn PCC on the child name, and only if CU is first burned on the parent.
* Only the grandparent can burn PCC on the parent name, and only if CU is first burned on the grandparent.
* And so on...
Follow that chain up until you hit a .eth second-level name like `name.eth`, since .eth second-level names will have PCC automatically burned when wrapping. The parent `eth` node is already in the Locked state.
A parent name can burn all the fuses it needs to on a child name in one transaction. This can be done when the subname is created, or on an existing subname that has not yet been Emancipated.
### DNS Domains and Fuses
Currently, only .eth names support fuses, because only the `eth` node is onchain native and completely locked beyond anyone's control.
Technically speaking, the owner of a DNS TLD has the ability to burn fuses on that TLD in the Name Wrapper, and set it to the "Locked" state. And then from there, all subnames under that DNS TLD *will* be able to use fuses.
The DNS TLD owner would need to:
* Request the Controller of that TLD from the ENS DAO
* Wrap the TLD node in the Name Wrapper
* Burn the **`PARENT_CANNOT_CONTROL`** and **`CANNOT_UNWRAP`** fuses on the wrapped TLD to lock it
However, this still does not have all the immutable guarantees that .eth names do. This is because for DNS names, the "source of truth" always lies not in the Ethereum network, but in the DNS network, and the DNS root zone governed by ICANN stakeholders.
So even if the DNS TLD owner "Locks" that TLD in the ENS Name Wrapper, if that TLD were to ever change ownership on the DNS side, then (per the [ENS DAO Constitution](https://docs.ens.domains/v/governance/ens-dao-constitution#iv.-ens-integrates-with-the-global-namespace)) the new owner would be able to override control of that TLD on the ENS side, unwrap it, and replace/revoke all 2LDs. This is just something to keep in mind for wrapped DNS domains.
Even if wrapped DNS domains do not support fuses, you can still use them as ERC-1155 NFTs. They will still have their own NFT metadata and show up in your wallet, with whatever avatar you have set, etc. They just won't have all the extra functionality that comes with the fuse/permission system.
import { Card } from '../../components/ui/Card'
## Name Wrapper Overview
:::note
Are you looking for user-facing guides on how to interact with the Name Wrapper in the ENS Manager App? If so, see here instead: [Name Wrapper Guides](https://support.ens.domains/en/collections/4194784-name-wrapper-guides)
:::
The **Name Wrapper** is a contract for ENS that allows you to "wrap" any ENS name into a ERC-1155 NFT.
### Without the Name Wrapper
Before the Name Wrapper, only .eth 2LDs (second-level domains, like `ens.eth`) had ERC-721 NFTs associated with them, unless the owner created a separate custom contract.
### With the Name Wrapper
**Parent-Controlled Fuses:**
* [Fuses](/wrapper/fuses) that only the parent owner can burn
* "Perks" that can be given to the owner of a name
**Example:** By burning `CAN_EXTEND_EXPIRY`, you allow the owner to
extend/renew their own subname
**Owner-Controlled Fuses:**
* [Fuses](/wrapper/fuses) that either the owner or parent owner can burn
* "Permissions" that can be revoked on a name
**Example:** By burning `CANNOT_TRANSFER`, the wrapped NFT can no longer be
transferred or sold.
**Subname Fuses:**
* The parent owner has the power to burn fuses when creating subnames
* Decides what perks, permissions, or guarantees to give to subname owners
With this new contract, you can wrap:
* Any .eth name or subname (e.g. `name.eth`, `sub.name.eth`)
* Any DNS name or subname (e.g. `name.com`, `sub.name.com`)
Unwrapped .eth 2LDs have the concept of a separate **Owner** and **Manager**.
This changes after you wrap the name, because there is only a single account that serves as both the **Owner** and **Manager** for the wrapped name.
## Wrapped States
```mermaid
graph LR;
unregistered((Unregistered));
unwrapped(Unwrapped);
wrapped(Wrapped);
emancipated(Emancipated);
locked(Locked);
unregistered--->|register|unwrapped;
unwrapped--->|wrap|wrapped;
wrapped--->|unwrap|unwrapped;
wrapped--->|protect|emancipated;
emancipated--->|lock|locked;
emancipated--->|unwrap|unwrapped;
emancipated--->|expire|unregistered;
locked-->|expire|unregistered;
```
Taking the Name Wrapper into account, an ENS name can be in one of these possible states:
#### Unregistered
The name has not even been registered/created yet, or it has expired.
#### Unwrapped
The name exists and has not expired (in the case of .eth second-level names). The Name Wrapper contract does not have ownership over the name. You own the name in the registry and/or .eth registrar.
#### Wrapped
The Name Wrapper contract has ownership of the name (in the registry/registrar). You are issued an ERC-1155 NFT in return, which proves that you are the actual owner.
You can unwrap the name at any time, which burns the ERC-1155 NFT, and returns ownership in the registry/registrar back to you.
If your name is a subname like `sub.name.eth`, then the owner of `name.eth` can technically replace the subname and transfer it to a different owner.
In addition, the parent owner can burn parent-controlled fuses on your name.
#### Emancipated
The owner of the parent name is no longer able to replace this name, or burn any additional fuses on it. All .eth second-level names (like `name.eth`) are automatically put into the Emancipated state when they are wrapped.
The name can still be unwrapped and rewrapped by the owner.
#### Locked
The name can no longer be unwrapped. The owner can now burn owner-controlled fuses on the name. Fuses for subnames of this name can now be burned as well.
## Name Wrapper Use-Cases
### Lock the resolved records for a name
By default, newly registered names will use the Public Resolver, which just allows the current manager/controller of the name to update any records.
However, in some cases perhaps you want to make sure that a name resolves to specific records and **never** changes. You can accomplish this with the **`CANNOT_SET_RESOLVER`** fuse.
Say you own `mycoolcontract.eth` representing a smart contract. You can use ENS subnames to refer to specific versions of that contract, like `1.mycoolcontract.eth`. And perhaps you want those versioned subnames to always point to:
* The ETH address of that immutable contract
* The ABI for that contract
* The contenthash for some versioned documentation page
* etc.
One way to do this is just to make sure the name is **Locked**, all the records are set correctly, and then transfer the owner to some burn address so it can never be updated again.
But of course this isn't ideal, because maybe there are some records that you *do* want to update in the future. Or maybe you still want to keep ownership of that subname for other reasons.
Instead of essentially burning the name, you could create a custom resolver that locks in certain records forever. Then:
1. Set the resolver of that name to your custom contract
2. Set the records however you want and lock them into the resolver
3. Burn these fuses on the name:
* `PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_SET_RESOLVER`
Now you can still keep ownership and even some limited management power over the name, while still guaranteeing that the ETH address, ABI, and whatever other records are completely immutable, as long as the expiry is set appropriately.
### Issue subdomains as tickets to an event
Maybe you have `mycoolevent.eth` and you want to issue tickets like `1.ticket.2023.mycoolevent.eth`.
If you want, you can choose to not Emancipate those subnames, but still burn some custom parent-controlled fuses. Those fuses might:
* Indicate what "tier" their event ticket is
* Maybe they can upgrade their ticket to a higher tier, which would burn some additional fuses
* Allow them access to the express line or some VIP room
* Maybe even automatically via some smart door
When you burn those fuses, perhaps you also set the expiry to the day after the event ends.
Or, maybe you want your attendees to be able to keep their subnames as a souvenir or proof-of-attendance!
If so, then instead of letting the names expire at the end of the event, you could extend the expiry and burn some additional fuses to allow the attendees to keep them forever! In that case you might want to burn these fuses:
* `CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL`
If you want those tickets to be non-transferrable (soulbound to the address that attended), then burn these fuses:
* `CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_TRANSFER`
### Sell or rent subnames
#### I want to sell / rent out subnames!
Say you own the wrapped name `verypopularname.eth`. Obviously you can just manually create wrapped subnames like `my.verypopularname.eth` and then sell them on an NFT marketplace. But that sure doesn't scale well.
To accomplish this, you will want to create a **subname registrar**. This is a contract that will handle all the registration / renewal for you, and then users will be able to interact with that contract in order to register their own subnames.
In fact, this is exactly how .eth 2LDs are registered. The owner of the `eth` TLD (the NFT contract) delegates registration / renewal to the ETHRegistrarController contract. It is acting as a subname registrar for the name `eth`.
Your contract would expose a `register` method that anyone can call. Under the hood it will use the [setSubnodeOwner](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#setsubnodeowner) or [setSubnodeRecord](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#setsubnoderecord) methods to create subnames, passing in the **fuses** and **expiry** you want to set.
#### What fuses should I burn???
First, note that if you want to burn any fuses on subnames, then your name must be **Locked** (meaning **`CANNOT_UNWRAP`** is burned).
Assuming that you want your subnames to be "unruggable", such that you cannot replace / revoke them, then you will want to burn **`PARENT_CANNOT_CONTROL`** on the subnames. This will place them in the **Emancipated** state upon registration.
If you want to sell "forever" subnames, where users register once and can then keep them for as long as they wish, then you can consider burning the **`CAN_EXTEND_EXPIRY`** fuse.
This will allow the subname owner to extend their own expiry whenever they want. The max expiry is the expiry of the parent name, but the .eth Registrar allows *anyone* to renew/extend a .eth 2LD as well.
If you just want to **rent** subnames, then do not burn **`CAN_EXTEND_EXPIRY`**. Instead, you could include a `renew` method on your contract that users can call for another fee.
If you want to enable "unruggable renewals" for your registrar, to guarantee that users will always be able to renew, then you can call `approve` on the Name Wrapper and approve your registrar contract as the "subname renewal manager" for your name.
Then, burn the **`CANNOT_APPROVE`** fuse on your name, to guarantee that you can never revoke that contract for subname renewals. See [Approved Operators](/wrapper/contracts/#approved-operators) for more info.
If you want to impose other restrictions on your registered subnames, then you can burn the **`CANNOT_UNWRAP`** fuse to Lock the subname, and also burn whatever other fuses you want.
For example, if you want to prevent owners of your subnames (like `my.verypopularname.eth` from creating their own subnames (like `buy.my.verypopularname.eth`), then you would burn **`CANNOT_UNWRAP`** and **`CANNOT_CREATE_SUBDOMAIN`**.
To recap on fuses...
* Sell permanent names:
* `CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL`
* Sell permanent names, but prevent them from creating their own subnames:
* `CAN_EXTEND_EXPIRY | PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_CREATE_SUBDOMAIN`
* Rent out names:
* `PARENT_CANNOT_CONTROL`
* Rent out names, but prevent them from transferring or reselling them:
* `PARENT_CANNOT_CONTROL | CANNOT_UNWRAP | CANNOT_TRANSFER`
And so on, it's up to you. You can also burn whatever custom parent-controlled or owner-controlled fuses you want to.
#### Can I customize my own rules and fees?
Yes! It's your registrar contract, so you can impose whatever rules and fees you want.
For example, the .eth Registrar imposes a 3-character minimum on all names, as well as a [custom fee structure](https://support.ens.domains/core/registration/fees) and a [temporary premium auction](https://support.ens.domains/core/registration/temporary-premium) upon expiration.
By default there is no character limit on subnames, but your contract could have its own rules and fee structure or whatever you want. For example, you can:
* Allow or disallow specific addresses from registering / renewing
* Only allow registration based on some custom criteria like holding a specific NFT
* Custom length restrictions like only 3+ characters or \< 100 characters
* Only allow names with characters `[a-z0-9]` and nothing else
* Use a custom fee structure based on:
* The length of the name
* The specific characters that are in the name, like emojis
* A pre-curated list of "good" names like people's first names
* And whatever other rules you want.
#### More information
See this page for a step-by-step guide on creating and setting up your own subname registrar: [Creating a Subname Registrar](/wrapper/creating-subname-registrar)
There is even a set of [reference implementation contracts](/wrapper/creating-subname-registrar#reference-implementation) you can use as a starting base!
### Give subnames out to NFT holders
#### I want to give subnames out to all of my DAO members / NFT holders!
Say you own the wrapped name `mycoolnft.eth`, representing a popular NFT project you created. You want to distribute subnames like `6529.mycoolnft.eth` to all holders.
One option is to just bulk create the subnames and drop the wrapped NFTs into their wallets. This might be good at least as an initial drop, because then the holders don't need to interact with any contract or spend any gas, you're doing that for them!
To create the subnames, you'd use the [setSubnodeOwner](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#setsubnodeowner) or [setSubnodeRecord](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#setsubnoderecord) methods.
You must also decide:
#### How much control over the subnames do you want to relinquish?
Do you want to be able to revoke subnames? Or do you want them to be completely outside your control?
One thing to consider is whether you want the **current** holder of your NFT to always be able to claim/reclaim the corresponding ENS subname. If so, then you will **not** want to Emancipate those subnames (in other words, do not burn **`PARENT_CANNOT_CONTROL`**).
If the subname is Emancipated, then the NFT holder could sell/transfer the NFT but keep the subname (up until the expiry).
To make it easy for anyone to claim/reclaim a subname after your initial drop, you can set up a contract for this.
#### Setting up a subname claim contract
The claim method of your contract could:
1. Call `ownerOf` or `balanceOf` on your NFT contract to get or verify the current owner of the NFT
2. Call `ownerOf` or `balanceOf` on the ENS Name Wrapper contract to get or verify the current owner of the wrapped subname
* If both owner addresses are the same, just return, nothing to do
3. Call `setSubnodeOwner` or `setSubnodeRecord` on the ENS Name Wrapper:
* **owner:** The current owner of the NFT
* **fuses:** What fuses you want to burn (if any) on that subname. If you burn any fuses, you must also set an expiry.
* **expiry:** When the subname will expire.
Then, to give that contract access to create subnames on your behalf, you would call `setApprovalForAll` on the Name Wrapper to approve your contract as an operator.
Now, even if the NFT gets sold / transferred, the new owner will be able to claim their `mycoolnft.eth` subname at any time.
In addition, if you expand your NFT collection in the future and there are new owners, then those new owners would be able to claim their subnames as well.
If you are creating a new NFT contract, you could even bake this functionality **directly into the NFT contract** too, instead of needing a separate contract! By doing this, you wouldn't need a separate `claim` method either, your NFT contract would just **automatically transfer the wrapped ENS subname** whenever the NFT itself gets transferred!
#### Giving your subname owners perks
If you decide to not Emancipate the subnames that you issue, you *will* still be able to burn any Parent-Controlled Fuses. There are 13 unreserved parent-controlled fuses that you can use however you wish!
For example, perhaps you want to grant onchain "perks" or "roles" to certain holders. You would call [setChildFuses](https://github.com/ensdomains/ens-contracts/tree/master/contracts/wrapper#setchildfuses) on the Name Wrapper and pass in the fuses you want to burn, and the expiry.
This means that those "perks" or "roles" can also be time-boxed if you want. Maybe a perk expires in 1 week or something, up to you.
There is also the reserved **`CAN_EXTEND_EXPIRY`** parent-controlled fuse. If you burn this, then the subname owner will be able to extend their own expiry whenever they want.
import { EnsProfile } from '../../components/EnsProfile'
import { Card } from '../../components/ui/Card'
## Avatars
Personalization of profiles is what makes identity great.
This page covers the very special **avatar** record that enables users to take their avatar with them across the web.
### Getting the user's Avatar
Avatars are an awesome way for users to express themselves. To get the user's avatar, all you need is their **name**. If you only have their address, see [primary names](/web/reverse#get).
The following code snippets let you get the avatar for a user.
:::code-group
```tsx [Wagmi]
// https://wagmi.sh/react/hooks/useEnsAvatar
import { useEnsAvatar } from 'wagmi'
function App() {
const { data: ensAvatar } = useEnsAvatar({
address: 'nick.eth',
chainId: 1, // (1 = Ethereum Mainnet, 11155111 = Sepolia)
})
return (
)
}
```
```ts [Ethers]
// https://docs.ethers.org/v5/api/providers/provider/#Provider-getAvatar
const ensAvatar = await provider.getAvatar('nick.eth')
```
```ts [Viem]
// https://viem.sh/docs/ens/actions/getEnsAvatar.html
import { normalize } from 'viem/ens'
import { publicClient } from './client'
const ensAvatar = await publicClient.getEnsAvatar({
name: normalize('nick.eth'),
})
```
```py [Web3.py]
# https://web3py.readthedocs.io/en/latest/ens_overview.html#read-text-metadata-for-an-ens-record
from ens.auto import ns
avatar = ns.get_text('alice.eth', 'avatar')
```
```go [Go]
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/ethclient"
ens "github.com/wealdtech/go-ens/v3"
)
func main() {
client, _ := ethclient.Dial("https://rpc.ankr.com/eth")
domain, _ := ens.Normalize("nick.eth")
resolver, _ := ens.NewResolver(client, domain)
avatar, _ := resolver.Text("avatar")
fmt.Println("Avatar: ", avatar)
}
```
:::
#### The Metadata Service
The [metadata service](https://metadata.ens.domains/docs) is run by ENS Labs. It is a free service web service that allows you to retrieve the
avatar of an ENS name via a web request, as opposed to adding extra logic to your application and interacting
with an ethereum node. This is of course centralised and should be used if absolutely necessary.
### What exactly is an Avatar Record?
An avatar record is simply a [text record](/web/records) that has "avatar" as its key and a URI as its value,
with some rules about what URI schemes are supported and how to process them. For more info, see [ENSIP-11](/ensip/12).
### Supported URI schemes
Clients are expected to support a number of URI schemas, which aren't always web URIs, so the final result you see in your application
will vary depending on how the library you are using has decided to handle avatar records.
* `http(s):` - URI Scheme for HTTP(S) URLs. Libraries will most likely return the result directly.
* `ipfs:` - URI scheme for [IPFS hashes](). Libraries may decide to fetch the result from a public gateway for you.
* `data:` - URI Scheme for [data URIs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs).
Libraries will most likely return the result directly.
* `eip155:` - The URI scheme for EIP-155 identifiers for linking to NFTs on Ethereum based chains. A little complicated
to resolve manually, most libraries should resolve this for you and return the underlying resource.
:::note
For EIP-155 NFT Avatars the nft must be owned by the wallet address the ENS
name resolves to. This is done by checking the `ownerOf` method on the NFT
contract.
:::
### Common schemes that aren't officially supported
* `ethereum:` - The URI scheme for Ethereum addresses
* `bzz:` - The URI scheme for Swarm hashes
### File Information
Avatars come in many different shapes and sizes. Not just the above URI schemas, but also in different file formats, sizes, and more.
Although standards exist for some of these, files are **not required** to follow these standards.
Below is some information about the avatars your app might be loading.
| FileProperty: | Info/Recommendation |
| -------------- | ------------------------------------------------------------------------------- |
| File Extension | Mostly `png`, `jpeg`, `jpg`, `webp`, `gif`, `webm`, but could be anything |
| File Size | We recommend having sensible timeouts |
| Aspect Ratio | We recommend `object-fit: cover` or setting a background color |
| Transparency | We recommend setting a background color as some images may contain transparency |
Luckily most browsers and network libraries have default timeouts to start with, we highly recommend that if you are doing any manual avatar downloading or fetching you add a sensible timeout.
import { EnsProfile } from '../../components/EnsProfile'
import { SendTransactionDemo } from '../../components/SendTransaction'
import { Card } from '../../components/ui/Card'
## Design Guidelines \[Guidelines for designing interfaces that use ENS names]
ENS is a tool to simplify the experience for your users by making blockchain addresses human-readable.
Here are a series of guidelines and tools that will help you make good design choices and better implement ENS in your product.
### When to show ENS names
In every instance where a user might otherwise see an Ethereum address, you can instead display an ENS name (with its avatar, if relevant).
This is true for both read and write operations.
An example of read operations where it's appropriate to show an ENS name is the connected wallet status or representing an action from another user like a vote ([Snapshot is a great example](https://snapshot.box/)).
An example of write operations where it's appropriate to show an ENS name is when a user is inputting an address of any kind (token transfer, smart contract interaction, etc.).
Beyond these use cases, remember that the [ENS Public Resolver](/resolvers/public) allows you to link [different kinds of resources](/web/records) to ENS names.
### 1. Replacing Ethereum addresses with ENS Names
:::note
An ENS name should only be shown in place of an Ethereum address if the user has set a reverse record for their address, and if the reverse record matches the forward resolution. [Learn more about primary names](/web/reverse).
:::
#### 1.1 - Displaying ENS names instead of Ethereum addresses
{/* TODO: build a sample UI of ENS names in a list, like votes or messages or transfers */}
When replacing Ethereum addresses with ENS names you should consider these facts and best practices:
* **Design a truncated version of the ENS name:** ENS names can be very long; besides not being character-limited, users can create an infinite number of nested subdomains.
If you do show a truncated version of the name, you should provide a way to view the full name, such as expanding it on hover.
* **Not all ENS names end with .eth**: ENS supports [.eth](/registry/eth) and most DNS TLDs such as [.com, .xyz, and 1200+ others](/dns/tlds).
A correct implementation of ENS treats any dot-separated name as a potential ENS name and will attempt a look-up.
#### 1.2 - Always provide an option to see the Ethereum address associated with the ENS name
If you are showing the ENS name in its entirety or a truncated version, you should:
* **Always provide the user a way to display the full Ethereum address**: Notice how if you type "ens.eth" in the [example above](#send_transaction), the resolved ETH address appears under the name.
This is especially important in high-risk situations, such as when the user is about to send a transaction or interact with a smart contract.
* **Allow the user to copy the full Ethereum address**: Allow the user to copy the full address either through a copy button or by selecting it.
* **Optionally give the user a way to automatically open the Ethereum address in a block explorer** such as Etherscan.
* **Optionally show the** **balance amount of signed-in users.** User research shows that users tend to recognise their own Ethereum address through their balance, as well as the address itself.
This is meant only for the currently "signed in" user: only show their own balance and avoid showing the balance of other users.
### 2. Resolving input fields
{/* */}
Input fields where a user is supposed to insert Ethereum addresses should also accept and resolve ENS names. These inputs indicate that the user wants to interact with another user's Ethereum address or contract.
Follow these guidelines to create the best experience:
* **Wait before resolving the ENS name**: Debounce input fields that accept ENS names to avoid unnecessary network calls. You can also wait for the user to type a minimum of 1 character on both sides of the dot before resolving the name. For example, if the user type "ens.", there is no chance of it being a valid ENS name and therefore no need to resolve it. But after the user types "ens.e", it should be treated as a potential ENS name.
* **Don't overwrite the input field with the Ethereum address:** Show the resolved ENS name near the input field instead.
* **Always display both the ENS name** ***and*** **the Ethereum address together** : Do this after it has successfully been resolved.
### Other guidelines and tips
#### Usernames for accounts that don't have an ENS name
You can offer free ENS names to your users which would not only improve their experience in your application, but also across the Ethereum ecosystem.
See [how to issue subdomains](/web/subdomains).
#### Caching and updating ENS Names
If your application needs to display many ENS Names in the UI, you can consider **caching** (for a short period of time) the ENS Name after it has been resolved or after the user has added the name in an input field.
Your **optimistic UI** can display the names from cache **in non-risky situations**, in which your user for example is simply browsing, but doesn't need to act or make decisions based on the information displayed.
However, **in all risky situations** (eg transferring anything of value or interacting with a smart contract), you should **perform a direct live resolution** and get the most up to date information from the ENS Registry.
Also consider that users can change their information at any time which may not be tracked in the onchain registry, so you should **periodically validate the information you cached**. [Learn more about offchain ENS names](/learn/ccip-read).
#### Notes on displaying Ethereum Addresses (with or without ENS names)
Even when ENS names are not available, [research](https://medium.com/@lyricalpolymath/web3designdecisionframework-e84075816515) [shows](https://medium.com/@lyricalpolymath/web3-design-principles-f21db2f240c1) that there are some good practices to follow when displaying Ethereum addresses in dApps.
* **Always show the initial ' 0x '** to indicate it's an address.
* When displaying the name in shorthand versions, **show the first 5 and last 4 characters of the address**.
This is not a security requirement as vanity addresses can be spoofed relatively simply; this is a good practice because some users check the beginning of the name and others check the end of the name.
Also, four is the highest number of elements that our mind can easily chunk, parse and remember well.
* **Always provide a way to display the full Ethereum address.**
### Front-end tools
[Thorin](https://thorin.ens.domains/) is a react component library for the ENS design system.
It provides a set of components that make it easier to follow the guidelines and best practices described above.
## Preparing for ENSv2 \[Everything you need to know to prepare your application for ENSv2.]
ENSv2 brings multi-chain support and improved architecture to ENS. While names can still be stored on Ethereum Mainnet, ENSv2 introduces Namechain as the primary Layer 2 for ENS, with support for additional L2s as well. To ensure your application works seamlessly with ENSv2, you'll need to make a few key updates.
The good news? For most applications, preparing for ENSv2 is as simple as updating to the latest version of a [supported library](/web/libraries). At the time of writing, not all libraries have added ENSv2 support yet. Here's the current status:
* [viem >= v2.35.0](https://github.com/wevm/viem/blob/main/src/CHANGELOG.md#2350)
* ethers.js: Not published yet. [Work in progress on v6.16.0](https://github.com/ethers-io/ethers.js/tree/wip-v6.16.0-ens)
* web3.js: Deprecated
:::info
**Using a supported library? You're done!** Everything is handled automatically.
The sections below are optional reading for those who want to understand the technical details or test their integration manually.
:::
### Universal Resolver
Even though ENSv2 is designed for multi-chain, all resolution still starts on Ethereum Mainnet. There is a [new Universal Resolver](/resolvers/universal) that acts as the canonical entry point. This is an upgradable proxy contract, owned be the ENS DAO, so its address won't change in the future if its implementation is changed.
Your application needs to use this new Universal Resolver in order to be ready for ENSv2. As mentioned above, updating to the latest version of your supported web3 library handles this automatically.
Learn more about the [Universal Resolver here](/resolvers/universal) and about the [resolution process in general here](/resolution).
#### Testing Universal Resolver Support
To test if your integration uses the Universal Resolver, try resolving the address for `ur.gtest.eth`. It should return `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. If it instead returns `0x1111111111111111111111111111111111111111`, you likely need to update your web3 library.
### Offchain and L2 Resolution with CCIP Read
ENSv1 already supports delegating resolution from Ethereum Mainnet to an L2 or completely offchain using [CCIP Read (ERC-3668)](/learn/ccip-read). All the libraries mentioned above implement CCIP Read. However, not all integrations handle it properly.
With ENSv2, users can store names on Ethereum Mainnet, Namechain, or any other supported L2. This makes CCIP Read support essential for your integration to work correctly.
In a nutshell, CCIP Read defers resolution to a gateway. Think of a gateway as an HTTP API. The response of the gateway can be verified with a read-call to the ENS contracts on Ethereum Mainnet (or Sepolia for testing). This means that your application needs to be able to send HTTP requests as part of the ENS resolution process. As mentioned above, this is already handled by the web3 libraries in the background.
Learn more about [CCIP-Read, Offchain and L2 resolvers here](/resolvers/ccip-read).
#### Testing CCIP Read Support
To test if your integration properly implements CCIP Read, try resolving `test.offchaindemo.eth`. It should return the address `0x779981590E7Ccc0CFAe8040Ce7151324747cDb97`.
### DNS Names and Name Detection
ENS supports importing DNS names into ENS, allowing legacy domain names to work alongside .eth names. It's important that your application correctly also detects DNS names.
#### Common Mistake: Only Matching .eth
Many integrations check if the input ends with `.eth` in order to detect an ENS name:
```js
if (input.endsWith('.eth') {
// ...
}
```
This is **incorrect** because it excludes DNS names imported into ENS (like `ensfairy.xyz`).
#### Correct Pattern: Match All Valid Domains
Instead, your integration should treat any dot-separated string as a potential ENS name. For example, `a.co` should be treated as a potential ENS name.
```js
if (input.includes('.') && input.length > 2) {
// ...
}
```
This pattern correctly matches:
* `.eth` names like `vitalik.eth`
* DNS names like `ensfairy.xyz`
* Subdomains like `ses.fkey.id`
* Emoji domains like `🦇️🔊️🦇️🔊️🦇️🔊️.eth`
Learn more about [DNS integration here](/learn/dns). The full specification of name normalization is defined in [ENSIP-15](/ensip/15).
### Multichain Considerations
Even if your application only operates on an L2 like Base, ENS resolution always starts on Ethereum Mainnet. This means you need to configure a L1 client alongside your L2 chain.
#### Configuring Both L2 and Mainnet
Here's how to set up your application to use Base (or another L2) while ensuring ENS resolution works correctly by including Mainnet:
:::code-group
```ts [Viem]
import { createPublicClient, http, toCoinType } from 'viem'
import { base, mainnet } from 'viem/chains'
// Client for Base transactions
const baseClient = createPublicClient({
chain: base,
transport: http(),
})
// Client for ENS resolution on Mainnet
const mainnetClient = createPublicClient({
chain: mainnet,
transport: http(),
})
// Get the Base address for this ENS name
const baseAddress = await mainnetClient.getEnsAddress({
name: 'test.ses.eth',
coinType: toCoinType(base.id),
})
```
```tsx [Wagmi]
import { createConfig, http, useEnsAddress } from 'wagmi'
import { toCoinType } from 'viem'
import { base, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, mainnet], // Include both your L2 and Mainnet
transports: {
[base.id]: http(),
[mainnet.id]: http(),
},
})
function MyComponent() {
const { data: baseAddress } = useEnsAddress({
name: "test.ses.eth",
chainId: mainnet.id, // Always use mainnet for ENS resolution
coinType: toCoinType(base.id) // Always specify the coinType (chain)
});
}
```
```ts [Ethers]
import { ethers } from 'ethers'
// Provider for Base
const baseProvider = ethers.getDefaultProvider('base')
// Provider for ENS resolution on Mainnet
const mainnetProvider = ethers.getDefaultProvider('mainnet')
// Get the Base address for this ENS name
const resolver = await mainnetProvider.getResolver('test.ses.eth')
const baseAddress = await resolver?.getAddress(8453) // Base chain ID
```
:::
#### Chain-Specific Addresses
It is possible to configure a different address per chain for the same name:
* `test.ses.eth` resolves to `0x2B0F09F23193de2Fb66258a10886B9f06903276c` for Ethereum Mainnet, but
* `test.ses.eth` resolves to `0x7d3a48269416507E6d207a9449E7800971823Ffa` for Base.
From an application point of view it is important to be aware and always request the address for the correct chain, even on Ethereum Mainnet. All examples above explicitly set the `coinType` to Base, since they request the Base address for a given name.
:::warning
Omitting the coinType currently resolves the Ethereum Mainnet (or Sepolia on testnet) address. This address is not guaranteed to work on L2s. Always double check with your user when sending funds to such an address.
:::
## Listing a Users Names
In some cases you might want to show off all names that a user owns. Due to the nature of how the ENS Protocol works under the hood, this might be a slightly more difficult task than expected.
Fortunately, tooling has been developed to accommodate for this and to make it easier.
### Why not all names?
Not all ENS names exist onchain ([learn more about wildcard resolution](/ensip/10)), meaning we don't always know which names a user owns/controls.
The notable exception is [second-level](/terminology#first-layer) [.eth names](/registry/eth). Ownership of these names are onchain and indexable through scanning events on the appropriate smart contracts. Note that this does not necessarily mean address and text records associated with the name are onchain ([read more about offchain resolvers](/resolvers/ccip-read)).
### Guidelines
When using one of the methods described below it is important to keep in mind that you should always allow for a user to manually enter a name, as not all names are indexable.
It is generally recommended to allow users to input a name using an [input box](/web/design#2-resolving-input-fields) and to verify it resolves to the correct address upon user-completion.
### The Graph
The [ENS subgraph](/web/subgraph) indexes all events from relevant smart contracts and exposes them via a GraphQL endpoint. Note that addresses in filters must be lowercased.
ENSjs makes it easy to run common queries on the subgraph with strong type safety. Docs can be found [here](https://github.com/ensdomains/ensjs/tree/main/docs/subgraph).
```graphql
{
domains(where: { owner: "0x225f137127d9067788314bc7fcc1f36746a3c3b5" }) {
name
}
wrappedDomains(
where: { owner: "0x225f137127d9067788314bc7fcc1f36746a3c3b5" }
) {
name
}
}
```
import { EmbedLink } from '../../components/EmbedLink'
import { Card } from '../../components/ui/Card'
## Getting Started \[Integrate ENS into your dApp]
This section walks you through how to leverage the ENS open standards to improve the user experience of your app.
{/* TODO: Break the following examples into a component to fetch live data */}
vitalik.eth
➡️
mi pinxe lo crino tcati
0xd8d...6045
0xb8c...67d5
0x866...5eEE
0xd8d...6045
➡️
➡️
➡️
{['nick.eth', 'jefflau.eth', 'vitalik.eth'].map((name) => (
{name}
))}
### Quickstart
If you are looking to jumpstart your journey with ENS, or you are looking for a quick reference, visit the [Quickstart](/web/quickstart) page.
### Tools and Libraries
ENS is an integral part of the Ethereum ecosystem.
Fortunately, the open-source community is to the rescue, and almost all of the tools and libraries you use today support ENS.
To learn more check out the [tools & libraries section](/web/libraries).
### Avatars, Addresses & Records
Information about a name is fetched from its resolver. This can be done using pre-built features included in popular [web3 libraries](/web/libraries) (recommended), or by calling a resolver contract directly.
If you're interested in interacting with ENS resolvers, you might find the [Resolver Reference](/resolvers/interfaces) section helpful.
### Subnames
{['root', 'registrar', 'controller', 'resolver', 'registry'].map(
(subname, i) => (
{subname}
)
)}
.ens.eth
### Registration
{['nick', 'vitalik', 'matoken', 'jefflau', 'ens'].map((subname, i) => (
{subname}
))}
.eth
import { ConnectKits } from '../../components/ConnectKits'
import { Libraries } from '../../components/Libraries'
## Tools & Libraries \[Tools to help you interface with the ENS protocol]
### Quickstart Kits
There are a few plug-and-play kits that you can use to jumpstart your project. These kits will include everything you need to have users connect their wallet, have names showing, avatars, and more, right out of the box!
### Libraries
There are many ways to interface with the ENS Ethereum smart contracts, indexers, and metadata services. Whether you're building a dApp, a backend service, or interacting with ENS from your smart contract, there's a library out there to help you get started.
## Multichain \[L2 & Crosschain Resolution]
### ENS L2
The ENS Labs team recently announced our plans and roadmap for scaling ENS to the entire internet and beyond. You can read more [on our blog](https://blog.ens.domains/post/ensv2), [on X](https://twitter.com/ensdomains/status/1795440186513576318), and [the forums](https://discuss.ens.domains/t/technical-feedback-thread-for-ensv2/19233).
The roadmap involves migrating .eth registrations to a new system, in addition to improved support for existing L2 solutions.
You can find out more on the [changelog](/changelog).
### But isn't ENS on mainnet?
Yes, technically. The resolution process always starts on mainnet. There needs to be, one source of truth after all. However, the name
resolution process can branch off to other chains, offchain gateways and much more.
To read a more in-depth explanation of how resolution works, checkout the [section dedicated to the Resolution Process](/resolution/).
### My dapp is on X but I want ENS
The ENS Protocol can be used on/for any chain!
If you are building a non-mainnet dApp and want to use ENS names simply [add a Mainnet RPC to your Wagmi config](/web/libraries) and specify `chainId: 1` in your config like so:
```tsx
import { useAccount, useEnsAvatar, useEnsName } from 'wagmi'
const Name = () => {
const { data: ensName } = useEnsAddress({
name: 'nick.eth',
chainId: 1, // (1 = Ethereum, 11155111 = Sepolia) // [!code hl]
})
return {ensName || address}
}
```
And voila! You can now resolve ENS names anywhere! 🎉
## Naming Contracts \[Learn how to name your smart contracts with ENS]
While it's commonly known that regular user accounts can have [primary names](/web/reverse), it's less known that smart contracts can also have names.
In order for you to manage the primary name of your smart contract, you need to own the [reverse node](/terminology#reverse-node) for the contract address. There are several ways of doing this, depending on if you are actively developing your contract or if it is already deployed.
:::note
To enable reverse resolution, you must set both the reverse record and the ETH address to the contract’s deployed address.
:::
Skip to [Naming Tools](#naming-tools) for a frontend solution to naming your smart contracts.
### New Contracts
Depending on your use case, there are a few ways to set a smart contract's primary name.
If you want to be able to change the name later, you have two options:
* **(Recommended)** Make the contract [Ownable](https://docs.openzeppelin.com/contracts/5.x/access-control) and set yourself as the owner.
* Take ownership of the reverse node (`{address}.addr.reverse`) for the contract. This only works for contracts on Ethereum Mainnet.
The Ownable method is preferred since it doesn't require any additional code in many cases, and has the best Etherscan support.
For immutable smart contracts (without an owner), you can set the reverse record directly in the constructor at the time of deployment.
Let's look at a few examples.
#### Ownable (recommended)
:::note
An example of this is [ownable.contract.gtest.eth](https://etherscan.io/address/ownable.contract.gtest.eth#code)
:::
If you want to be able to change the name in the future, you can make your smart contract [Ownable](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable).
```solidity
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract MyContract is Ownable {
constructor(address initialOwner) Ownable(initialOwner) {}
}
```
[Reverse Registrars](/registry/reverse) on all supported chains understand the Ownable interface and will let the `owner()` of a contract set its reverse record without having to add any ENS-specific code.
Once this contract is deployed, call `setNameForAddr()` on a Reverse Registrar from your authorized owner account on the relevant chain. Note that the arguments are slightly different on L1 and L2s.
* The first address argument should be the address of your contract (both L1 and L2s)
* The second address argument should be the owner of your smart contract (only L1)
* The third address argument should be the `defaultResolver()` from the Reverse Registrar (only L1)
* The last argument is the ENS name to set it to (both L1 and L2s)
#### Set a name in the constructor
:::note
An example of this [contract.gtest.eth](https://etherscan.io/address/contract.gtest.eth#code)
:::
If you don't want to be able to change the name in the future, you can call `setName()` on a Reverse Registrar directly from your contract's constructor. Your contract would look something like this:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
interface IReverseRegistrar {
function setName(string memory name) external returns (bytes32);
}
contract MyContract {
/// @param reverseRegistrar The address of the Reverse Registrar contract on the relevant chain to use.
/// @param name The reverse name to set for this contract's address.
constructor(address reverseRegistrar, string memory name) {
IReverseRegistrar(reverseRegistrar).setName(name);
}
}
```
You can find the Reverse Registrar addresses [here](/registry/reverse#supported-chains).
#### ReverseClaimer.sol (L1 only)
:::note
While this method works perfectly at the ENS protocol level, Etherscan does not index the contract events correctly so it may not appear in their UI.
:::
This is a simple drop-in module that transfers ownership of the reverse node to an address of your choice, which can then update the reverse name at any time.
```solidity
import "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
import "@ensdomains/ens-contracts/contracts/reverseRegistrar/ReverseClaimer.sol";
contract MyContract is ReverseClaimer {
constructor (
ENS ens
) ReverseClaimer(ens, msg.sender) {}
}
```
When you deploy your contract, the deployer account (`msg.sender`) will be given ownership of the reverse node for that contract address. This gives you authorization to call `setName(node, newName)` on the latest public resolver ([resolver.ens.eth](https://etherscan.io/address/resolver.ens.eth)), where `node` is the reverse node for the contract address and `newName` is the name you want to set it to.
To find the reverse node for your contract address, you can use the following viem script:
```ts
import { namehash } from 'viem/ens'
const myContractAddress = '0x...' // replace with your contract address
const node = namehash(
`${myContractAddress.slice(2).toLowerCase()}.addr.reverse`
)
console.log(node)
```
### Existing Contracts
If your contract is already deployed you might still be able to set a name for it.
If your contract supports the [Ownable](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable) interface from OpenZeppelin, [read the section above](#ownable-recommended).
#### Safe, Multisig & DAO
If your contract is a Safe, Multisig, DAO or otherwise has the ability to execute arbitrary calldata, you can use a [Reverse Registrar](/registry/reverse) contract directly to set a name for it.
You might even be able to use the [ENS Manager App](https://app.ens.domains/) inside of your safe app to set a primary name.
### Naming Tools
:::warning
These are 3rd party tools and not officially supported by ENS Labs.
:::
[Enscribe](https://app.enscribe.xyz/) is a tool designed to simplify the process of naming smart contracts with ENS names. The application enables users to deploy new smart contracts with a primary name directly and easily name existing smart contracts.
Enscribe simplifies what is otherwise a multi-step, error-prone process by offering:
* Atomic contract deployment using `CREATE2`
* Naming `Ownable`, `ERC173` and `ReverseClaimer` contracts as described above
* ENS subname creation, forward resolution and reverse record assignment
* Naming of existing contracts, with an easy way to locate contracts that you've already deployed
Even if you don't own an ENS name, you can still utilize Enscribe's hosted ENS parent, `deployd.eth`, to create subnames like `my-app.deployd.eth` and set them as the primary name for your contract.
To learn more, refer to the [Enscribe Docs](https://www.enscribe.xyz/docs/).
import { AddressRecords } from '../../components/AddressRecords'
import { ConnectKits } from '../../components/ConnectKits'
import { EnsProfile } from '../../components/EnsProfile'
import { TextRecords } from '../../components/TextRecords'
import { Card } from '../../components/ui/Card'
## Quickstart
Hey there 👋, this is the quickstart guide. If you want to learn the process checkout [everything about ENS in dApps](/web/).
If you would rather just clone an example repository checkout these:
### Starter Kits
### Add to your dApp
This quickstart guide assumes you have a basic understanding of React.
#### Installation
```bash [Terminal]
npm install wagmi viem @tanstack/react-query
```
#### Showing the User Profile
The below codesnippet demonstrates how you can create a basic user profile section that shows the users ENS name and avatar.
The snippet leverages the [useAccount](https://wagmi.sh/react/hooks/useAccount), [useEnsName](https://wagmi.sh/react/hooks/useEnsName), and [useEnsAvatar](https://wagmi.sh/react/hooks/useEnsAvatar) hooks from wagmi.
```tsx
import { useAccount, useEnsAvatar, useEnsName } from 'wagmi'
export const EnsProfile = () => {
const { address } = useAccount()
const { data: name } = useEnsName({ address, chainId: 1 })
const { data: avatar } = useEnsAvatar({ name, chainId: 1 })
return (
{name}
{address}
)
}
```
:::info
ENS resolution always starts from L1 regardless of the chain the user is connected to. This is why we specify `chainId: 1` for Ethereum Mainnet in the wagmi hooks above.
:::
#### Text Record Lookups
:::code-group
```tsx [TextRecords.tsx]
// [!include ~/components/TextRecords.tsx]
```
```ts [useEnsTexts.ts]
// [!include ~/hooks/useEnsTexts.ts]
```
:::
#### Address Record Lookups
While ENS resolution always starts from Ethereum L1, you can store addresses for other chains in ENS records.
:::code-group
```tsx [AddressRecords.tsx]
// [!include ~/components/AddressRecords.tsx]
```
```ts [useEnsAddresses.ts]
// [!include ~/hooks/useEnsAddresses.ts]
```
:::
import { EmbedLink } from '../../components/EmbedLink'
import { TextRecords } from '../../components/TextRecords'
import { Card } from '../../components/ui/Card'
## Text Records
Text records are key-value pairs that can be used to store any arbitrary data associated with a name.
Think of this as a user's **digital backpack** utilized for the storage of preferences, public details, and more.
The most popular records have been standardised.
One example of a standardised record is the [avatar record](/web/avatars) which is used to store a user's profile picture.
### Getting Records
To fetch the record for a specific name, you can use one of the following methods:
:::code-group
```tsx [Wagmi]
// https://wagmi.sh/react/api/hooks/useEnsText
import { normalize } from 'viem/ens'
import { useEnsText } from 'wagmi'
export const MyProfile: FC<{ name: string }> = ({ name }) => {
const { data } = useEnsText({
name: normalize('nick.eth'),
key: 'com.twitter',
})
return (
Twitter: {data}
)
}
```
```tsx [Ethers]
// https://docs.ethers.org/v5/api/providers/provider/#EnsResolver
const provider = new ethers.providers.JsonRpcProvider()
const resolver = await provider.getResolver('nick.eth')
const twitter = await resolver.getText('com.twitter')
```
```tsx [Viem]
// https://viem.sh/docs/ens/actions/getEnsText.html
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { normalize } from 'viem/ens'
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
})
const ensText = await publicClient.getEnsText({
name: normalize('nick.eth'),
key: 'com.twitter',
})
```
```python [web3.py]
# https://web3py.readthedocs.io/en/latest/ens_overview.html#text-records
from ens.auto import ns
# set text
ns.set_text('alice.eth', 'url', 'https://example.com')
# get text
url = ns.get_text('alice.eth', 'url')
assert url == 'https://example.com'
```
```go [Go]
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/ethclient"
ens "github.com/wealdtech/go-ens/v3"
)
func main() {
client, _ := ethclient.Dial("https://rpc.ankr.com/eth")
domain, _ := ens.Normalize("nick.eth")
resolver, _ := ens.NewResolver(client, domain)
twitter, _ := resolver.Text("com.twitter")
fmt.Println("Twitter: ", twitter)
}
```
:::
### Types of Records
[ENSIP-5](/ensip/5) and [ENSIP-18](/ensip/18) specify two sets of records that are considered standardized. Below are some of the most commonly ones:
| Name | Usage | Reference | Example |
| ----------- | --------------------------------------- | --------------------- | ------------------------------------------ |
| avatar | [Avatar](/web/avatars) | [ENSIP-5](/ensip/5) | eip155:1/erc1155:0x495f... |
| description | Bio or description of the profile | [ENSIP-5](/ensip/5) | Lead developer of ENS |
| com.twitter | Twitter/X handle | [ENSIP-5](/ensip/5) | nicksdjohnson |
| com.github | GitHub handle | [ENSIP-5](/ensip/5) | arachnid |
| url | Website URL | [ENSIP-5](/ensip/5) | [https://ens.domains](https://ens.domains) |
| header | Image URL to be used as a header/banner | [ENSIP-18](/ensip/18) | ipfs\://QmNtHN7WE... |
#### Custom Records
While standardized records are expected to have the best ecosystem support, it's possible to store any key-value pair you desire. We generally recommend to stick to a pattern, or prefix things with your app or protocol (eg. `com.discord`, or `org.reddit`), as such to avoid collisions.
### Setting Records
Text records are controlled by the resolver associated with a given name. Read more about [interacting with a resolver](/resolvers/interacting).
import { EmbedLink } from '../../components/EmbedLink'
import { EnsProfile } from '../../components/EnsProfile'
import { Card } from '../../components/ui/Card'
## Address Lookup \[Learn how to resolve blockchain addresses from human-readable names with ENS.]
The ENS Protocol aims to make it easy to use Ethereum.
It does this by providing a simple way to use human-readable names instead of long machine-readable addresses.
### Getting the users Ethereum Address
The goal here is to take a name, such as `nick.eth`, and convert it to an address, such as `0x225f137127d9067788314bc7fcc1f36746a3c3B5`.
The simplest thing you can do is start with a name, and resolve it to an address.
We call this a "forward lookup".
Think of places where users can enter names, such as sending transactions, chatting, etc.
Note that all dot-separated strings should be treated as potential ENS names, since ENS supports [many TLDs](/dns/tlds). A common mistake is to only treat strings that end in `.eth` as ENS names.
:::code-group
```tsx [Wagmi]
import { useAccount, useEnsAvatar, useEnsName } from 'wagmi'
export const Name = () => {
const { data: ensName } = useEnsAddress({
address: 'nick.eth', // The name to lookup
chainId: 1, // The chain to start resolution on (Ethereum Mainnet or a testnet)
})
return {ensName || address}
}
```
```ts [Ethers.js]
const address = await provider.lookupAddress('nick.eth')
```
```ts [Viem]
import { normalize } from 'viem/ens'
import { publicClient } from './client'
const ensAddress = await publicClient.getEnsAddress({
name: normalize('nick.eth'),
})
```
```py [web3.py]
from ens.auto import ns
address = ns.address('alice.eth')
```
```rust [ethers-rs]
let provider = Provider::::try_from("https://mainnet.infura.io/v3/...")?;
let address = provider.lookup_address("nick.eth").await?;
```
```go [go-ens]
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/ethclient"
ens "github.com/wealdtech/go-ens/v3"
)
func main() {
client, _ := ethclient.Dial("https://rpc.ankr.com/eth")
domain, _ := ens.Normalize("nick.eth")
resolver, _ := ens.NewResolver(client, domain)
address, _ := resolver.Address()
fmt.Println("Address:", address.Hex())
}
```
```ts [ensjs]
import { createEnsPublicClient } from '@ensdomains/ensjs'
import { http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createEnsPublicClient({
chain: mainnet,
transport: http(),
})
const subgraphRecords = client.getSubgraphRecords({ name: 'ens.eth' })
const records = client.getRecords({
name: 'ens.eth',
records: {
coins: [...(subgraphRecords?.coins || []), 'BTC', 'ETH', 'ETC', 'SOL'],
texts: [
...(subgraphRecords?.texts || []),
'avatar',
'email',
'description',
],
contentHash: true,
abi: true,
},
})
```
```csharp [nethereum]
var ensService = new Nethereum.ENS.ENSService(web3)
var address = await ensService.ResolveAddressAsync('alice.eth')
```
:::
To learn what happens under the hood when you do a forward lookup, read the [resolution](/resolution) section.
### Multichain Addresses
ENS Names aren't just limited to storing Ethereum addresses.
Any blockchain address (BTC, LTC, SOL, etc.) can be queried by [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) coin type or a value derived from an EVM Chain ID (specified in [ENSIP-11](/ensip/11)). This includes Ethereum L2 networks such as OP Mainnet and Base.
For EVM Chains besides Ethereum Mainnet, always use its [ENSIP-11](/ensip/11) coin type, irrespective of being included in SLIP-0044 (like Ether Classic).
The standardization of multichain addresses was first introduced in [ENSIP-9](/ensip/9), and also [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304).
:::note
Regardless of the chain you're resolving an address for, ENS resolution always starts from Ethereum L1.
:::
:::code-group
```tsx [Wagmi]
// https://wagmi.sh/react/api/hooks/useEnsAddress
import { useEnsAddress } from 'wagmi'
import { arbitrum, base } from 'wagmi/chains'
import { toCoinType } from 'viem'
const name = 'gregskril.eth'
export const MyAddresses = () => {
// SLIP-0044 Coin Types (see ENSIP-9)
const { data: bitcoinAddr } = useEnsAddress({ name, coinType: 0, chainId: 1 })
const { data: solanaAddr } = useEnsAddress({
name,
coinType: 501,
chainId: 1,
})
// EVM Chain IDs (see ENSIP-11)
const { data: baseAddr } = useEnsAddress({
name,
coinType: toCoinType(base.id),
chainId: 1,
})
const { data: arbitrumAddr } = useEnsAddress({
name,
coinType: toCoinType(arbitrum.id),
chainId: 1,
})
return (
{JSON.stringify({ bitcoinAddr, solanaAddr, baseAddr, arbitrumAddr })}
)
}
```
```ts [Viem]
// https://viem.sh/docs/ens/actions/getEnsAddress.html#cointype-optional
const ensName = await publicClient.getEnsAddress({
name: normalize('wagmi-dev.eth'),
coinType: 0, // BTC
})
```
```ts [Ethers.js]
// https://docs.ethers.org/v5/api/providers/provider/#EnsResolver
const resolver = await provider.getResolver('ricmoo.eth')
const btcAddress = await resolver?.getAddress(0)
```
```py [web3.py (Python)]
# https://web3py.readthedocs.io/en/latest/ens_overview.html#multichain-address-resolution
from ens.auto import ns
eth_address = ns.address('alice.eth', coin_type=60)
```
:::
| Network | Coin Type |
| ------------ | ---------- |
| Bitcoin | 0 |
| Litecoin | 2 |
| Dogecoin | 3 |
| Ethereum | 60 |
| Solana | 501 |
| OP Mainnet | 2147483658 |
| Polygon | 2147483785 |
| Base | 2147492101 |
| Arbitrum One | 2147525809 |
... and many many more following [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) and [ENSIP-11](/ensip/11)
#### Decoding Address Hashes
ENS resolvers store all addresses in bytes, which may have to be encoded to their respective address formats. To do this, we recommend using the [@ensdomains/address-encoder](https://www.npmjs.com/package/@ensdomains/address-encoder) package.
### Advanced
import { EmbedLink } from '../../components/EmbedLink'
import { EnsProfile } from '../../components/EnsProfile'
import { QandA } from '../../components/QandA'
import { Badge } from '../../components/ui/Badge'
import { Card } from '../../components/ui/Card'
## Primary Names
:::info
Primary names are now supported on both Ethereum Mainnet and popular L2s (Base, OP Mainnet, Arbitrum One, Scroll, and Linea). This enables users to have an end-to-end experience with ENS on their preferred L2!
:::
A "primary name" is the result of a bi-directional relationship between an EVM address and a human-readable ENS name. The two directions are:
1. Name -> Address (forward resolution)
2. Address -> Name (reverse resolution)
The outcome of this relationship makes it safe for applications to display ENS names instead of EVM addresses, leading to a better user experience.
0xb8c...67d5
to
While forward resolution is configured in [Resolvers](/resolvers/quickstart), reverse records are typically set via smart contracts called Reverse Registrars which you can [read more about below](#setting-primary-names).
### L2 Primary Names
Before we dive into code examples, let's first understand why things work the way they do.
Prior to August 2025, ENS users had to make a transaction on Ethereum Mainnet (L1) to set a primary name. More specifically, they had to set a reverse record on the [Reverse Registrar](/registry/reverse) contract which was only available on L1.
Since a majority of user activity is now on L2s, we've added the ability to set a reverse record on the following Ethereum Rollups:
* Arbitrum
* Base
* Linea
* OP Mainnet
* Scroll
In addition to these chains, we've also added the ability to set a default reverse record on Ethereum Mainnet (L1) that serves as a fallback when no chain-specific primary name is set. This is the simplest way to set a universal primary name for users who have a wallet that supports all EVM chains.
While this may sound simple in theory, it's easy to get tripped on the details in practice. Let's look at an example.
#### Understanding the Verification Process
The key thing to understand is that the forward address *for a given chain* must match the reverse record on the respective chain's reverse registrar.
Say I own `nick.eth`. The name resolves to `0x1234...5678` because I've set the ETH address for that name. I call `setName("nick.eth")` on the Base reverse registrar, and I expect that my primary name is now `nick.eth` on Base. But that's actually not the case.
ENS names can resolve to [different addresses on different chains](/web/resolution), and since `nick.eth` in the example above has only specified an Ethereum Mainnet address, the verification process will fail. In order to fix this, I need to set the Base address for `nick.eth` which is on L1 in this case. This is done by calling the following function on the resolver for the name.
```solidity
setAddr(
namehash("nick.eth"), // node (see Name Processing)
convertEVMChainIdToCoinType(8453), // coinType (see ENSIP-11)
0x1234...5678 // the address to set
)
```
Now that `nick.eth` resolves to `0x1234...5678` via the Base cointype, and `name(0x1234...5678)` on the Base reverse registrar returns `nick.eth`, my primary name is fully set.
An alternative approach, which would be more efficient in this case, is to set the default EVM address for `nick.eth` on the latest [public resolver](/resolvers/public), and the default reverse record to `nick.eth` on the default reverse registrar. This would allow the name to resolve to the correct address on all chains.
### Getting a Primary Name
:::info
**Important**: After retrieving a name from reverse resolution, you **must** verify it by performing a forward resolution on that name to confirm it still resolves to the original address. This prevents spoofing or misconfiguration. If the addresses don't match, display the original address instead of the name. Most libraries will handle this for you.
:::
Looking up a users L1 primary name is very simple. In most web3 libraries (wagmi, viem, ethers, web3py, etc.), you will find a built-in function to do a lookup by address as shown below. In most cases, the library will handle the verification for you.
Remember that in all cases, ENS resolution always starts from Ethereum Mainnet.
:::code-group
```tsx [Wagmi]
// https://wagmi.sh/react/hooks/useEnsName
import { useEnsName } from 'wagmi'
import { mainnet } from 'wagmi/chains'
export const Name = () => {
const { data: name } = useEnsName({
address: '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5',
chainId: mainnet.id, // resolution always starts from L1
})
return Name: {name}
}
```
```ts [Ethers v5]
const address = '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5';
const name = await provider.lookupAddress(address);
// Always verify the forward resolution
if (name) {
const resolvedAddress = await provider.resolveName(name);
if (resolvedAddress !== address) {
// If verification fails, use the original address
return address;
}
}
```
```ts [Viem]
// https://viem.sh/docs/ens/actions/getEnsName.html
import { publicClient } from './client'
const ensName = await publicClient.getEnsName({
address: '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5',
})
```
```py [Web3.py]
# https://web3py.readthedocs.io/en/latest/ens_overview.html#get-the-ens-name-for-an-address
from ens.auto import ns
name = ns.name('0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5')
```
```go [Go]
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
ens "github.com/wealdtech/go-ens/v3"
)
func main() {
client, _ := ethclient.Dial("https://rpc.ankr.com/eth")
name, _ := ens.ReverseResolve(client, common.HexToAddress("0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5"))
fmt.Println("Name:", name)
// Name: nick.eth
}
```
:::
As of September 2025, Wagmi and Viem are the only libraries that support L2 Primary Names, and they can be used like this:
```tsx [Wagmi]
// https://wagmi.sh/react/hooks/useEnsName
import { toCoinType } from 'viem'
import { useEnsName } from 'wagmi'
import { base, mainnet } from 'wagmi/chains'
export const Name = () => {
const { data: name } = useEnsName({
address: '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5',
chainId: mainnet.id, // resolution always starts from L1
coinType: toCoinType(base.id), // [!code ++]
})
return Name: {name}
}
```
:::info
The official implementation of L2 Primary Names has a propogation period of up to 6 hours. If you're participating in a hackathon and need to resolve a name immediately, you can use [this implementation](https://github.com/ensdomains/frontend-template/blob/main/src/hooks/useEnsNameOptimistic.tsx) instead (not recommended for production use).
:::
🎉 And that's it! Now you can turn all your pages from this, to this:
0xb8c2...67d5
sent 0.1 ETH to
0xd8dA....6045
turns into
nick.eth
sent 0.1 ETH to
vitalik.eth
:::info
If you're a library developer looking to implement this functionality, we recommend using the [Universal Resolver](/resolvers/universal). It's a utility contract that greatly simplifies the process of resolving a name.
:::
### Setting Primary Names
Since primary names require two-way resolution, there are technically two steps to setting it up. Let's say that user `0x1234...5678` wants to set their primary name on Base to `nick.eth`.
First, the user would need to set the Base address for `nick.eth` to `0x1234...5678`. [Read more about multichain addresses](/web/resolution#multi-chain-addresses-btc-ltc-etc) to understand how this works.
Next, the user would need to set the reverse record for `0x1234...5678` to `nick.eth` in the Base Reverse Registrar. [Read more about reverse records](/registry/reverse) to understand how this works.
In order to avoid doing this manually for multiple chains, the user can set their default reverse record to `nick.eth` on the default reverse registrar, and their default EVM address to `0x1234...5678` on the latest [public resolver](/resolvers/public).
import { Card } from '../../components/ui/Card'
## Sign In With Ethereum (SIWE) \[A specification that leverages Ethereum signatures to perform authentication]
[ERC-4361](https://eips.ethereum.org/EIPS/eip-4361) defines a message format that a user signs using their keys to authenticate.
An example payload looks like the following:
```
localhost wants you to sign in with your Ethereum account:
0x225f137127d9067788314bc7fcc1f36746a3c3B5
This is a test statement.
URI: https://localhost/login
Version: 1
Chain ID: 1
Nonce: abcdef1234567890
Issued At: 2023-01-30T00:00:00.000Z
```
After authentication, an app may resolve the user's ENS name and profile, as well as other [onchain resources](https://docs.siwe.xyz/quickstart/retrieve-onchain-data).
### Resources
* [ERC-4361](https://eips.ethereum.org/EIPS/eip-4361)
* [Project website](https://siwe.xyz/)
* [Docs](https://docs.siwe.xyz/)
* [Libraries](https://docs.siwe.xyz/libraries/)
import { EmbedLink } from '../../components/EmbedLink'
import { Card } from '../../components/ui/Card'
## Subdomains
We believe that any place an address is used, a name should be able to be used instead.
The smart contracts you interact with have names, the deposit address for your favorite exchange has a name, your favorite DAO has a name, or maybe you use subnames to keep your wallets organized.
{['root', 'registrar', 'controller', 'resolver', 'registry'].map(
(subname, i) => (
{subname}
)
)}
.ens.eth
Luckily, the ENS Protocol has so much to offer for you to play with. There are a variety of ways you can give out subdomains to your apps users, set them up for yourself, or more.
If you are interested in naming smart contracts specifically, check out the [Naming Smart Contracts](/web/naming-contracts) page.
### Different Types of Subnames
ENS subnames come in a variety of forms: L1, L2, and offchain. From a technical perspective, L2 and offchain subnames are quite similar, but there are some tradeoffs to consider when choosing which one to use.
#### L1 Subnames
If you own a .eth name like nick.eth and go to create a subname in [the manager app](https://app.ens.domains/nick.eth?tab=subnames), you will be creating a subname on Ethereum Mainnet (L1) by default. This is the simplest way to create a subname with the least amount of moving pieces, but ultimately you are limited by the gas fees of Ethereum Mainnet.
If you'd like to issue L1 subnames to your users, read our guide on [creating an onchain subname registrar](/wrapper/creating-subname-registrar).
#### L2 Subnames
Developers can connect an ENS name on L1 with their own smart contracts on any L2 network, and [depending on the implementation](/learn/ccip-read), this could be fully trustless while significantly reducing the cost of issuing subnames.
[Durin](https://durin.dev/) is an opinionated approach to issuing ENS subnames on L2. It takes care of the L1 Resolver and offchain gateway parts of the [CCIP Read stack](/resolvers/ccip-read) for you, so you can focus on the business logic of your L2 smart contracts.
#### Offchain Subnames
Offchain subnames are exactly what they sound like - subnames that live in a centralized database on private servers, also powered by [CCIP Read](/resolvers/ccip-read). If your goal is to name a large amount of EVM addresses quickly and cheaply, with a low barrier to entry, offchain subnames might be for you. Often times, managing offchain names is as simple as interacting with a REST API.
From a user perspective, offchain subnames are hardly different than onchain subnames. They will not appear in wallet applications as NFTs like the previous two approaches, but they can resolve all the same data (addresses, text records, etc).
There are multiple API providers that offer programmatic access to offchain subnames such as [NameStone](https://namestone.com/), [Namespace](https://namespace.ninja/) and [JustaName](https://justaname.id/), along with open-source examples like [gskril/ens-offchain-registrar](https://github.com/gskril/ens-offchain-registrar).
## Subgraph
This is a page covering the graph's ENS subgraph. The ENS subgraph indexes onchain events of second-level .eth names, and DNS imported names.
It allows us to build a reasonable approximation of the ENS names an address owns.
To read more about why not all names (such as Offchain & Gasless Names) show up in the subgraph read the [listing names](/web/enumerate) page.
### The Graph
The Graph is a protocol for indexing and querying data from blockchains. There are multiple subgraphs that you can use to query information about ENS names.
These subgraphs are available for [mainnet](https://thegraph.com/explorer/subgraphs/5XqPmWe6gjyrJtFn9cLy237i4cWw2j9HcUJEXsP5qGtH), [sepolia](https://api.studio.thegraph.com/query/49574/enssepolia/version/latest) and [holesky](https://api.studio.thegraph.com/query/49574/ensholesky/version/latest).
:::note
Developers are welcome to use our rate limited API endpoints above for
testing, but it is highly encouraged to [sign up for a free account with
TheGraph](https://thegraph.com/studio/apikeys/) to get your own API key.
:::
### GraphQL Schema
The schema for the ENS subgraph is defined in [/schema.graphql](https://github.com/ensdomains/ens-subgraph/blob/master/schema.graphql).
### Use Cases
There are certain use cases where the graph is better for querying ENS specific information than through the resolution process.
One of such use-cases is querying which NFT names are owned by a specific address.
### Terminology
When using the subgraph, you may encounter `registrant` and `controller` fields. These were the old terminology for [Owner](/terminology#owner) and [Manager](/terminology#manager) respectively.
The `registrant` address is the owner of a name. It's the same value that will be returned from calling `ownerOf()` on the Base Registrar Controller (registrar.ens.eth). A registrant/owner may transfer ownership and assign a controller/manager.
The `controller` address is the manager of a name. It's the same value that will be returned from calling `owner()` on the ENS Registry (registry.ens.eth). A controller/manager may change the resolver of a name and set its records.
### Example Queries
:::note
Most of these example queries have equivalent functionality in [ENSjs](https://github.com/ensdomains/ensjs/tree/main/docs).
:::
You can explore the following examples interactively via the [Graph Explorer Playground](https://thegraph.com/explorer/subgraphs/5XqPmWe6gjyrJtFn9cLy237i4cWw2j9HcUJEXsP5qGtH?view=Playground\&chain=arbitrum-one)
#### Getting a list of names owned by an account
Ensure the address is lowercase
```graphql
query getDomainsForAccount {
domains(where: { owner: "0xa508c16666c5b8981fa46eb32784fccc01942a71" }) {
name
}
}
```
#### Getting the top domain for an account based on the longest registry
```graphql
query getDomainForAccount {
account(id: "0xa508c16666c5b8981fa46eb32784fccc01942a71") {
registrations(first: 1, orderBy: expiryDate, orderDirection: desc) {
domain {
name
}
}
id
}
}
```
returns
```json
{
"data": {
"account": {
"registrations": [
{
"domain": {
"name": "datanexus.eth"
}
}
],
"id": "0xa508c16666c5b8981fa46eb32784fccc01942a71"
}
}
}
```
#### Searching for a subdomain
```graphql
query getSubDomains($Account: String = "messari.eth") {
domains(where: { name: "messari.eth" }) {
name
id
subdomains(first: 10) {
name
}
subdomainCount
}
}
```
returns
```json
{
"data": {
"domains": [
{
"name": "messari.eth",
"id": "0x498ada62251a1227664ace8d97b0de2dcc6652ddf61e6fb5d3150f43ccf599e6",
"subdomains": [
{
"name": "subgraphs.messari.eth"
},
{
"name": "bd.messari.eth"
}
],
"subdomainCount": 2
}
]
}
}
```
#### Getting the expiry of an ENS domain
```graphql
query getDomainExp($Account: String = "paulieb.eth") {
registrations(
where: { domain_: { name: $Account } }
first: 1
orderBy: expiryDate
orderDirection: desc
) {
expiryDate
}
}
```
returns
```json
{
"data": {
"registrations": [
{
"expiryDate": "1714752524"
}
]
}
}
```
import { EmbedLink } from '../../components/EmbedLink'
import { Properties } from '../../components/Properties'
import { Repository } from '../../components/Repository'
import { Card } from '../../components/ui/Card'
## Offchain / L2 Resolvers
While ENS name resolution always starts from Ethereum Mainnet, it's possible to store almost all data associated with a name and its subdomains elsewhere. By leveraging [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) (CCIP Read) in a [Resolver](/resolvers/quickstart), developers can effectively defer resolution to an L2 or offchain API.
➡️
L1 Resolver
0xde90...4F31
➡️
➡️
### How does CCIP Read work?
CCIP Read (Cross Chain Interoperability Protocol) is a specification that defines a standard error smart contracts can throw if they want to trigger an offchain HTTP request.
```solidity
error OffchainLookup(
address sender,
string[] urls,
bytes callData,
bytes4 callbackFunction,
bytes extraData
)
```
When a contract reverts with the `OffchainLookup` error, clients (wagmi, viem, ethers, etc.) unwrap the error and handle it appropriately.
#### How does ENS use CCIP Read?
By [leveraging CCIP Read in a Resolver](/resolvers/writing#offchain-resolvers), developers can store name data beyond Ethereum Mainnet. A common use case is managing subnames on Layer 2 networks - for example, Coinbase allows users to register names like `jesse.base.eth` on Base, while the parent name `base.eth` remains on Ethereum Mainnet.
This creates a seamless experience for application developers - they can resolve names like `jesse.base.eth` exactly the same way they would resolve mainnet names, without needing to know which network the data is actually stored on. The use of CCIP Read in name resolution is completely transparent to users.

To resolve an offchain/L2 name using CCIP Read, the steps are as follows:
1. A user types "example.eth" into their wallet.
2. The wallet's client calls `resolve()` on example.eth's Resolver.
3. The Resolver reverts with an `OffchainLookup` error.
4. The client makes a request to the gateway URL specified in the error with the calldata from the error.
5. The gateway processes the request and returns data to the client. This is where the data is fetched from L2 or an offchain database.
6. The client calls the callback function specified in the error with the data returned from the gateway, which usually performs some sort of validation.
7. If the callback function validates the data, the client returns the result to the user.
While this might sound complex, it all happens under the hood and is completely transparent to application developers.
### Offchain Subname Example
An example of offchain ENS names powered by CCIP Read can be found at [offchain.ens.gregskril.com](https://offchain.ens.gregskril.com/).
The name [offchaindemo.eth](https://ens.app/offchaindemo.eth) with Resolver [0x35b9...E237](https://etherscan.io/address/0x35b920d4329C5797727Af8b15358b43509e5E237#code), reverts with `OffchainLookup` and directs the client to a Gateway URL.
The Gateway returns the relevant information from an offchain database, signed by a trusted private key which the smart contract can verify. This prevents a compromised Gateway from returning false information.
### Offchain vs L2 Resolvers
From the perspective of the L1 Resolver contract, the process of resolving an L2 name is exactly the same as resolving on offchain name. The differences come from the Gateway implementation and the Resolver's callback function.
For names that are stored offchain like the example above, the Gateway would read from a normal web2 database and the Resolver's callback function would simply verify the Gateway operator's signature.
For names that are stored on L2, the Gateway would make an RPC call to the relevant L2 and the Resolver's callback function would ideally verify the response by using the L2's state roon on L1 (this assumes knowledge of how L2's work).
To implement trustless L2 resolution, developers should use a solution like [Unruggable Gateways](https://gateway-docs.unruggable.com/).
### Writing a CCIP Read Gateway
A gateway is an offchain API endpoint that implements the [Gateway Interface](https://eips.ethereum.org/EIPS/eip-3668#gateway-interface) specified in EIP-3668. It is responsible for decoding the calldata from an `OffchainLookup` error and returning a relevant response.
#### Implementing the Endpoint
Your gateway must implement either a `GET` or `POST` endpoint with `{sender}` and `{data}` parameters, and be stored in the implementing smart contract. The `OffchainLookup` error will include this URL, which is how the client knows where to send the request.
:::code-group
```yaml [POST]
// POST if URL does not include '{data}' parameter
URL: https://example.com/gateway
Method: POST
Body:
sender: "0x..."
data: "0x..."
```
```yaml [GET]
// GET if URL includes '{data}' parameter
URL: https://example.com/gateway/{sender}/{data}.json
Method: GET
```
:::
Lowercased address of the contract reverting with the `OffchainLookup`
error.
0x prefixed bytes of the data passed to the `OffchainLookup` error.
#### Example Gateway Implementation
The most basic gateway implementation is to return a static value without doing any signing. We even have a library [@ensdomains/ccip-read-router](http://github.com/ensdomains/ccip-read-router) to abstract decoding the calldata.
#### Trust Assumptions
As explained in [Offchain vs L2 Resolvers](#offchain-vs-l2-resolvers), trust assumptions are up to the implementing developer and can range from fully trusted to full trustless.
The worst case scenario of a trusted implementation is that a malicious actor gains control of the gateway and can return false information.
The worst case scenario of a trustless implementation is that a malicious actor can take a gateway offline, but it can never return false data.
### Writing an Offchain/L2 Resolver
See [Writing a Resolver](/resolvers/writing#offchain-resolvers) for more information on how to implement a Resolver with CCIP Read.
### Testing your offchain names
To test your implementation, search the relevant name in the [ENS Manager App](https://app.ens.domains). Make sure that you've configured your test name to return a result for common data like an ETH address or common text records like `avatar` or `description`. If you set an arbitrary text record key like `test`, the manager app has no way of knowing that it exists.
## Interacting with a Resolver \[Set Addresses, Text Records, and more]
Some apps may want to allow for users to edit, update, or modify their name and its behaviour at a more advanced level.
This is possible by interacting with the resolver contract of a name directly.
### Checking Interface Support
Before you start sending transactions to users resolvers, you should check if they support the interface you want to use. This is done by calling the `supportsInterface` (see [EIP-165](https://eips.ethereum.org/EIPS/eip-165)) function on the resolver contract.
```solidity
function supportsInterface(bytes4 interfaceID) external pure returns (bool)
```
In order to ensure that resolvers we interact with are compatible with specific standards you can call the above function on contracts with an interfaceID and then check the boolean it returns.
Interface IDs are calculated according to solidity ABI and stored in a four-byte value.
### Updating a User's Record
If you want to help a user set their avatar, specify a preferred color scheme, or set any other record on their ENS name you can do so in specific cases.
First we need to check if the user's resolver supports the interface we want to use (see [setText](/resolvers/interfaces#0x10f13a8c)).
Afterwhich you can call the `setText()` function on the user's resolver contract.
:::code-group
```solidity [Solidity]
interface Resolver {
function setText(bytes32 node, string calldata key, string calldata value) external;
}
```
```typescript [ENSjs]
// https://github.com/ensdomains/ensjs/blob/main/docs/wallet/function.setRecords.md
import { addEnsContracts } from '@ensdomains/ensjs'
import { setRecords } from '@ensdomains/ensjs/wallet'
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
const wallet = createWalletClient({
chain: addEnsContracts(mainnet),
transport: custom(window.ethereum),
})
const hash = await setRecords(wallet, {
name: 'ens.eth',
coins: [
{
coin: 'ETH',
value: '0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7',
},
],
texts: [{ key: 'foo', value: 'bar' }],
resolverAddress: '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41',
})
// 0x...
```
:::
Note that only the [Manager](/terminology#manager) of a name can set records on the resolver. For unwrapped names, the manager can be found by calling `owner()` on the ENS Registry. For wrapped names, the manager can be found by calling `ownerOf()` on the Name Wrapper. You can find the contract addresses [here](/learn/deployments#mainnet).
### Update a User's Resolver
Overwriting a user's resolver involves overwriting the behaviour of their ENS name.
To change the resolver of a name, the Manager must call `setResolver()` on either the ENS Registry or the Name Wrapper, depending on whether the name is wrapped or not.
To figure out if a name is wrapped, call `owner()` on the ENS Registry. If this returns the address of the Name Wrapper, that indicates the name is wrapped and you should call `ownerOf()` on the Name Wrapper to get the effective owner of the name. You can find the contract addresses [here](/learn/deployments#mainnet).
:::code-group
```solidity [Solidity]
// Both the ENS Registry and the Name Wrapper implement this interface
interface ENS {
function setResolver(bytes32 node, address resolver) external;
}
```
```typescript [ENSjs]
// https://github.com/ensdomains/ensjs/blob/main/docs/wallet/function.setResolver.md
import { addEnsContracts } from '@ensdomains/ensjs'
import { setResolver } from '@ensdomains/ensjs/wallet'
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
const wallet = createWalletClient({
chain: addEnsContracts(mainnet),
transport: custom(window.ethereum),
})
const hash = await setResolver(wallet, {
name: 'ens.eth',
contract: 'registry',
resolverAddress: '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41',
})
// 0x...
```
:::
Please do not change the resolver for a user without their permission. Overwriting the resolver is a destructive action and will overwrite any existing resolution logic.
### Layer 2 & Offchain Resolvers
At the time of writing this the ecosystem around multichain and "writing" to layer 2 & offchain resolvers has yet to be standardized and is still under active development.
Please check back at a later date.
import { InterfaceDetails } from '../../components/InterfaceDetails'
import { resolver_methods } from '../../data/resolver'
## Resolver Interface Standards
This page is a collection of methods that a resolver MAY implement.
## Public Resolver
:::info
Find the address of the latest public resolver on the [deployments page](/learn/deployments).
:::
The public resolver is a general-purpose ENS resolver that is suitable for most user needs.
It permits the owner of a name to update their records, includes permissions, and stores its data on layer-1 ethereum.
Most ENS names registered through the ENS Manager will use the latest version of the public resolver by default.
Names that resolve to a supported public resolver are editable from within the ENS Manager.
If you'd like to take a peek under the hood you can view the [public resolver source code](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/resolvers/PublicResolver.sol) on GitHub.
### Features
The public resolver supports the following features:
* [EIP-137](https://eips.ethereum.org/EIPS/eip-137) - Contract address interface (`addr()`)
* [EIP-165](https://eips.ethereum.org/EIPS/eip-165) - Interface Detection (`supportsInterface()`)
* [EIP-181](https://eips.ethereum.org/EIPS/eip-181) - Reverse Resolution (`name()`)
* [EIP-205](https://eips.ethereum.org/EIPS/eip-205) - ABI Resolution for contracts (`ABI()`)
* [EIP-619](https://eips.ethereum.org/EIPS/eip-619) - SECP256k1 public keys (`pubkey()`)
* [EIP-634](https://eips.ethereum.org/EIPS/eip-634) - Text records (`text()`)
* [EIP-1577](https://eips.ethereum.org/EIPS/eip-1577) - Content hash resolution (`contenthash()`)
* [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304) - Multicoin support (`addr()`)
* [ENSIP-19](/ensip/19#default-address) - Default EVM address resolution
:::note
While the `PublicResolver` provides a default implementation, remember that custom resolvers exist. It is therefore not recommended to hardcode any addresses. To ensure a safe implementation, always use the `supportsInterface()` method to check for the existence of a specific interface. See [Interacting with a Resolver](/resolvers/interacting) for how to do this.
:::
### Default EVM Address Resolution
The latest public resolver supports the notion of a "default EVM address" for a name, represented by coinType `0`. If this is set, it will be returned by the `addr(bytes32 node, uint256 coinType)` function regardless of the `coinType` parameter, unless overridden by a more specific address.
This pairs nicely with the default reverse registrar when dealing with [L2 primary names](/web/reverse#l2-primary-names).
## Resolvers Quickstart
At the heart of every ENS name is its resolver. A resolver is a smart contract that implements a specific set of Resolver features (see [Resolver Interface](/resolvers/interfaces)).
The resolvers smart contract functions have control over the resolution process of a ["node"](/resolution/names#namehash) (a name or subdomain) and onwards (subdomains of itself).
### Basic Resolver
A naive but very plausible example of a resolver is the following.
```solidity
contract MyResolver {
function addr(bytes32 node) external pure returns (address) {
return 0x225f137127d9067788314bc7fcc1f36746a3c3B5;
}
function supportsInterface(
bytes4 interfaceID
) external pure returns (bool) {
return
interfaceID == this.addr.selector ||
interfaceID == this.supportsInterface.selector;
}
}
```
Notice how the above would always return the same address regardless of the name it is queried for.
If you want to [write your own resolver resolver](/resolvers/writing), or see the [interface reference](/resolvers/interfaces).
### Public Resolver
The default resolver for all names is the Public Resolver, a swiss army knife of resolvers, written by the ENS Labs team, feature-packed with everything your everyday user might need.
You can read more about the [Public Resolver](/resolvers/public).
### Interacting with a resolver
Depending on the resolver in charge of a name, certain frontend apps will be able to interact with them as well.
This means you can set your favourite records, upgrade your name to different logic, and more, from your dApp of choice.
Are you writing a dApp and want to build this? Checkout the [Interacting with a Resolver](/resolvers/interacting) section.
### Offchain Resolution
Although by default ENS resolution is done onchain. You can leverage the power of CCIP Read to redirect resolution to an offchain gateway.
More about writing a CCIP Read-enabled resolver [here](/resolvers/ccip-read).
import { InterfaceDetails } from '../../components/InterfaceDetails'
import { universalresolver_methods } from '../../data/universal-resolver'
## Universal Resolver \[A swiss army knife for resolution.]
### Overview
:::note
Application developers typically don't need to interact with the universal resolver directly. This guide is directed at lower level-library developers.
:::
The Universal Resolver is a smart contract that simplifies the process of resolving ENS names. It's the recommended way to implement ENS resolution in modern libraries.
Adopting the universal resolver will make the transition to [ENSv2](https://ens.domains/ensv2) seamless.
### Test Case
You might be asking yourself, "How do I know if my application is already using the Universal Resolver?"
To answer that question, we've prepared a test case. If you're using the Universal Resolver, your app should resolve `ur.gtest.eth` to `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`. If it's not, it will resolve to `0x1111111111111111111111111111111111111111`.
### Implementation Guide
The Universal Resolver should be treated as the canonical entrypoint to ENS for name resolution. `0xeEeEEEeE14D718C2B47D9923Deab1335E144EeEe` is the official deployment address on Ethereum Mainnet and testnets, which is a proxy contract owned by ENS DAO that will be upgraded to support [ENSv2](https://ens.domains/ensv2) in the future.
This guide assumes that your application already supports [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668).
#### Forward Resolution
To resolve one or more records for a name, use the `resolve(bytes name, bytes data)` method which returns `(bytes data, address resolver)`.
The `name` argument is the [DNS-encoded](/resolution/names#dns) version of the name. Make sure to [normalize](/resolution/names#normalize) the name first, as well! For example, given the name `My.Name.eth`:
1. Normalize:
* `My.Name.eth` -> `my.name.eth`
2. DNS Encode:
* `my.name.eth` -> `0x026d79046e616d650365746800`
The `data` argument is a single ABI-encoded call to the resolver for that name, or a multicall encoded via the following interface:
```solidity
interface IMulticallable {
function multicall(bytes[] calldata data) external view returns (bytes[] memory results);
}
```
For example, if you want to resolve the ETH address and description text record for `nick.eth`, your logic to generate the `data` parameter would look something like this:
```ts
import { namehash, normalize } from 'viem/ens'
import { encodeFunctionData, parseAbi } from 'viem/utils'
const simpleResolverAbi = parseAbi([
'function addr(bytes32 node) view returns (address)',
'function text(bytes32 node, string key) view returns (string)',
])
const multicallAbi = parseAbi([
'function multicall(bytes[] data) returns (bytes[] results)',
])
const name = normalize('nick.eth')
const node = namehash(name)
const resolverCalls = [
{
abi: simpleResolverAbi,
functionName: 'addr',
args: [node],
},
{
abi: simpleResolverAbi,
functionName: 'text',
args: [node, 'description'],
},
] as const
const data = encodeFunctionData({
abi: multicallAbi,
functionName: 'multicall',
args: [resolverCalls.map((call) => encodeFunctionData(call))],
})
```
Learn about [standard resolver methods](/resolvers/interfaces) for ABI-encoding that should be added to `simpleResolverAbi` in production.
The response you'll get back from `resolve` will have to be decoded against the multicall ABI, then further decoded against the base resolver ABI. This results in the ETH address and value of the description text record. The rest of the logic would look something like this:
```ts
import { createPublicClient, decodeFunctionResult, http, toHex } from 'viem'
import { mainnet } from 'viem/chains'
import { packetToBytes } from 'viem/ens'
// ...adding from the above example
const dnsEncodedName = toHex(packetToBytes(name))
const universalResolverAbi = parseAbi([
'error ResolverNotFound(bytes name)',
'error ResolverNotContract(bytes name, address resolver)',
'error UnsupportedResolverProfile(bytes4 selector)',
'error ResolverError(bytes errorData)',
'error ReverseAddressMismatch(string primary, bytes primaryAddress)',
'error HttpError(uint16 status, string message)',
'function resolve(bytes name, bytes data) view returns (bytes result, address resolver)',
'function reverse(bytes lookupAddress, uint256 coinType) view returns (string primary, address resolver, address reverseResolver)',
])
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
const resolveRes = await client.readContract({
abi: universalResolverAbi,
address: '0xeEeEEEeE14D718C2B47D9923Deab1335E144EeEe',
functionName: 'resolve',
args: [dnsEncodedName, data],
})
const decodedMulticall = decodeFunctionResult({
abi: multicallAbi,
functionName: 'multicall',
data: resolveRes[0],
})
const decodedRes = decodedMulticall.map((res, i) =>
decodeFunctionResult({
abi: simpleResolverAbi,
functionName: resolverCalls[i].functionName,
data: res,
})
)
// decodedRes[0] = "0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5"
// decodedRes[1] = "Lead developer of ENS & Ethereum Foundation alum. Certified rat tickler. he/him."
```
#### Reverse Resolution
To reverse-resolve an address to an ENS name (go from address to name), call the `reverse (bytes lookupAddress, uint256 coinType)` method which returns `(string primary, address resolver, address reverseResolver)`.
The `lookupAddress` argument is the Ethereum address of the account you want to fetch the primary name for. The `coinType` argument defines the chain you'd like to fetch the reverse record from. See [Multichain Addresses](/web/resolution#multichain-addresses) for more information about the `coinType` argument.
`reverse` internally checks that the name forward resolves to the address you're looking up, so your implementation doesn't need to do any additional checks and should be quite straightforward. It might look something like this:
```ts
import { createPublicClient, http, parseAbi } from 'viem'
import { mainnet } from 'viem/chains'
const address = '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5'
const universalResolverAbi = parseAbi([
'error ResolverNotFound(bytes name)',
'error ResolverNotContract(bytes name, address resolver)',
'error UnsupportedResolverProfile(bytes4 selector)',
'error ResolverError(bytes errorData)',
'error ReverseAddressMismatch(string primary, bytes primaryAddress)',
'error HttpError(uint16 status, string message)',
'function resolve(bytes name, bytes data) view returns (bytes result, address resolver)',
'function reverse(bytes lookupAddress, uint256 coinType) view returns (string primary, address resolver, address reverseResolver)',
])
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
const [primaryName] = await client.readContract({
abi: universalResolverAbi,
address: '0xeEeEEEeE14D718C2B47D9923Deab1335E144EeEe',
functionName: 'reverse',
args: [address, 60n],
})
// primaryName = "nick.eth"
```
#### Batch Gateways
The Universal Resolver utilizes a batch gateway to perform parallel [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) (CCIP-Read) requests and mitigate offchain server issues. [`CCIPBatcher.sol`](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ccipRead/CCIPBatcher.sol) is the recommended batch gateway client implementation. The protocol and server implementation is defined in [ENSIP-21: Batch Gateway Offchain Lookup Protocol](/ensip/21/) (BGOLP).
The latest batch gateways can be queried from the Universal Resolver via `batchGateways()` which returns `(string[] gateways)`.
1. **External Batch Gateway** `https://ccip-v3.ens.xyz` is a trustless service operated by ENS Labs which receives batch gateway requests, performs the supplied CCIP-Read requests in parallel, bundles up the responses or failures, and replies to the caller. This service acts like an open proxy. This mechanism functions in **ALL** clients that support CCIP-Read.
2. **Local Batch Gateway** `x-batch-gateway:true` is a [special-purpose URL](/ensip/21/) which notifies ENSIP-21 aware clients that the `OffchainLookup` is a BGOLP request and can be handled locally without using the **External Batch Gateway** service. The client follows the same process but the requests originate locally without an additional network hop to an external service. For unaware clients, the URL is ignored by the [Client Lookup Protocol](https://eips.ethereum.org/EIPS/eip-3668#client-lookup-protocol) in EIP-3668.
:::note
Currently only [viem](https://github.com/wevm/viem/blob/main/src/utils/ens/localBatchGatewayRequest.ts) supports ENSIP-21.
:::
## Writing a Resolver
Every ENS name has a resolver, which is responsible for resolving information about a name.
Resolvers are a core part of the ENS protocol. They give each name, represented as a ["node"](/resolution/names#namehash), the power to control the resolution process for itself and all of its subnames. Resolvers were originally standardized in [EIP 137](https://eips.ethereum.org/EIPS/eip-137), but have since received a few updates such as [EIP 181](https://eips.ethereum.org/EIPS/eip-181), [EIP 2304](https://eips.ethereum.org/EIPS/eip-2304), and [ENSIP-10](/ensip/10).
You can find the latest default resolver implementation, called the Public Resolver, on [GitHub](https://github.com/ensdomains/ens-contracts/blob/mainnet/contracts/resolvers/PublicResolver.sol) and [Etherscan](/learn/deployments).
### Resolver Interface
You can view an extended list of resolver methods [here](/resolvers/interfaces), however a simple interface might look something like this:
```solidity
interface IMyResolver {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
function addr(bytes32 node) external view returns (address payable);
function addr(bytes32 node, uint256 coinType) external view returns (bytes memory);
function contenthash(bytes32 node) external view returns (bytes memory);
function text(bytes32 node, string calldata key) external view returns (string memory);
function setAddr(bytes32 node, address addr) external;
function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;
function setContenthash(bytes32 node, bytes calldata hash) external;
function setText(bytes32 node, string calldata key, string calldata value) external;
}
```
### Wildcard Resolution
In [ENSIP-10](/ensip/10) a new `resolve()` method was added to the resolver interface to allow for wildcard resolution.
```solidity
interface IExtendedResolver {
/**
* @dev Performs ENS name resolution for the supplied name and resolution data.
* @param name The name to resolve, in normalised and DNS-encoded form.
* @param data The resolution data, as specified in ENSIP-10.
* @return The result of resolving the name.
*/
function resolve(
bytes memory name,
bytes memory data
) external view returns (bytes memory);
}
```
:::note
Don't forget to add `0x9061b923` to your [EIP-165](https://eips.ethereum.org/) `supportsInterface()` implementation.
:::
### Onchain Resolvers
By default, ENS names use the [Public Resolver](/resolvers/public) which stores all data onchain. An extremely basic resolver that stores a mapping of ENS names to addresses might look like this:
```solidity
contract OnchainResolver {
mapping(bytes32 node => address addr) public addr;
function setAddr(bytes32 node, address _addr) external {
addr[node] = _addr;
}
function supportsInterface(
bytes4 interfaceID
) external pure returns (bool) {
return
interfaceID == OnchainResolver.supportsInterface.selector ||
// function addr(bytes32 node) external view returns (address)
interfaceID == 0x3b3b57de;
}
}
```
:::note
This is not secure since it doesn't implement any form of access control for updating a name's address, and is only suitable for demonstration purposes.
:::
Since the mapping is stored internally, it costs gas for the owner of a name to update their address. This is great for a maximal decentralization, but is not always practical.
### Offchain Resolvers
An offchain resolver is a resolver that implements CCIP Read to defer a name's resolution to an HTTP server. This server can then load data from any source including offchain databases, APIs, or other blockchains. [Learn more about CCIP Read](/resolvers/ccip-read).
An equivalent offchain resolver to the above onchain example looks something like this:
```solidity
contract OffchainResolver {
string public url =
"https://docs.ens.domains/api/example/basic-gateway";
error OffchainLookup(
address sender,
string[] urls,
bytes callData,
bytes4 callbackFunction,
bytes extraData
);
function addr(bytes32 node) external view returns (address) {
bytes memory callData = abi.encodeWithSelector(
OffchainResolver.addr.selector,
node
);
string[] memory urls = new string[](1);
urls[0] = url;
revert OffchainLookup(
address(this),
urls,
callData,
OffchainResolver.addrCallback.selector,
abi.encode(callData, address(this))
);
}
function addrCallback(
bytes calldata response,
bytes calldata
) external pure returns (address) {
address _addr = abi.decode(response, (address));
return _addr;
}
function supportsInterface(
bytes4 interfaceID
) external pure returns (bool) {
return
interfaceID == OffchainResolver.supportsInterface.selector ||
interfaceID == OffchainResolver.addr.selector;
}
}
```
:::note
This is not secure since it doesn't implement any form of verification in the callback function, and is only suitable for demonstration purposes.
:::
Any ENS name that sets its resolver to this contract would resolve to whatever address the Gateway returns, which can be changed at any time offchain for free. See the [gateway code here](https://github.com/ensdomains/docs/blob/master/functions/api/example/basic-gateway.ts).
For the same functionality to work with subnames, you'd need to implement the `resolve()` method from ENSIP-10. A feature-complete example can be found [here](https://github.com/ensdomains/ccip-tools/blob/master/contracts/OffchainResolver.sol), and easily deployed via [https://ccip-tools.pages.dev](https://ccip-tools.pages.dev).
import { Card } from '../../components/ui/Card'
## Resolution
The process by which we load information about a name is called resolution. It's a simple process, but it's important to understand.
Here is a diagram of some of the contracts involved when resolving a name.
The resolution process involves multiple parts. Most notably the [Registry](/registry/ens), multiple Registrars ([ETH Registrar](/registry/eth), [DNS Registrar](/registry/dns), [Reverse Registrar](/registry/reverse), etc)
and the concept of a [Resolver](/resolvers/quickstart).
### How to resolve
Here is a little peek at what happens under the hood of your favourite library when you do a name lookup.
#### 1. Find the Resolver
Every name has a "resolver". A resolver is simply a contract that implements the [resolver specification](/resolvers/quickstart) and can be queried for information about a name.
To get the resolver responsible for a name, you can query [The Registry](/registry/ens) for the `resolver` of a name.
:::code-group
```solidity [Solidity]
ENS.resolver(bytes32 node) view returns (address)
```
```tsx [Wagmi]
// https://wagmi.sh/react/api/hooks/useEnsResolver
import { normalize } from 'viem/ens'
import { useEnsResolver } from 'wagmi'
export const MyResolver = () => {
const { data: myResolver } = useEnsResolver({
name: normalize('nick.eth'), // The name to lookup
})
return {myResolver}
}
```
```ts [Ethers]
const resolver = await provider.getResolver('nick.eth')
```
```ts [viem]
// https://viem.sh/docs/ens/actions/getEnsResolver.html
import { normalize } from 'viem/ens'
import { publicClient } from './client'
const ensResolver = await publicClient.getEnsResolver({
name: normalize('nick.eth'),
})
```
```py [Web3.py]
# https://web3py.readthedocs.io/en/latest/ens_overview.html#working-with-resolvers
from ens.auto import ns
resolver = ns.resolver('alice.eth')
```
:::
To verify which specifications are implemented by a resolver, you can call the `supportsInterface(bytes4 interfaceID)` on the resolver with the interfaceID you would like to test for.
#### 2. Query the Resolver
Now you have found the resolver responsible for the name in question, you can query it for the information you are interested in.
There are many ways you can query the resolver, `addr()` `text()` `contenthash()` `abi()` etc.
If the resolver supports text records, you can call `text()` to get that text record for the name.
More about loading information from a resolver can be found [here](/resolvers/interacting).
##### Wildcard Resolution
In addition, all of the above functions can be sent to the `resolve()` function, specified in [ENSIP-10](/ensip/10).
This allows for not only multicall functionality, but also easier implementation of EIP-3668, and more.
Most clients & many resolvers utilize wildcard resolution as their primary form of resolution.
### Reverse Resolution
Due to the modular nature of how ENS is designed, it is also possible to lookup the "primary name" of an address.
This process actually uses forward resolution under the hood, you read that right - its just forwards resolution.
To look up the primary name of a given address, you must do a resolver lookup for `addr.reverse` and then query the `name()` field on the resolver.
This name field returns the "preferred" name for the address. You should always follow up a reverse lookup with a forward lookup to verify that the resulting name points back to the original address. If the address doesn't match, display the address rather than the reversed name.
```solidity
/// @dev The starting point for all ENS resolution is the Registry
ENS ens = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e;
/// @dev The node hash for "addr.reverse"
bytes32 ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
/// @dev Returns the node hash for a given account's reverse records, `{address}.addr.reverse`
function reverseNode(address addr) public pure returns (bytes32) {
return keccak256(
abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr))
);
}
/// @dev Get the reverse record for an address
function getReverseRecord(address addr) public view returns (string) {
bytes32 reverseNodeHash = reverseNode(addr);
// Get the resolver for the reverse node
Resolver resolver = ens.resolver(reverseNodeHash);
// Get the address's preferred name
return resolver.name(reverseNodeHash);
}
```
:::info
**Important**: The client MUST perform a forward resolution on a user's reverse record to verify the address matches the one you are looking up. The example above does not perform this verification.
:::
Please note that many libraries already have functionality to do this. You can read more about it in the [Getting a Primary Name](/web/reverse) section.
import { NameProcessing } from '../../components/NameProcessing'
import { Card } from '../../components/ui/Card'
## Name Processing \[Normalization and recommendations for how to handle names]
When interacting with the ENS smart contracts directly, it is important to note that names are not stored as strings. [Libraries](/web/libraries) handle name encoding for you when implementing basic name resolution, but you may need to handle the encoding yourself when interacting with the protocol directly.
Below is an interactive tool that shows all the different formats of names and how to implement them.
### Name Normalization
Normalization is the process of canonicalizing a name before running it through the [Namehash](#namehash) algorithm. It is important to always normalize all input, because even one little difference (like a capital vs lowercase character) will cause the namehash to be completely different.
For example, `NaMe.EtH` normalizes to `name.eth`. This ensures that the correct Registry node is used, no matter how the user types in the name.
ENS names are validated and normalized using the [ENSIP-15](/ensip/15) normalization algorithm.
Previously, [UTS-46](https://www.unicode.org/reports/tr46/) was used, but that is insufficient for emoji sequences. Correct emoji processing is only possible with [UTS-51](https://www.unicode.org/reports/tr51/). The [ENSIP-15](/ensip/15) normalization algorithm draws from those older Unicode standards, but also adds many other validation rules to prevent common spoofing techniques like inserting zero-width characters, or using confusable (look-alike) characters. See here for additional discussion on this: [Homogylphs](https://support.ens.domains/en/articles/7901658-homoglyphs)
A standard implementation of the algorithm is available at [@adraffy/ens-normalize](https://github.com/adraffy/ens-normalize.js). This library is used under the hood in [viem](https://viem.sh/docs/ens/utilities/normalize), [ENSjs](https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/utils/normalise.ts#L27), and others.
```js
import { normalize } from 'viem/ens'
// Uses @adraffy/ens-normalize under the hood
const normalized = normalize('RaFFY🚴♂️.eTh')
// => "raffy🚴♂.eth"
```
If the name was not able to be normalized, then that method will throw an error. A name is valid if it is able to be normalized.
### Namehash
:::note
You **MUST** [normalize](#normalize) a name before you attempt to create a namehash! If you don't, then the hash you get may be incorrect. Some libraries like [ensjs](https://github.com/ensdomains/ensjs) will automatically do this for you.
:::
In the core ENS registry, names are stored as a hash instead of the raw string to optimize for gas, performance, and more. This hashed value is typically referred to as a `node`. The node is a hex-encoded 32-byte value that is derived from the name using the `namehash` algorithm defined in [ENSIP-1](/ensip/1).
Namehash is a recursive algorithm that hashes each part of the name, then hashes the results together. Because recursive functions aren't very efficient in Solidity, it's usually best to derive the namehash offchain and pass to it a contract. Luckily, there are libraries that do this for us.
:::code-group
```tsx [Viem]
// https://viem.sh/docs/ens/utilities/namehash
import { namehash, normalize } from 'viem/ens'
const normalizedName = normalize('name.eth')
const node = namehash(normalizedName)
```
```ts [Ethers.js]
// https://docs.ethers.org/v6/api/hashing/#namehash
import { ensNormalize, namehash } from 'ethers/hash'
const normalizedName = ensNormalize('name.eth')
const node = namehash(normalizedName)
```
```python [ens-namehash-py]
# https://github.com/ConsenSysMesh/ens-namehash-py
from namehash import namehash
node = namehash('name.eth')
```
```rust [namehash-rust]
// https://github.com/InstateDev/namehash-rust
fn main() {
let node = &namehash("name.eth");
let s = hex::encode(&node);
}
```
```solidity [Solidity]
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@ensdomains/ens-contracts/contracts/utils/NameEncoder.sol";
contract MyContract {
function namehash(string calldata name) public pure returns (bytes32) {
(, bytes32 node) = NameEncoder.dnsEncodeName(name);
return node;
}
}
```
:::
#### Algorithm
The specification for the namehash algorithm was originally defined in [EIP-137](https://eips.ethereum.org/EIPS/eip-137#namehash-algorithm) (same as [ENSIP-1](/ensip/1)).
It's a recursive algorithm that works its way down until you hit the root domain. For `ens.eth`, the algorithm works like so:
```
namehash('ens.eth') = keccak256(namehash('eth') + labelhash('ens'))
namehash('eth') = keccak256(namehash('') + labelhash('eth'))
namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000
```
That last line is a special case: The namehash for an empty string (representing the root domain) is 32 null bytes.
If you plug everything in above, you'll end up with the final namehash value:
```
namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000
labelhash('eth') = keccak256('eth') = 0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0
namehash('eth') = keccak256(namehash('') + labelhash('eth')) = keccak256(0x00000000000000000000000000000000000000000000000000000000000000004f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0) = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae
labelhash('ens') = keccak256('ens') = 0x5cee339e13375638553bdf5a6e36ba80fb9f6a4f0783680884d92b558aa471da
namehash('ens.eth') = keccak256(namehash('eth') + labelhash('ens')) = keccak256(0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae5cee339e13375638553bdf5a6e36ba80fb9f6a4f0783680884d92b558aa471da) = 0x4e34d3a81dc3a20f71bbdf2160492ddaa17ee7e5523757d47153379c13cb46df
```
This brings us to the final node for ens.eth: `0x4e34d3a81dc3a20f71bbdf2160492ddaa17ee7e5523757d47153379c13cb46df`
#### Reverse Nodes
The [Reverse Node](/terminology#reverse-node) is a node in the Registry that can be claimed for any Ethereum account. The name this node represents is `[addr].addr.reverse`, where `[addr]` is the Ethereum public address (lowercase, without the "0x"). These reverse nodes are typically used to set a [Primary Name](#primary-name) for an account.
To generate the namehash for a reverse node:
* Take the input address and:
* Remove the "0x" at the beginning
* Convert all characters to lowercase
* Add `.addr.reverse` to the end
* Run this result through the namehash algorithm
For example, for address `0x481f50a5BdcCC0bc4322C4dca04301433dED50f0`, the name for the reverse node is:
* `481f50a5bdccc0bc4322c4dca04301433ded50f0.addr.reverse`
And the resulting namehash for the reverse node is:
* `0x58354ffdde6ac279f3a058aafbeeb14059bcb323a248fb338ee41f95fa544c86`
### Labelhash
:::note
You **MUST** [normalize](#normalize) a name before you attempt to create a labelhash! If you don't, then the hash you get may be incorrect.
:::
Labelhash is the Keccak-256 hash of a single label (e.g. `name` in `name.eth`), used in places that don't require the full name.
One example of where labelhash is used is in the [BaseRegistar](/registry/eth), since it only supports registering 2LDs (second-level domains, like `name.eth`) and not 3LDs+ (e.g. `sub.name.eth`). The token ID of a second-level .eth name in the BaseRegistar is the uint256 of the labelhash.
:::code-group
```tsx [Viem]
// https://viem.sh/docs/ens/utilities/labelhash
import { labelhash, normalize } from 'viem/ens'
const normalizedLabel = normalize('label')
const hash = labelhash(normalizedLabel)
```
```tsx [Ethers]
// https://docs.ethers.org/v6/api/crypto/#keccak256
import { keccak256 } from 'ethers/crypto'
import { ensNormalize } from 'ethers/hash'
import { toUtf8Bytes } from 'ethers/utils'
const normalizedLabel = ensNormalize('label')
const labelhash = keccak256(toUtf8Bytes(normalizedLabel))
```
```solidity [Solidity]
string constant label = "label";
bytes32 constant labelhash = keccak256(bytes(label));
```
:::
### DNS Encoding
:::note
You **MUST** [normalize](#normalize) a name before you DNS-encode it! If you
don't, then when you pass those DNS-encoded bytes into a contract method,
incorrect namehashes/labelhashes may be derived.
:::
This is a binary format for domain names, which encodes the length of each label along with the label itself. It is used by some of the ENS contracts, such as when wrapping names in the [Name Wrapper](/wrapper/overview) or resolving data with [ENSIP-10](/ensip/10).
:::code-group
```tsx [Viem]
import { packetToBytes } from 'viem/ens'
import { toHex } from 'viem/utils'
const name = 'name.eth'
const dnsEncodedName = toHex(packetToBytes(name))
// 0x046e616d650365746800
```
```tsx [Ethers]
// https://docs.ethers.org/v6/api/hashing/#dnsEncode
import { dnsEncode } from 'ethers/lib/utils'
const dnsEncodedName = dnsEncode('name.eth')
```
```solidity [Solidity]
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@ensdomains/ens-contracts/contracts/utils/NameEncoder.sol";
contract MyContract {
function dnsEncode(string calldata name) public pure returns (bytes memory) {
(bytes memory dnsEncodedName,) = NameEncoder.dnsEncodeName(name);
return dnsEncodedName;
}
}
```
:::
#### Decoding
To decode a DNS-encoded name, you can use `bytesToPacket()` from ENSjs.
```tsx
import { bytesToPacket } from '@ensdomains/ensjs/utils'
import { hexToBytes } from 'viem/utils'
const dnsEncodedName = '0x046e616d650365746800'
const name = bytesToPacket(hexToBytes(dnsEncodedName))
// name.eth
```
#### Algorithm
To DNS-encode a name, first split the name into labels (delimited by `.`). Then for each label from left-to-right:
* One byte to denote the length of the label
* The UTF-8 encoded bytes for the label
* If this is the last label, then one final NUL (`0x00`) byte.
For example, to DNS-encode `my.name.eth`:
* `0x02` (length of the label "my")
* `0x6D79` (UTF-8 encoded bytes of "my")
* `0x04` (length of the label "name")
* `0x6E616D65` (UTF-8 encoded bytes of "name")
* `0x03` (length of the label "eth")
* `0x657468` (UTF-8 encoded bytes of "eth")
* `0x00` (end of name marker)
Final result: `0x026d79046e616d650365746800`
:::note
Since the length of each label is stored in a single byte, that means that with this DNS-encoding scheme, each label is limited to being 255 UTF-8 encoded bytes in length. Because of this, names with longer labels cannot be wrapped in the [Name Wrapper](/wrapper/overview), as that contract uses the DNS-encoded name.
:::
## DNS Registrar
In [DNS on ENS](/learn/dns) we learned how ENS aims to extend the functionality of the DNS.
On this page we will explore the implementation of DNSSEC, the DNSRegistrar, and the building blocks for gasless DNSSEC.
:::note
Not all top level domains support DNSSEC, and some might have custom ENS
implementations. Please refer to the [TLD List](/dns/tlds) for TLD-specific
information.
:::
### DNSSEC
DNSSEC (Domain Name System Security Extensions) is an added layer of security on top of DNS that allows for cryptographic verification of records. It establishes a chain of trust from the root key (which is signed by ICANN) down to each key.
All ENS-enabled DNS names are required to use DNSSEC, and the [DNSSECOracle](https://github.com/ensdomains/ens-contracts/tree/master/contracts/dnssec-oracle) is responsible for verifying the signatures.
#### Claiming a Name Onchain
Since 2021, it has been possible to [import a DNS name](/learn/dns#importing-a-dns-name) and use that as an ENS name. This process involves enabling DNSSEC, setting a specific TXT record, and submitting a proof to the [DNSRegistrar](https://github.com/ensdomains/ens-contracts/tree/master/contracts/dnsregistrar) smart contract.
Expect your `TXT` record to look something like this:
```
TXT _ens a=;
```
You can learn more about [how to import a DNS name](/learn/dns#importing-a-dns-name) in the DNS section, or see how to [programmatically complete these steps](#programming-dnssec-proofs).
There is no ENS protocol fee to import a DNS name, but it requires a large amount of gas (up to a few million) to submit the proof onchain. Continue reading to learn how this has been mitigated.
### Offchain Verification (Gasless)
[EP 5.1](/dao/proposals/5.1) introduced a new DNSSECOracle and DNSRegistrar which makes it possible to perform DNSSEC verification at query time, enabling truly free usage of DNS names in ENS. We call this "gasless DNSSEC".
It works by enabling [wildcard resolution](/ensip/10) at the DNS TLD level. During the [name resolution process](/resolution), if a name doesn't already exist onchain but has been configured for usage in ENS, the DNSSEC proof will be fetched offchain via [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668) and then verified onchain with the same DNSSECOracle mentioned above.
#### Import a DNS name gaslessly
To configure a DNS name for usage in ENS, simply add a `TXT` record with the following format:
```
TXT @ ENS1 <resolver-address>
```
The `resolver-address` implementation is customizable just like any other ENS resolver. To get started quickly, a special ExtendedDNSResolver has been deployed which allows users to specify an ETH address that the name should resolve to within the same `TXT` record. To use this setup, simply add a record with the following format:
```
TXT @ ENS1 <extended-resolver-address> <eth-address>
TXT @ ENS1 0x238A8F792dFA6033814B18618aD4100654aeef01 0x225f137127d9067788314bc7fcc1f36746a3c3B5
```
### Other
#### TLD Ownership
You can lookup the `owner` of any TLD by calling the `Registry.owner(bytes32 node)` function.
If at least one domain has been imported for this TLD (via the onchain method), the owner will be either the `DNSRegistrar` or a smart contract controlled by the respective registry operator.
If a TLD has not yet been activated, the `owner` will return `0x0` and it may require one user to import a name onchain to activate the TLD. See the [supported TLD list](/dns/tlds) for more info.
#### Programming DNSSEC Proofs
To help you interact with DNSSEC data and the DNSRegistrar, we provide a few libraries.
* [DNSProvejs](https://github.com/ensdomains/dnsprovejs) = A library for querying and validating DNSSEC data from DNS
* [ENSjs](https://github.com/ensdomains/ensjs) = A library for interacting with ENS smart contracts
##### Retrieving a proof
```ts
import { addEnsContracts } from '@ensdomains/ensjs'
import { getDnsImportData } from '@ensdomains/ensjs/dns'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createPublicClient({
chain: addEnsContracts(mainnet),
transport: http(),
})
const dnsImportData = await getDnsImportData(client, {
name: 'example.com',
})
```
##### Submitting the proof to the DNSRegistrar
```ts
import { addEnsContracts } from '@ensdomains/ensjs'
import { getDnsImportData, importDnsName } from '@ensdomains/ensjs/dns'
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { mainnet } from 'viem/chains'
const mainnetWithEns = addEnsContracts(mainnet)
const client = createPublicClient({
chain: mainnetWithEns,
transport: http(),
})
const wallet = createWalletClient({
chain: mainnetWithEns,
transport: custom(window.ethereum),
})
const dnsImportData = await getDnsImportData(client, {
name: 'example.com',
})
await importDnsName(wallet, {
name: 'example.com',
dnsImportData,
})
```
### Other functions
```ts
// Get the list of suffixes
DNSRegistrar.suffixes
// Get Oracle
DNSRegistrar.oracle
```
```ts
DNSRegistrar.claim(bytes name, bytes proof)
DNSRegistrar.proveAndClaim(bytes name, tuple[] input, bytes proof)
DNSRegistrar.proveAndClaimWithResolver(bytes name, tuple[] input, bytes proof, address resolver, address addr)
```
## The Registry \[Root Registry of the Ethereum Name Service]
The ENS registry is the core contract that lies at the heart of ENS resolution. All ENS lookups start by querying the registry. The registry maintains a list of domains, recording the owner, resolver, and TTL for each, and allows the owner of a domain to make changes to that data.
The ENS registry is specified in [EIP 137](https://eips.ethereum.org/EIPS/eip-137).
### Why Registries?
Top-Level Domains (TLDs), like `.eth`, `.com`, and `.test`, are owned by smart contracts called registrars , which specify rules governing the allocation of their names.
Anyone may, by following the rules imposed by these registrar contracts, obtain ownership of a domain for their own use.
| TLD | Registrar Contract |
| ------------------- | -------------------------------------- |
| `[root]` | [The Registry](/registry/ens) |
| `.eth` | [ETH Registry](/registry/eth) |
| `.com`, `.xyz`, etc | [DNS Registrar](/registry/dns) |
| `.addr.reverse` | [Reverse Registrar](/registry/reverse) |
### Who owns the root Registry?
The [ENS Registry](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) is owned by the [ENS Root](https://etherscan.io/address/0xaB528d626EC275E3faD363fF1393A41F581c5897) which is owned by the [ENS DAO Wallet](https://etherscan.io/address/0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7).
To verify this you can run the `owner` function on the registry & root contracts.
### Other Functions
```ts
// Get Owner
ENS.owner(bytes32 node) view returns (address)
// Get Resolver
ENS.resolver(bytes32 node) view returns (address)
// Get TTL
ENS.ttl(bytes32 node) view returns (uint64)
// Get Approval
ENS.isApprovedForAll(address owner, address operator) view returns (bool)
// Check Record Existence
ENS.recordExists(bytes32 node) view returns (bool)
```
```ts
// Set Owner (only callable by current owner)
ENS.setOwner(bytes32 node, address owner)
// Set Resolver
ENS.setResolver(bytes32 node, address resolver)
// Set TTL
ENS.setTTL(bytes32 node, uint64 ttl)
// Set Subnode Owner
ENS.setSubnodeOwner(bytes32 node, bytes32 label, address owner)
// Set Multiple (convenience function (setResolver, setTTL, setOwner))
ENS.setRecord(bytes32 node, address owner, address resolver, uint64 ttl)
// Set Multiple Subnode
ENS.setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl)
// Set Approval
ENS.setApprovalForAll(address operator, bool approved)
```
Events
```ts
// Transfer Event
event Transfer(bytes32 indexed node, address owner)
// New Resolver Event
event NewResolver(bytes32 indexed node, address resolver)
// New TTL Event
event NewTTL(bytes32 indexed node, uint64 ttl)
// New Owner Event
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner)
```
import { FiBookOpen, FiClock, FiHash } from 'react-icons/fi'
import { Card } from '../../components/ui/Card'
## ETH Registrar \[Smart contracts responsible for the ".eth" TLD]
The ETH Registrar is a special registrar. It allows for trustless onchain name registration and is in charge of the ".eth" TLD.
### BaseRegistrar vs Controller
The ETH Registrar is split into two contracts. The [BaseRegistrar](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/BaseRegistrarImplementation.sol) and the [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol).
The BaseRegistrar is responsible for name ownership, transfers, etc (ownership related), while the Controller is responsible for registration & renewal (pricing related). This separation is done to reduce the attack surface of the registrar, and provides users with the guarantees of continued ownership of a name so long as the registrar is in place.
#### Controllers
The [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) is the main controller for the ETH Registrar, and provides a straightforward registration and renewal mechanism.
### Pricing Structure
The ETH Registrar charges a fee for registration.
This fee is paid in ETH and is set to prevent spamming the registrar.
Any protocol fees are sent to the ENS Treasury.
#### Pricing Oracle
Initially, a single pricing oracle was deployed, the [StablePriceOracle](https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StablePriceOracle.sol).
This contract has owner-set prices for each name length (1, 2, 3, 4, 5 or more).
Users do not have to interact with this oracle directly, as the controller provides functionality to determine the pricing for a registration or renewal.
#### 3, 4, and 5 Letter Names
The ETH Registrar has special pricing for 3, 4, and 5 (and more) letter names. At the time of writing, a `5+` letter `.eth` will cost you `5 USD` per year.
A `4` letter `160 USD` per year, and a `3` letter `640 USD` per year.
This pricing structure is done to promote market diversity as there are an exponentially less amount of names the shorter they become.
The minimum length of a name is 3 characters.
| Name Length | Price (USD) |
| ----------- | ----------- |
| 5+ | 5 |
| 4 | 160 |
| 3 | 640 |
#### Premium & Auctions
In addition to length-based pricing the ETH Registrar also has a premium pricing structure.
90 days after a name expires (aka after the grace period), the name will go into a Temporary Premium Auction.
The Auction is a 21 day dutch auction, meaning that the price starts high (\~100 Million USD) and exponentially decrease till it hits 0 or a bid goes through.
This is done to prevent sniping of names, and ensures the name goes to the highest bidder fairly.
You can read more about the temporary premium in [this article](https://support.ens.domains/en/articles/7900612-temporary-premium).
#### Where does the money go?
Upon registration funds are sent to the ETHRegistrarController. The controller then sends the funds to the ENS Treasury (anyone can call the `withdraw` method to trigger this).
Income from the ETH Registrar is used to fund the development of ENS, its ecosystem, and other public goods.
Read more about our spending in [Article III of the Constitution](/dao/constitution#iii-income-funds-ens-and-other-public-goods).
### ERC721 and NFTs
In the early days of ENS, the ERC721 standard did not exist.
The original ETH Registrar formed the pre-cursor to the ERC721 standard.
As we witnessed the ERC721 being standardized, support for it was added to the ETH Registrar.
Today, users can interact with the ETH Registrar to transfer their name just like with any other ERC721 token.
### Registering a Name
Registering a name is a trustless process that takes place onchain (more on this below). Some open source frontends for registering names are the [ENS Manager App](https://app.ens.domains/), [ENS Fairy](https://ensfairy.xyz/), Rainbow Wallet.
The process of registering a `.eth` name uses a commit-reveal process.
Commit
Wait
Reveal
#### Commit-Reveal
The ETHRegistrarController, the highest level contract that users register names through, implements a commit reveal scheme to prevent frontrunning registrations.
We first call the `commit` function with an opaque bit of data (the `commitmenthash`), wait 60 seconds, and then call the `register` function. The `commit` function takes a commitment hash, which can be generated using the `makeCommitment` function. The commitment hash is opaque and revealed during the `register` function.
The commit-reveal process is to prevent a malicious actor from seeing your `register` transaction in the public mempool and frontrunning it.
```solidity
ETHRegistrarController.makeCommitment(
name string,
owner address,
duration uint256,
secret bytes32,
resolver address,
data bytes[],
reverseRecord bool,
ownerControlledFuses uint16
)
// For example
makeCommitment(
"myname", // "myname.eth" but only the label
0x1234..., // The address you want to own the name
31536000, // 1 year (in seconds)
0x1234..., // A randomly generated 32 byte secret you create
0x1234..., // The address of the resolver you want to use
[0x8b95dd71...], // Encoded function calls you want to pass to the resolver, like `setAddr()`
false, // Whether or not to set the new name as your primary name
0 // The NameWrapper fuses you want to set
);
```
Once you have calculated the commitment hash, submit the `commit` transaction.
```solidity
ETHRegistrarController.commit(commitment bytes32)
```
After having committed, it is required to wait at least the `MIN_COMMITMENT_AGE` (60 seconds) before making the subsequent `register` transaction.
#### Registering
Once you have made the onchain commitment and waited 60 seconds, you can register your name.
Registration takes in the same parameters as the `makeCommitment` function above.
Before initiating registration, ensure that:
* `available(label)` == `true`, where `label` is "name" in "name.eth"
* `duration` >= `MIN_REGISTRATION_DURATION`
* `commitments[commitment]` is between 1 min and 24 hrs old
* `msg.value` >= `rentPrice(name, duration)` + `5-10% (slippage)`
Because the rent price is paid in ETH but denominated in USD, callers are recommended to send slightly more than the value returned by `rentPrice` to avoid issues with fast price changes. A premium of 3-5% will likely be sufficient.
Any excess funds sent during registration are automatically returned to the caller.
```solidity
ETHRegistrarController.register(
name string,
owner address,
duration uint256,
secret bytes32,
resolver address,
data bytes[],
reverseRecord bool,
ownerControlledFuses uint16
)
// For example
register(
"myname", // "myname.eth" but only the label
0x1234..., // The address you want to own the name
31536000, // 1 year (in seconds)
0x1234..., // The same secret you used in the `commit` transaction
0x1234..., // The address of the resolver you want to use
[0x8b95dd71...], // Encoded function calls you want to pass to the resolver, like `setAddr()`
false, // Whether or not to set the new name as your primary name
0 // The NameWrapper fuses you want to set
);
```
### Renewing a Name
```solidity
ETHRegistrarController.renew()
```
Any user can renew a domain, not just the owner. This means that if you want to ensure a name doesn't expire you can renew it for someone.
By allowing renewal for any arbitrary amount of time users can ensure their name will not expire.
As per the separation between registry and controller, even with upgraded controller your name will still be yours.
### Other features
```solidity
ETHRegistrarController.MIN_COMMITMENT_AGE uint
ETHRegistrarController.MAX_COMMITMENT_AGE uint
ETHRegistrarController.MIN_REGISTRATION_DURATION uint
// Get Commitment Timestamp
ETHRegistrarController.commitments mapping(bytes32=>uint)
// Get Rent Price
ETHRegistrarController.rentPrice(string name, uint duration) view returns (uint)
// Check Name Validity
ETHRegistrarController.valid(string name) view returns (bool)
// Check Name Availability
// Returns true if the name is both valid and available for registration by this controller.
ETHRegistrarController.available(string name) view returns (bool)
// Calculate Commitment Hash
ETHRegistrarController.makeCommitment(string name, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] data, bool reverseRecord, uint16 ownerControlledFuses) view returns (bytes32)
// Get Name Expiry (unix timestamp at which registration expires)
BaseRegistrar.nameExpires(uint256 label) view returns (uint)
// Check Name Availability (less specific, use ETHRegistrarController.available instead)
BaseRegistrar.available(uint256 label) view returns (bool)
// Get Transfer Period End (unix timestamp at which transfer period (from legacy registrar) ends)
BaseRegistrar.transferPeriodEnds uint
// Get Controller Status
BaseRegistrar.controllers mapping(address=>bool)
// Check Token Approval
BaseRegistrar.getApproved(uint256 tokenId) view returns (address operator)
// Check All Tokens Approval
BaseRegistrar.isApprovedForAll(address owner, address operator) view returns (bool)
// Get Token Owner
BaseRegistrar.ownerOf(uint256 tokenId) view returns (address)
// Get Token URI
BaseRegistrar.tokenURI(uint256 tokenId) view returns (string)
```
Writable
```solidity
// Transfer a Name
BaseRegistrar.transferFrom(address from, address to, uint256 tokenId)
BaseRegistrar.safeTransferFrom(address from, address to, uint256 tokenId)
BaseRegistrar.safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)
// Approve Operator
BaseRegistrar.approve(address to, uint256 tokenId)
// Set Approval For All
BaseRegistrar.setApprovalForAll(address operator, bool approved)
// Reclaim ENS Record
BaseRegistrar.reclaim(uint256 label)
```
Events
```solidity
// BaseRegistrar
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event NameMigrated(uint256 indexed hash, address indexed owner, uint expires);
event NameRegistered(uint256 indexed hash, address indexed owner, uint expires);
event NameRenewed(uint256 indexed hash, uint expires);
// Controller
event NameRegistered(string name, bytes32 indexed label, address indexed owner, uint cost, uint expires);
event NameRenewed(string name, bytes32 indexed label, uint cost, uint expires);
```
## Reverse Registrars
:::info
Reverse resolution is part of the [primary name](/web/reverse) feature. If you're just trying to fetch a name for an address, you should start there.
:::
Reverse resolution is the process of mapping an EVM address (eg, `0x1234...5678`) to an ENS name on a number of different chains. This is accomplished by using special namespaces in the ENS registry:
| Reverse Namespace | Name in the ENS registry |
| ------------------ | ------------------------ |
| Default (Ethereum) | reverse |
| Ethereum | addr.reverse |
| Arbitrum | 8000a4b1.reverse |
| Base | 80002105.reverse |
| Linea | 8000e708.reverse |
| Optimism | 8000000a.reverse |
| Scroll | 80082750.reverse |
L2 namespaces are derived via `[coinTypeAsHex].reverse` as specified in [ENSIP-19](/ensip/19/), and users' reverse records can be resolved via `[address].[reverseNamespace]`.
For example, the account `0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5` can claim `b8c2c29ee19d8307cb7255e1cd9cbde883a267d5.addr.reverse` in the ENS registry. After doing so, it can configure a resolver and expose metadata, such as a canonical ENS name for this address.
The reverse registrar provides functions to `claim` a reverse record,
as well as a convenience function (`setName`) to configure the record as it's most commonly used, as a way of specifying a canonical name for an address.
### Supported Chains
Reverse Registrars are deployed on Ethereum Mainnet (L1) and popular L2s (Base, OP Mainnet, Arbitrum One, Scroll, and Linea). This enables users to set a chain-specific reverse record while also supporting a default reverse record on L1 that acts as a fallback when a chain-specific record is not set.
In practice, it's strongly recommended to **not** hardcode the reverse registrar addresses because they can change in the future and unexpectedly break your application. Instead, resolve them according to [ENSIP-19](/ensip/19).
For convenience, the latest deployments of the reverse registrars are listed below.
{/* TODO: Add an example of how to do this */}
#### Mainnet Deployments
| Chain | Address |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| Default (Ethereum) | [0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9](https://etherscan.io/address/0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9) |
| Ethereum | [0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb](https://etherscan.io/address/0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb) |
| Arbitrum One | [0x0000000000D8e504002cC26E3Ec46D81971C1664](https://arbiscan.io/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Base | [0x0000000000D8e504002cC26E3Ec46D81971C1664](https://basescan.org/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Linea | [0x0000000000D8e504002cC26E3Ec46D81971C1664](https://lineascan.build/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Optimism | [0x0000000000D8e504002cC26E3Ec46D81971C1664](https://optimistic.etherscan.io/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Scroll | [0x0000000000D8e504002cC26E3Ec46D81971C1664](https://scrollscan.com/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
#### Testnet Deployments
| L2 Testnet Chain | Address |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Default (Ethereum) | [0x4F382928805ba0e23B30cFB75fC9E848e82DFD47](https://sepolia.etherscan.io/address/0x4F382928805ba0e23B30cFB75fC9E848e82DFD47) |
| Ethereum | [0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6](https://sepolia.etherscan.io/address/0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6) |
| Arbitrum Sepolia | [0x00000BeEF055f7934784D6d81b6BC86665630dbA](https://sepolia.arbiscan.io/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Base Sepolia | [0x00000BeEF055f7934784D6d81b6BC86665630dbA](https://sepolia.basescan.org/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Linea Sepolia | [0x00000BeEF055f7934784D6d81b6BC86665630dbA](https://sepolia.lineascan.build/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Optimism | [0x00000BeEF055f7934784D6d81b6BC86665630dbA](https://sepolia-optimism.etherscan.io/address/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Scroll Sepolia | [0x00000BeEF055f7934784D6d81b6BC86665630dbA](https://sepolia.scrollscan.com/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
### Setting Records
The updated Reverse Registrar interface exposes methods to support that make it easier to set a reverse record for an EOA or smart contract:
```solidity
/// @notice Sets the `name()` record for the reverse ENS record associated with the calling account.
/// @param name The name to set
/// @return The ENS node hash of the reverse record
function setName(string memory name) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the addr provided account.
/// Can be used if the addr is a contract that is owned by an SCA.
/// @param addr The address to set the name for
/// @param name The name to set
/// @return The ENS node hash of the reverse record
function setNameForAddr(
address addr,
string memory name
) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the contract provided that is owned with `Ownable`.
/// @param contractAddr The address of the contract to set the name for (implementing Ownable)
/// @param owner The owner of the contract (via Ownable)
/// @param name The name to set
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract
/// @param signatureExpiry The expiry of the signature
/// @param signature The signature of an address that will return true on isValidSignature for the owner
/// @return The ENS node hash of the reverse record
function setNameForOwnableWithSignature(
address contractAddr,
address owner,
string calldata name,
uint256[] memory coinTypes,
uint256 signatureExpiry,
bytes calldata signature
) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the addr provided account using a signature.
/// @param addr The address to set the name for
/// @param name The name of the reverse record
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract
/// @param signatureExpiry Date when the signature expires
/// @param signature The signature from the addr
/// @return The ENS node hash of the reverse record
function setNameForAddrWithSignature(
address addr,
string calldata name,
uint256[] calldata coinTypes,
uint256 signatureExpiry,
bytes calldata signature
) external returns (bytes32);
```
#### Signatures
Signature format for `setNameForAddrWithSignature`:
```
validatorAddress, // the address of the reverse registrar
functionSignature, // 0x2023a04c
name, // string name value
addr, // address to set name for
coinTypes, // array of coinTypes wanting to be set
signatureExpiry // expiry of the signature, up to 1 hour in the future
```
Signature format for `setNameForOwnableWithSignature`:
```
validatorAddress, // the address of the reverse registrar
functionSignature, // 0x975713ad
name, // string name value
contractAddr, // contract address to set name for
owner, // owner address of contract (i.e. the signature being verified)
coinTypes, // array of coinTypes wanting to be set
signatureExpiry // expiry of the signature, up to 1 hour in the future
```
### Other Functions
:::info
The following functions are only available on the ETH Reverse Registrar.
:::
#### Claim Address
```solidity
function claim(address owner) public returns (bytes32);
```
Claims the caller's address in the reverse registrar, assigning ownership of the reverse record to `owner`. Equivalent to calling `claimWithResolver(owner, 0)`. Doesn't actually set the reverse record.
```solidity
function claimWithResolver(address owner, address resolver) public returns (bytes32)
```
Claims the caller's address in the reverse registrar, assigning `ownership` of the reverse record to owner. If `resolver` is nonzero, also updates the record's resolver.
After calling this function:
* The reverse record for the caller (1234....addr.reverse) is owned by `owner`.
* If `resolver` is nonzero, the reverse record for the caller has its resolver set to `resolver`; otherwise it is left unchanged.
#### Get Default Resolver
```solidity
function defaultResolver() public view returns (address);
```
Returns the address of the resolver contract that the `ReverseRegistrar` uses for `setName`.
### Do's and Dont's
Under no situation is it recommended to force a user to change their primary name, nor doing so without clearly notifying the user of what the transaction they are about to execute could modify.
Doing so could be seen as hostile or undesired behaviour by end users and might degrade their experience with your app.
## Layer 2 & Offchain Resolution
All ENS resolution starts on Ethereum Mainnet (or testnet).
However, by leveraging [CCIP Read](/resolvers/ccip-read) and [Wildcard Resolution](/ensip/10), name resolution can be taken cross-chain, offchain, and more.
This allows for a lot of flexibility in how you can use your ENS and for storage of your ENS records on your favourite Layer 2, or even offchain.
### ENS on Layer 2
In the resolution process, clients first fetch the resolver associated with the name in the ENS registry on L1. That resolver is responsible for telling the client where to find the data associated with the name such as the addresses, text records, etc.
If you want to register and resolve (sub)names from L2, you would write a resolver smart contract that defers resolution to the L2 and ideally verifies that data against the L2's storage proofs posted to L1. This process can be done with the [Unruggable Gateway](https://gateway-docs.unruggable.com/).
An example implementation of Layer 2 resolving is:
#### linea.eth
Linea was the first L2 team to build a trust-minimized ENS subname system. Names are stored on Linea, verified with [storage proofs](https://docs.linea.build/developers/tooling/cross-chain/ccip-read-gateway) on L1, and function as ENS subnames such as [greg.linea.eth](https://app.ens.domains/greg.linea.eth). You can try it out [here](https://names.linea.build/).
#### clv.eth
Clave is focused on enhancing user experience and security through a mobile wallet that leverages account abstraction and device hardware. Clave accounts come with usernames that are now stored onchain in ZKsync Era, verified with [storage proofs](https://github.com/getclave/zksync-storage-proofs) in L1, and issued as ENS subnames such as [ulas.clv.eth](https://app.ens.domains/ulas.clv.eth). You can read more about the implementation [here](https://blog.getclave.io/introducing-onchain-clave-usernames-with-ens).
### Primary Names on Layer 2
The process of setting primary names from L2 is under active development. This doc will be updated as more information becomes available.
### Offchain Resolution
Moving resolution processes offchain offers numerous advantages, including efficiency gains and reduced congestion on the main blockchain; however, it also introduces trade-offs in terms of trust, as it necessitates reliance on external systems.
Depending on the implementation, names could be stored in a database or be ephemeral.
Advantages of offchain name storage include gaslessness and instant updates.
If this sounds appealing consider [writing an Offchain Resolver](/resolvers/ccip-read).
Popular implementations of offchain names include but are not limited to:
#### cb.id
Coinbase Wallet is one of the largest mobile wallets issuing free ENS subnames to their users.
These names are stored offchain on coinbase servers, and can be registered from the Coinbase Wallet App or Browser Extension.
An example of a cb.id is [jesse.cb.id](https://app.ens.domains/jesse.cb.id).
#### uni.eth
Uniswap Wallet is another popular mobile wallet that issues free ENS subnames to their users.
You can read more about the Uniswap Wallet ENS integration [here](https://blog.uniswap.org/introducing-uni-eth-your-unique-web3-username).
An example of a uni.eth is [chase.uni.eth](https://app.ens.domains/chase.uni.eth).
import { ContractDeployments } from '../../components/ContractDeployments'
import { EmbedLink } from '../../components/EmbedLink'
import { Card } from '../../components/ui/Card'
## Deployments
:::note
This page contains information that is only relevant to developers who would
like to interact with the contract manually. Most libraries will handle this
for you.
:::
ENS is multichain (read more [here](/web/multichain)) and can be used in any application.
In addition to being able to query many address formats and record types, data can be stored [practically anywhere](/learn/ccip-read).
However, resolution needs to start somewhere, so the entrypoint for resolution is Ethereum Mainnet, alongside the most popular testnets.
Ethereum Mainnet
→
Base
Arbitrum
Offchain
...
### Deployments
Below you will find an abbreviated list of our latest contract deployments. The source of truth for ENS contract deployments is the [ensdomains/ens-contracts](https://github.com/ensdomains/ens-contracts/tree/staging/deployments) repository.
#### Mainnet
Interact with ENS on Ethereum Mainnet via [app.ens.domains](https://app.ens.domains).
#### Sepolia
Interact with ENS on the Sepolia testnet via [sepolia.app.ens.domains](https://sepolia.app.ens.domains).
#### Holesky
:::warning
Holesky testnet support is being phased out. Please migrate your workflows to Sepolia.
:::
Interact with ENS on the Holesky testnet via [holesky.app.ens.domains](https://holesky.app.ens.domains).
### But what about multichain?
While the core ENS protocol lives on Ethereum Mainnet, it can be used to resolve data for any chain!
import { DNSGrid } from '../../components/DNSGrid'
import { DNSUsageExamples } from '../../components/DNSUsageExamples'
import { EmbedLink } from '../../components/EmbedLink'
## DNS on ENS \[ENS supports DNS names, allowing users to import DNS names into ENS.]
The Ethereum Name Service is so much more than just `.eth` names. It is a general-purpose naming system that can be used for any kind of name. This includes DNS names.
DNS functionality was originally introduced in [ENSIP-6](/ensip/6).
### Importing a DNS name
There are currently two ways of importing a DNS name into ENS. Both methods require you enable DNSSEC on your domain, and setup a TXT record.
This record is then verified using smart contracts on the Ethereum blockchain.
To import a name, simply visit the [ENS Manager](https://ens.app), type in your name, and click "Import DNS". You will walked through setting up your DNS records.
Additionally you can read more about the records and specifications here:
### Why DNS on ENS?
ENS aims to extend the existing functionality of the DNS system. This also means that existing DNS names (such as `.com`, `.org`, or `.xyz`) should be able to leverage the benefits of the ENS resolution process.
### DNS Names in the wild
DNS names are widely used and many users may already have one without even realizing it. Some major platforms that issue subdomains of their DNS names include:
### Top-Level Domains
In addition to allowing any DNSSEC enabled name to be imported, ENS also allows existing DNS TLDs to take control of their smart-contract resolution process.
Resulting in even more seamless integration with the DNS system.
A list of all supported TLDs can be found [here](/dns/tlds)
import { DNSGrid } from '../../components/DNSGrid'
import { EmbedLink } from '../../components/EmbedLink'
import { EnsProfile } from '../../components/EnsProfile'
import { Card } from '../../components/ui/Card'
## What is the Ethereum Name Service?
The Ethereum Name Service (ENS) is a distributed, open, and extensible naming system based on the Ethereum blockchain.
ENS maps human-readable names like 'alice.eth' to machine-readable identifiers such as Ethereum addresses, other cryptocurrency addresses, content hashes, metadata, and more.
ENS also supports 'reverse resolution', making it possible to associate metadata such as primary names or interface descriptions with Ethereum addresses.
Top-Level Domains (TLDs), like `.eth` and `.test`, are owned by smart contracts called [registrars](/registry/eth), which specify rules governing the allocation of their names.
Enabling seamless interoperability with the DNS (Domain Name System).
### ETH Registrar
The [ETH Registrar](/registry/eth) is the registrar for the `.eth` TLD, it allows for trustless decentralized names to be issued as tokens on the Ethereum Blockchain.
Registration is done through smart contracts, and name ownership is secured by the Ethereum blockchain.
### DNS + ENS
ENS has similar goals to DNS, the existing Internet's Domain Name Service, and aims to extend its capability.
ENS also supports importing DNS names through the use of DNSSEC.
Allowing you to take your `.com`, `.xyz`, or `.art` (and more) into the ENS ecosystem. Read more about DNSSEC names [on this page](/learn/dns).
### Subnames
{['root', 'registrar', 'controller', 'resolver', 'registry'].map(
(subname, i) => (
{subname}
)
)}
.ens.eth
Because of the hierarchical nature of ENS, anyone who owns a domain at any level can take control of resolution.
Users can create subdomains manually, or take matters into their own hands and write their own resolution logic.
For instance, if Alice owns 'alice.eth', she can create 'pay.alice.eth' and configure it as she wishes.
Or, use a [Custom Resolver](/resolvers/quickstart), and programmatically issue subdomains, for example in an App, Community, or DAO.
### ENS Manager App
You can try ENS out for yourself now by using the [ENS Manager App](https://ens.app/), or by using any of the many ENS enabled applications on [our homepage](https://ens.domains/).
import { EnsProfile } from '../../components/EnsProfile'
import { Card } from '../../components/ui/Card'
## Resolution \[The ENS Resolution Process]
:::note
This document aims to provide a brief overview of how resolution works, to
read more about resolution checkout the [dedicated Resolution
Section](/resolution).
:::
One of the major parts of the ENS protocol is the resolution process. The Resolution process at its core is the process of converting a human-readable name to a machine-readable address.
Though there is a lot of smart contract magic under the hood, the ENS system consists of two main paths: [Forward Resolution](#forward-resolution), used to go from name to address (and load other extra data), and [Reverse Resolution](#reverse-resolution), used to go from address to name.
### Forward Resolution
Forwards resolution is the process of going **from name to address**. As well as to load the records associated to a name.
These records include but are not limited to **discord**, **twitter**, **github**, **email**, **timezone**, and more.
{/* TODO: Turn this into a component and fetch live data */}
➡️
⬇️
ETH Address: 0x5555...3dCa
BTC Address: 1RicMoo...Jyn
Twitter: @ricmoo
Github: @ricmoo
...
Implementing forwards resolution in a dApp can be as simple as using a single line of code!
To learn more about how to implement forwards resolution, check out the [Address Resolution](/web/resolution) documentation.
### Reverse Resolution
Reverse resolution is the process of going **from address to name**. This is a crucial part of the ENS system, as it allows for any address, to be resolved into a human readable name.
Instead of pages filled with addresses, you can now show the names of the people behind the addresses.
0x225...c3B5
to
Implementing reverse resolution in a dApp can be as simple as using a single line of code!
To learn more about how to implement reverse resolution, check out the [Address Resolution](/web/reverse) documentation.
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-1: ENS
### Abstract
This ENSIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes.
The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as 'vitalik.wallet' or '[www.mysite.swarm](http://www.mysite.swarm)', and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve 'mysite.swarm' to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record.
### Motivation
Existing [specifications](https://github.com/ethereum/wiki/wiki/Registrar-ABI) and [implementations](https://ethereum.gitbooks.io/frontier-guide/content/registrar_services.html) for name resolution in Ethereum provide basic functionality, but suffer several shortcomings that will significantly limit their long-term usefulness:
* A single global namespace for all names with a single 'centralised' resolver.
* Limited or no support for delegation and sub-names/sub-domains.
* Only one record type, and no support for associating multiple copies of a record with a domain.
* Due to a single global implementation, no support for multiple different name allocation systems.
* Conflation of responsibilities: Name resolution, registration, and whois information.
Use-cases that these features would permit include:
* Support for subnames/sub-domains - eg, live.mysite.tld and forum.mysite.tld.
* Multiple services under a single name, such as a DApp hosted in Swarm, a Whisper address, and a mail server.
* Support for DNS record types, allowing blockchain hosting of 'legacy' names. This would permit an Ethereum client such as Mist to resolve the address of a traditional website, or the mail server for an email address, from a blockchain name.
* DNS gateways, exposing ENS domains via the Domain Name Service, providing easier means for legacy clients to resolve and connect to blockchain services.
The first two use-cases, in particular, can be observed everywhere on the present-day internet under DNS, and we believe them to be fundamental features of a name service that will continue to be useful as the Ethereum platform develops and matures.
The normative parts of this document does not specify an implementation of the proposed system; its purpose is to document a protocol that different resolver implementations can adhere to in order to facilitate consistent name resolution. An appendix provides sample implementations of resolver contracts and libraries, which should be treated as illustrative examples only.
Likewise, this document does not attempt to specify how domains should be registered or updated, or how systems can find the owner responsible for a given domain. Registration is the responsibility of registrars, and is a governance matter that will necessarily vary between top-level domains.
Updating of domain records can also be handled separately from resolution. Some systems, such as swarm, may require a well defined interface for updating domains, in which event we anticipate the development of a standard for this.
### Specification
#### Overview
The ENS system comprises three main parts:
* The ENS registry
* Resolvers
* Registrars
The registry is a single contract that provides a mapping from any registered name to the resolver responsible for it, and permits the owner of a name to set the resolver address, and to create subdomains, potentially with different owners to the parent domain.
Resolvers are responsible for performing resource lookups for a name - for instance, returning a contract address, a content hash, or IP address(es) as appropriate. The resolver specification, defined here and extended in other ENSIPs, defines what methods a resolver may implement to support resolving different types of records.
Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.
Resolving a name in ENS is a two-step process. First, the ENS registry is called with the name to resolve, after hashing it using the procedure described below. If the record exists, the registry returns the address of its resolver. Then, the resolver is called, using the method appropriate to the resource being requested. The resolver then returns the desired result.
For example, suppose you wish to find the address of the token contract associated with 'beercoin.eth'. First, get the resolver:
```javascript
var node = namehash("beercoin.eth");
var resolver = ens.resolver(node);
```
Then, ask the resolver for the address for the contract:
```javascript
var address = resolver.addr(node);
```
Because the `namehash` procedure depends only on the name itself, this can be precomputed and inserted into a contract, removing the need for string manipulation, and permitting O(1) lookup of ENS records regardless of the number of components in the raw name.
#### Name Syntax
ENS names must conform to the following syntax:
```go
::= | "."
::= any valid string label per [UTS46](https://unicode.org/reports/tr46/)
```
In short, names consist of a series of dot-separated labels. Each label must be a valid normalised label as described in [UTS46](https://unicode.org/reports/tr46/) with the options `transitional=false` and `useSTD3AsciiRules=true`. For Javascript implementations, a [library](https://www.npmjs.com/package/idna-uts46) is available that normalises and checks names.
Note that while upper and lower case letters are allowed in names, the UTS46 normalisation process case-folds labels before hashing them, so two names with different case but identical spelling will produce the same namehash.
Labels and domains may be of any length, but for compatibility with legacy DNS, it is recommended that labels be restricted to no more than 64 characters each, and complete ENS names to no more than 255 characters. For the same reason, it is recommended that labels do not start or end with hyphens, or start with digits.
#### namehash algorithm
Before being used in ENS, names are hashed using the 'namehash' algorithm. This algorithm recursively hashes components of the name, producing a unique, fixed-length string for any valid input domain. The output of namehash is referred to as a 'node'.
Pseudocode for the namehash algorithm is as follows:
```go
def namehash(name):
if name == '':
return '\0' * 32
else:
label, _, remainder = name.partition('.')
return sha3(namehash(remainder) + sha3(label))
```
Informally, the name is split into labels, each label is hashed. Then, starting with the last component, the previous output is concatenated with the label hash and hashed again. The first component is concatenated with 32 '0' bytes. Thus, 'mysite.swarm' is processed as follows:
```javascript
node = '\0' * 32
node = sha3(node + sha3('swarm'))
node = sha3(node + sha3('mysite'))
```
Implementations should conform to the following test vectors for namehash:
```javascript
namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000
namehash('eth') = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae
namehash('foo.eth') = 0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f
```
#### Registry specification
The ENS registry contract exposes the following functions:
```solidity
function owner(bytes32 node) constant returns (address);
```
Returns the owner (registrar) of the specified node.
```solidity
function resolver(bytes32 node) constant returns (address);
```
Returns the resolver for the specified node.
```solidity
function ttl(bytes32 node) constant returns (uint64);
```
Returns the time-to-live (TTL) of the node; that is, the maximum duration for which a node's information may be cached.
```solidity
function setOwner(bytes32 node, address owner);
```
Transfers ownership of a node to another registrar. This function may only be called by the current owner of `node`. A successful call to this function logs the event `Transfer(bytes32 indexed, address)`.
```solidity
function setSubnodeOwner(bytes32 node, bytes32 label, address owner);
```
Creates a new node, `sha3(node, label)` and sets its owner to `owner`, or updates the node with a new owner if it already exists. This function may only be called by the current owner of `node`. A successful call to this function logs the event `NewOwner(bytes32 indexed, bytes32 indexed, address)`.
```solidity
function setResolver(bytes32 node, address resolver);
```
Sets the resolver address for `node`. This function may only be called by the owner of `node`. A successful call to this function logs the event `NewResolver(bytes32 indexed, address)`.
```solidity
function setTTL(bytes32 node, uint64 ttl);
```
Sets the TTL for a node. A node's TTL applies to the 'owner' and 'resolver' records in the registry, as well as to any information returned by the associated resolver.
#### Resolver specification
Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions, the resolver MUST implement either all or none of them. Resolvers MUST specify a fallback function that throws.
Resolvers have one mandatory function:
```solidity
function supportsInterface(bytes4 interfaceID) constant returns (bool)
```
The `supportsInterface` function is documented in ENSIP-165, and returns true if the resolver implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a resolver returns `true` for `supportsInterface()`, it must implement the functions specified in that interface.
`supportsInterface` must always return true for `0x01ffc9a7`, which is the interface ID of `supportsInterface` itself.
Currently standardised resolver interfaces are specified in the table below.
The following interfaces are defined:
| Interface name | Interface hash | Specification |
| --------------------- | -------------- | --------------------------------------------------- |
| `addr` | 0x3b3b57de | Contract address |
| `name` | 0x691f3431 | [ENSIP-3](ensip-3-reverse-resolution.md) |
| `ABI` | 0x2203ab56 | [ENSIP-4](ensip-4-support-for-contract-abis.md) |
| text | 0x59d1d43c | [ENSIP-5](ensip-5-text-records.md) |
| contenthash | 0xbc1c58d1 | [ENSIP-7](ensip-7-contenthash-field.md) |
| interfaceImplementer | 0xb8f2bbb4 | [ENSIP-8](ensip-8-interface-discovery.md) |
| addr(bytes32,uint256) | 0xf1cb7e06 | [ENSIP-9](ensip-9-multichain-address-resolution.md) |
ENSIPs may define new interfaces to be added to this registry.
##### Contract Address Interface
Resolvers wishing to support contract address resources must provide the following function:
```solidity
function addr(bytes32 node) constant returns (address);
```
If the resolver supports `addr` lookups but the requested node does not have an addr record, the resolver MUST return the zero address.
Clients resolving the `addr` record MUST check for a zero return value, and treat this in the same manner as a name that does not have a resolver specified - that is, refuse to send funds to or interact with the address. Failure to do this can result in users accidentally sending funds to the 0 address.
Changes to an address MUST trigger the following event:
```solidity
event AddrChanged(bytes32 indexed node, address a);
```
### Appendix A: Registry Implementation
```solidity
contract ENS {
struct Record {
address owner;
address resolver;
uint64 ttl;
}
mapping(bytes32=>Record) records;
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event Transfer(bytes32 indexed node, address owner);
event NewResolver(bytes32 indexed node, address resolver);
modifier only_owner(bytes32 node) {
if(records[node].owner != msg.sender) throw;
_
}
function ENS(address owner) {
records[0].owner = owner;
}
function owner(bytes32 node) constant returns (address) {
return records[node].owner;
}
function resolver(bytes32 node) constant returns (address) {
return records[node].resolver;
}
function ttl(bytes32 node) constant returns (uint64) {
return records[node].ttl;
}
function setOwner(bytes32 node, address owner) only_owner(node) {
Transfer(node, owner);
records[node].owner = owner;
}
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) {
var subnode = sha3(node, label);
NewOwner(node, label, owner);
records[subnode].owner = owner;
}
function setResolver(bytes32 node, address resolver) only_owner(node) {
NewResolver(node, resolver);
records[node].resolver = resolver;
}
function setTTL(bytes32 node, uint64 ttl) only_owner(node) {
NewTTL(node, ttl);
records[node].ttl = ttl;
}
}
```
### Appendix B: Sample Resolver Implementations
##### Built-in resolver
The simplest possible resolver is a contract that acts as its own name resolver by implementing the contract address resource profile:
```solidity
contract DoSomethingUseful {
// Other code
function addr(bytes32 node) constant returns (address) {
return this;
}
function supportsInterface(bytes4 interfaceID) constant returns (bool) {
return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7;
}
function() {
throw;
}
}
```
Such a contract can be inserted directly into the ENS registry, eliminating the need for a separate resolver contract in simple use-cases. However, the requirement to 'throw' on unknown function calls may interfere with normal operation of some types of contract.
##### Standalone resolver
A basic resolver that implements the contract address profile, and allows only its owner to update records:
```solidity
contract Resolver {
event AddrChanged(bytes32 indexed node, address a);
address owner;
mapping(bytes32=>address) addresses;
modifier only_owner() {
if(msg.sender != owner) throw;
_
}
function Resolver() {
owner = msg.sender;
}
function addr(bytes32 node) constant returns(address) {
return addresses[node];
}
function setAddr(bytes32 node, address addr) only_owner {
addresses[node] = addr;
AddrChanged(node, addr);
}
function supportsInterface(bytes4 interfaceID) constant returns (bool) {
return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7;
}
function() {
throw;
}
}
```
After deploying this contract, use it by updating the ENS registry to reference this contract for a name, then calling `setAddr()` with the same node to set the contract address it will resolve to.
##### Public resolver
Similar to the resolver above, this contract only supports the contract address profile, but uses the ENS registry to determine who should be allowed to update entries:
```solidity
contract PublicResolver {
event AddrChanged(bytes32 indexed node, address a);
event ContentChanged(bytes32 indexed node, bytes32 hash);
ENS ens;
mapping(bytes32=>address) addresses;
modifier only_owner(bytes32 node) {
if(ens.owner(node) != msg.sender) throw;
_
}
function PublicResolver(address ensAddr) {
ens = ENS(ensAddr);
}
function addr(bytes32 node) constant returns (address ret) {
ret = addresses[node];
}
function setAddr(bytes32 node, address addr) only_owner(node) {
addresses[node] = addr;
AddrChanged(node, addr);
}
function supportsInterface(bytes4 interfaceID) constant returns (bool) {
return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7;
}
function() {
throw;
}
}
```
### Appendix C: Sample Registrar Implementation
This registrar allows users to register names at no cost if they are the first to request them.
```solidity
contract FIFSRegistrar {
ENS ens;
bytes32 rootNode;
function FIFSRegistrar(address ensAddr, bytes32 node) {
ens = ENS(ensAddr);
rootNode = node;
}
function register(bytes32 subnode, address owner) {
var node = sha3(rootNode, subnode);
var currentOwner = ens.owner(node);
if(currentOwner != 0 && currentOwner != msg.sender)
throw;
ens.setSubnodeOwner(rootNode, subnode, owner);
}
}
```
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-10: Wildcard Resolution
Provides a mechanism to support wildcard resolution of ENS names (formerly [EIP-2544](https://eips.ethereum.org/EIPS/eip-2544)).
### Abstract
The Ethereum Name Service Specification (ENSIP-1) establishes a two-step name resolution process. First, an ENS client performs the namehash algorithm on the name to determine the associated "node", and supplies that node to the ENS Registry contract to determine the resolver. Then, if a resolver has been set on the Registry, the client supplies that same node to the resolver contract, which will return the associated address or other record.
As currently specified, this process terminates if a resolver is not set on the ENS Registry for a given node. This ENSIP changes the name resolution process by adding an additional step if a resolver is not set for a domain. This step strips out the leftmost label from the name, derives the node of the new fragment, and supplies that node to the ENS Registry. If a resolver is located for that node, the client supplies the original, complete node to that resolver contract to derive the relevant records. This step is repeated until a node with a resolver is found.
Further, this specification defines a new way for resolvers to resolve names, using a unified `resolve()` method that permits more flexible handling of name resolution.
### Motivation
Many applications such as wallet providers, exchanges, and dapps have expressed a desire to issue ENS names for their users via custom subdomains on a shared parent domain. However, the cost of doing so is currently prohibitive for large user bases, as a distinct record must be set on the ENS Registry for each subdomain.
Furthermore, users cannot immediately utilize these subdomains upon account creation, as the transaction to assign a resolver for the node of the subdomain must first be submitted and mined on-chain. This adds unnecessary friction when onboarding new users, who coincidentally would often benefit greatly from the usability improvements afforded by an ENS name.
Enabling wildcard support allows for the design of more advanced resolvers that deterministically generate addresses and other records for unassigned subdomains. The generated addresses could map to counterfactual contract deployment addresses (i.e. `CREATE2` addresses), to designated "fallback" addresses, or other schemes. Additionally, individual resolvers would still be assignable to any given subdomain, which would supersede the wildcard resolution using the parent resolver.
Another critical motivation with this standard is to enable wildcard resolution in a backwards-compatible fashion. It does not require modifying the current ENS Registry contract or any existing resolvers, and continues to support existing ENS records — legacy ENS clients would simply fail to resolve wildcard records.
### Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Let:
* `namehash` be the algorithm defined in ENSIP-1.
* `dnsencode` be the process for encoding DNS names specified in section 3.1 of RFC1035, with the exception that there is no limit on the total length of the encoded name. The empty string is encoded identically to the name '.', as a single 0-octet.
* `parent` be a function that removes the first label from a name (eg, `parent('foo.eth') = 'eth'`). `parent('tld')` is defined as the empty string ''.
* `ens` is the ENS registry contract for the current network.
ENSIP-10-compliant ENS resolvers MAY implement the following function interface:
```solidity
interface ExtendedResolver {
function resolve(bytes calldata name, bytes calldata data) external view returns(bytes);
}
```
If a resolver implements this function, it MUST return true when `supportsInterface()` is called on it with the interface's ID, `0x9061b923`.
ENS clients will call `resolve` with the DNS-encoded name to resolve and the encoded calldata for a resolver function (as specified in ENSIP-1 and elsewhere); the function MUST either return valid return data for that function, or revert if it is not supported.
ENSIP-10-compliant ENS clients MUST perform the following procedure when determining the resolver for a given name:
1. Set `currentname = name`
2. Set `resolver = ens.resolver(namehash(currentname))`
3. If `resolver` is not the zero address, halt and return `resolver`.
4. If `currentname` is the empty name ('' or '.'), halt and return null.
5. Otherwise, set `currentname = parent(currentname)` and go to 2.
If the procedure above returns null, name resolution MUST terminate unsuccessfully. Otherwise, ENSIP-10-compliant ENS clients MUST perform the following procedure when resolving a record:
1. Set `calldata` to the ABI-encoded call data for the resolution function required - for example, the ABI encoding of `addr(namehash(name))` when resolving the `addr` record.
2. Set `supportsENSIP10 = resolver.supportsInterface('0x9061b923')`.
3. If `supportsENSIP10` is true, set `result = resolver.resolve(dnsencode(name), calldata)`
4. If `supportsENSIP10` is false and `name == currentname`, set `result` to the result of calling `resolver` with `calldata`.
5. If neither 3 nor 4 are true, terminate unsuccessfully.
6. Return `result` after decoding it using the return data ABI of the corresponding resolution function (eg, for `addr()`, ABI-decode the result of `resolver.resolve()` as an `address`).
Note that in all cases the resolution function (`addr()` etc) and the `resolve` function are supplied the original `name`, *not* the `currentname` found in the first stage of resolution.
Also note that when wildcard resolution is in use (eg, `name != currentname`), clients MUST NOT call legacy methods such as `addr` to resolve the name. These methods may only be called on resolvers set on an exact match for `name`.
#### Pseudocode
```javascript
function getResolver(name) {
for(let currentname = name; currentname !== ''; currentname = parent(currentname)) {
const node = namehash(currentname);
const resolver = ens.resolver(node);
if(resolver != '0x0000000000000000000000000000000000000000') {
return [resolver, currentname];
}
}
return [null, ''];
}
function resolve(name, func, ...args) {
const [resolver, resolverName] = getResolver(name);
if(resolver === null) {
return null;
}
const supportsENSIP10 = resolver.supportsInterface('0x9061b923');
if(supportsENSIP10) {
const calldata = resolver[func].encodeFunctionCall(namehash(name), ...args);
const result = resolver.resolve(dnsencode(name), calldata);
return resolver[func].decodeReturnData(result);
} else if(name == resolverName) {
return resolver[func](...args);
} else {
return null;
}
}
```
### Rationale
The proposed implementation supports wildcard resolution in a manner that minimizes the impact to existing systems. It also reuses existing algorithms and procedures to the greatest possible extent, thereby easing the burden placed on authors and maintainers of various ENS clients.
It also recognizes an existing consensus concerning the desirability of wildcard resolution for ENS, enabling more widespread adoption of the original specification by solving for a key scalability obstacle.
While introducing an optional `resolve` function for resolvers, taking the unhashed name and calldata for a resolution function increases implementation complexity, it provides a means for resolvers to obtain plaintext labels and act accordingly, which enables many wildcard-related use-cases that would otherwise not be possible - for example, a wildcard resolver could resolve `id.nifty.eth` to the owner of the NFT with id `id` in some collection. With only namehashes to work with, this is not possible.
The DNS wire format is used for encoding names as it permits quick and gas-efficient hashing of names, as well as other common operations such as fetching or removing individual labels; in contrast, dot-separated names require iterating over every character in the name to find the delimiter.
### Backwards Compatibility
Existing ENS clients that are compliant with ENSIP-1 will fail to resolve wildcard records and refuse to interact with them, while those compliant with ENSIP-10 will continue to correctly resolve, or reject, existing ENS records. Resolvers wishing to implement the new `resolve` function for non-wildcard use-cases (eg, where the resolver is set directly on the name being resolved) should consider what to return to legacy clients that call the individual resolution functions for maximum compatibility.
Requiring clients to avoid calling existing resolution functions (eg, `addr` etc) on wildcard resolvers prevents inadvertent backwards compatibility issues with resolvers that answer queries for all names.
### Security Considerations
While compliant ENS clients will continue to refuse to resolve records without a resolver, there is still the risk that an improperly-configured client will refer to an incorrect resolver, or will not reject interactions with the null address when a resolver cannot be located.
Additionally, resolvers supporting completely arbitrary wildcard subdomain resolution will increase the likelihood of funds being sent to unintended recipients as a result of typos. Applications that implement such resolvers should consider making additional name validation available to clients depending on the context, or implementing features that support recoverability of funds.
There is also the possibility that some applications might require that no resolver be set for certain subdomains. For this to be problematic, the parent domain would need to successfully resolve the given subdomain node — to the knowledge of the authors, no application currently supports this feature or expects that subdomains should not resolve to a record.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-11: EVM compatible Chain Address Resolution
Introduces coinType for EVM compatible chains (amending [ENSIP-9](https://docs.ens.domains/ensip/9)).
### Abstract
This ENSIP extends [ENSIP 9 (multichain address resolution)](./9), dedicates a range of coin types for EVM compatible chains, and specifies a way to derive EVM chain IDs to the designated coin types.
The dedicated range uses over 0x80000000 (2147483648) which is reserved under ENSIP 9 so there will be no possibility of coin type collision with other non EVM coin types to be added in future. However, some of coin types previously allocated to EVM chain ids will be deprecated.
### Motivation
The existing ENSIP 9 relies on the existence of coin types on [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) which was designed to define address encoding type for deterministic wallets. As the majority of EVM compatible chains inherit the same encoding type as Ethereum, it is redundant to keep requesting the addition of EVM compatible chains into SLIP 44. This specification standardises a way to derive coinType based on [Chain ID](https://chainlist.org).
### Specification
This specification amends ENSIP 9 to specify that coin types with the most-significant bit set are to be treated as EVM chain IDs. The MSB is reserved in SLIP44 for other purposes relating to HD wallet key derivation, so no coin types exist in this range.
To compute the new coin type for EVM chains, bitwise-OR the chain ID with `0x80000000`: `0x80000000 | chainId`.
```typescript
export const convertEVMChainIdToCoinType = (chainId: number) =>{
return (0x80000000 | chainId) >>> 0
}
```
And to reverse the operation, bitwise-AND the coinType with `0x7fffffff`: `0x7fffffff & coinType`.
```typescript
export const convertCoinTypeToEVMChainId = (coinType: number) =>{
return (0x7fffffff & coinType) >> 0
}
```
#### Implementation
An implementation of this interface is provided in the [ensdomains/address-encoder](https://github.com/ensdomains/address-encoder/) repository.
#### Example
To compute the new coin type for EVM chains, call `convertEVMChainIdToCoinType(chainId)`
```javascript
const encoder = require('@ensdomains/address-encoder')
> encoder.convertEVMChainIdToCoinType(61)
2147483709
> encoder.convertCoinTypeToEVMChainId(2147483709)
61
```
You can also use existing functions formatsByName and formatsByCoinType to derive these chain IDs
```javascript
> encoder.formatsByName['XDAI']
{
coinType: 2147483748,
decoder: [Function (anonymous)],
encoder: [Function (anonymous)],
name: 'XDAI'
}
> encoder.formatsByCoinType[2147483748]
{
coinType: 2147483748,
decoder: [Function (anonymous)],
encoder: [Function (anonymous)],
name: 'XDAI'
}
```
#### Exceptions
The following EVM chains are the exception to this standard.
* AVAX = AVAX has multiple chain address formats, and only c chain is EVM compatible
* RSK = RSK has its own additional validation
They will continue using coinType defined at SLIP44
#### Backwards Compatibility
The following EVM compatible cointypes existed before introducing this new standard.
* NRG
* POA
* TT
* CELO
* CLO
* TOMO
* EWT
* THETA
* GO
* FTM
* XDAI
* ETC
When you display them for backward compatibility purposes, append `_LEGACY` to the cointype and make them read only.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-12: Avatar Text Records
A standard for storage of the avatar text record in ENS.
### Abstract
This ENSIP defines a process for retrieving avatar URIs from ENS, several [URI](https://datatracker.ietf.org/doc/html/rfc3986) schemes for the ENS 'avatar' text field, and how they should be interpreted by clients wishing to display a user's avatar image.
### Motivation
ENS primary name (formerly known as reverse record) has been widely integrated as a de facto web3 user name across many Ethereum based applications. As multiple apps started specifying avatar profile image as well as let users pick NFT as pfp (profile image), it became obvious to store such information within ENS so that the avatar information can be shared across different applications.
This specification standardises a way to store and retrieve this information using [ENSIP-5: Text Records](https://docs.ens.domains/ensip/5)
### Specification
#### Retrieving the avatar URI
The process for retrieving the avatar URI depends on whether the client has an Ethereum address or an ENS name to start with.
#### ENS Name
To determine the avatar URI for an ENS name, the client MUST first look up the resolver for the name and call `.text(namehash(name), 'avatar')` on it to retrieve the avatar URI for the name.
The client MUST treat the absence of a resolver, an revert when calling the `addr` method on the resolver, or an empty string returned by the resolver identically, as a failure to find a valid avatar URI.
#### Ethereum Address
To determine the avatar URI for an Ethereum address, the client MUST reverse-resolve the address by querying the ENS registry for the resolver of `<address>.addr.reverse`, where `<address>` is the lowercase hex-encoded Ethereum address, without leading '0x'. Then, the client calls `.text(namehash(<address>.addr.reverse'), 'avatar')` to retrieve the avatar URI for the address.
If a resolver is returned for the reverse record, but calling `text` causes a revert or returns an empty string, the client MUST call `.name(namehash('<address>.addr.reverse'))`. If this method returns a valid ENS name, the client MUST:
1. Validate that the reverse record is valid, by resolving the returned name and calling `addr` on the resolver, checking it matches the original Ethereum address.
2. Perform the process described under 'ENS Name' to look for a valid avatar URI on the name.
A failure at any step of this process MUST be treated by the client identically as a failure to find a valid avatar URI.
#### General Format
The 'avatar' text field MUST be formatted as a URI. Clients MUST ignore URI types they do not recognise, treating them the same as if no value was set for the field.
#### Image Types
Clients MUST support images with mime types of `image/jpeg`, `image/png`, and `image/svg+xml`. Clients MAY support additional image types.
#### URI Types
All clients SHOULD support the URI schemes defined below. They MAY implement additional schemes not defined in this specification.
**`https`**
If an https URI is provided, it MUST resolve to an avatar image directly. https URLs MUST NOT resolve to HTML pages, metadata, or other content containing the avatar image.
**`ipfs`**
If an [ipfs URI](https://docs.ipfs.io/how-to/address-ipfs-on-web/#native-urls) is provided, it MUST resolve to an avatar image directly. Clients without built-in IPFS support MAY rewrite the URI to an https URL referencing an IPFS gateway as described in [this document](https://docs.ipfs.io/how-to/address-ipfs-on-web/) before resolving it as an https URL.
**`data`**
If a [data URL](https://datatracker.ietf.org/doc/html/rfc2397) is provided, it MUST resolve to an avatar image directly.
**NFTs**
A reference to an NFT may be used as an avatar URI, following the standards defined in [CAIP-22](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-22.md) and [CAIP-29](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-29.md).
Clients MUST support at least ERC721 and ERC1155 type NFTs, and MAY support additional types of NFT.
To resolve an NFT URI, a client follows this process:
1. Retrieve the metadata URI for the token specified in the `avatar` field URI.
2. Resolve the metadata URI, fetching the ERC721 or ERC1155 metadata.
3. Extract the image URL specified in the NFT metadata.
4. Resolve the image URL and use it as the avatar.
Clients MUST support at least `https` and `ipfs` URIs for resolving the metadata URI and the avatar image, and MAY support additional schemes. Clients MAY implement `ifps` scheme support by rewriting the URI to an HTTPS URL referencing an IPFS gateway as described above.
Clients SHOULD additionally take the following verification steps:
1. Where the avatar URI was retrieved via forward resolution (starting from an ENS name), call the `addr` function on the same resolver and for the same name to retrieve the Ethereum address to which the name resolves. Otherwise, if the avatar URI was retrieved via reverse resolution (starting from an Ethereum address), use that address.
2. Verify that the address from step 1 is an owner of the NFT specified in the URI. If it is not, the client MUST treat the URI as invalid and behave in the same manner as they would if no avatar URI was specified.
Clients MAY support NFT URIs by rewriting them to `https` URIs for a service that provides NFT avatar image resolution support.
#### Examples
The following examples all resolve to the same avatar image:
```
eip155:1/erc721:0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/0 # BAYC token 0
ipfs://QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ # IPFS hash for BAYC token 0 image
https://ipfs.io/ipfs/QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ # HTTPS URL to IPFS gateway for BAYC token 0 image
```
### Backwards Compatibility
Not applicable.
### Security Considerations
None.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-13: SAFE Authentication For ENS
Using ENS Text Records to facilitate safer and more convenient signing operations. |
### Abstract
This EIP links one or more signing wallets via Ethereum Name Service Specification ([EIP-137](https://eips.ethereum.org/EIPS/eip-137)) to prove control and asset ownership of a main wallet.
### Motivation
Proving ownership of an asset to a third party application in the Ethereum ecosystem is common. Users frequently sign payloads of data to authenticate themselves before gaining access to perform some operation. However, this method--akin to giving the third party root access to one's main wallet--is both insecure and inconvenient.
***Examples:***
1. In order for you to edit your profile on OpenSea, you must sign a message with your wallet.
2. In order to access NFT gated content, you must sign a message with the wallet containing the NFT in order to prove ownership.
3. In order to gain access to an event, you must sign a message with the wallet containing a required NFT in order to prove ownership.
4. In order to claim an airdrop, you must interact with the smart contract with the qualifying wallet.
5. In order to prove ownership of an NFT, you must sign a payload with the wallet that owns that NFT.
In all the above examples, one interacts with the dApp or smart contract using the wallet itself, which may be
* inconvenient (if it is controlled via a hardware wallet or a multi-sig)
* insecure (since the above operations are read-only, but you are signing/interacting via a wallet that has write access)
Instead, one should be able to approve multiple wallets to authenticate on behalf of a given wallet.
#### Problems with existing methods and solutions
Unfortunately, we've seen many cases where users have accidentally signed a malicious payload. The result is almost always a significant loss of assets associated with the signing address.
In addition to this, many users keep significant portions of their assets in 'cold storage'. With the increased security from 'cold storage' solutions, we usually see decreased accessibility because users naturally increase the barriers required to access these wallets.
Some solutions propose dedicated registry smart contracts to create this link, or new protocols to be supported. This is problematic from an adoption standpoint, and there have not been any standards created for them.
#### Proposal: Use the Ethereum Name Service (EIP-137)
Rather than 're-invent the wheel', this proposal aims to use the widely adopted Ethereum Name Service in conjunction with the ENS Text Records feature ([EIP-634](https://eips.ethereum.org/EIPS/eip-634)) in order to achieve a safer and more convenient way to sign and authenticate, and provide 'read only' access to a main wallet via one or more secondary wallets.
From there, the benefits are twofold. This EIP gives users increased security via outsourcing potentially malicious signing operations to wallets that are more accessible (hot wallets), while being able to maintain the intended security assumptions of wallets that are not frequently used for signing operations.
##### Improving dApp Interaction Security
Many dApps requires one to prove control of a wallet to gain access. At the moment, this means that you must interact with the dApp using the wallet itself. This is a security issue, as malicious dApps or phishing sites can lead to the assets of the wallet being compromised by having them sign malicious payloads.
However, this risk would be mitigated if one were to use a secondary wallet for these interactions. Malicious interactions would be isolated to the assets held in the secondary wallet, which can be set up to contain little to nothing of value.
##### Improving Multiple Device Access Security
In order for a non-hardware wallet to be used on multiple devices, you must import the seed phrase to each device. Each time a seed phrase is entered on a new device, the risk of the wallet being compromised increases as you are increasing the surface area of devices that have knowledge of the seed phrase.
Instead, each device can have its own unique wallet that is an authorized secondary wallet of the main wallet. If a device specific wallet was ever compromised or lost, you could simply remove the authorization to authenticate.
Further, wallet authentication can be matokenUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Let:
* `mainAddress` represent the wallet address we are trying to authenticate or prove asset ownership for.
* `mainENS` represent the reverse lookup ENS string for `mainAddress`.
* `authAddress` represent the address we want to use for signing in lieu of `mainAddress`.
* `authENS` represent the reverse lookup ENS string for `authAddress`.
* `authKey` represents a string in the format `[0-9A-Za-z]+`.
Control of `mainAddress` and ownership of `mainAddress` assets by `authAddress` is proven if all the following conditions are met:
* `mainAddress` has an ENS resolver record and a reverse record set to `mainENS`.
* `authAddress` has an ENS resolver record and a reverse record set to `authENS`.
* `authENS` has an ENS TEXT record `eip5131:vault` in the format `:`.
* `mainENS` has an ENS TEXT record `eip5131:`.
#### Setting up one or many `authAddress` records on a single ENS domain
The `mainAddress` MUST have an ENS resolver record and reverse record configured.
In order to automatically discover the linked account, the `authAddress` SHOULD have an ENS resolver record and reverse record configured.
1. Choose an unused ``. This can be any string in the format `[0-0A-Za-z]+`.
2. Set a TEXT record `eip5131:` on `mainENS`, with the value set to the desired `authAddress`.
3. Set a TEXT record `eip5131:vault` on `authENS`, with the value set to the `:mainAddress`.
Currently this EIP does not enforce an upper-bound on the number of `authAddress` entries you can include. Users can repeat this process with as many address as they like.
#### Authenticating `mainAddress` via `authAddress`
Control of `mainAddress` and ownership of `mainAddress` assets is proven if any associated `authAddress` is the `msg.sender` or has signed the message.
Practically, this would work by performing the following operations:
1. Get the resolver for `authENS`
2. Get the `eip5131:vault` TEXT record of `authENS`
3. Parse `:` to determine the `authKey` and `mainAddress`.
4. MUST get the reverse ENS record for `mainAddress` and verify that it matches ``.
* Otherwise one could set up other ENS nodes (with auths) that point to `mainAddress` and authenticate via those.
5. Get the `eip5131:` TEXT record of `mainENS` and ensure it matches `authAddress`.
Note that this specification allows for both contract level and client/server side validation of signatures. It is not limited to smart contracts, which is why there is no proposed external interface definition.
#### Revocation of `authAddress`
To revoke permission of `authAddress`, delete the `eip5131:` TEXT record of `mainENS` or update it to point to a new `authAddress`.
### Rationale
#### Usage of EIP-137
The proposed specification makes use of EIP-137 rather than introduce another registry paradigm. The reason for this is due to the existing wide adoption of EIP-137 and ENS.
However, the drawback to EIP-137 is that any linked `authAddress` must contain some ETH in order to set the `authENS` reverse record as well as the `eip5131:vault` TEXT record. This can be solved by a separate reverse lookup registry that enables `mainAddress` to set the reverse record and TEXT record with a message signed by `authAddress`.
With the advent of L2s and ENS Layer 2 functionalities, off chain verification of linked addresses is possible even with domains managed across different chains.
#### One-to-Many Authentication Relationship
This proposed specification allows for a one (`mainAddress`) to many (`authAddress`) authentication relationship. i.e. one `mainAddress` can authorize many `authAddress` to authenticate, but an `authAddress` can only authenticate itself or a single `mainAddress`.
The reason for this design choice is to allow for simplicity of authentication via client and smart contract code. You can determine which `mainAddress` the `authAddress` is signing for without any additional user input.
Further, you can design UX without any user interaction necessary to 'pick' the interacting address by display assets owned by `authAddress` and `mainAddress` and use the appropriate address dependent on the asset the user is attempting to authenticate with.
#### Reference Implementation
##### Client/Server Side
In typescript, the validation function, using ethers.js would be as follows:
```solidity
export interface LinkedAddress {
ens: string,
address: string,
}
export async function getLinkedAddress(
provider: ethers.providers.EnsProvider, address: string
): Promise {
const addressENS = await provider.lookupAddress(address);
if (!addressENS) return null;
const vaultInfo = await (await provider.getResolver(addressENS))?.getText('eip5131:vault');
if (!vaultInfo) return null;
const vaultInfoArray = vaultInfo.split(':');
if (vaultInfoArray.length !== 2) {
throw new Error('EIP5131: Authkey and vault address not configured correctly.');
}
const [ authKey, vaultAddress ] = vaultInfoArray;
const vaultENS = await provider.lookupAddress(vaultAddress);
if (!vaultENS) {
throw new Error(`EIP5131: No ENS domain with reverse record set for vault.`);
};
const expectedSigningAddress = await (
await provider.getResolver(vaultENS)
)?.getText(`eip5131:${authKey}`);
if (expectedSigningAddress?.toLowerCase() !== address.toLowerCase()) {
throw new Error(`EIP5131: Authentication mismatch.`);
};
return {
ens: vaultENS,
address: vaultAddress
};
}
```
##### Contract side
##### With a backend
If your application operates a secure backend server, you could run the client/server code above, then use the result in conjunction with specs like [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) : `Standard Signature Validation Method for Contracts` for a cheap and secure way to validate that the the message signer is indeed authenticated for the main address.
##### Without a backend (JavaScript only)
Provided is a reference implementation for an internal function to verify that the message sender has an authentication link to the main address.
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
/**
* ENS Registry Interface
*/
interface ENS {
function resolver(bytes32 node) external view returns (address);
}
/**
* ENS Resolver Interface
*/
interface Resolver {
function addr(bytes32 node) external view returns (address);
function name(bytes32 node) external view returns (string memory);
function text(bytes32 node, string calldata key) external view returns (string memory);
}
/**
* Validate a signing address is associtaed with a linked address
*/
library LinkedAddress {
/**
* Validate that the message sender is an authentication address for mainAddress
*
* @param ensRegistry Address of ENS registry
* @param mainAddress The main address we want to authenticate for.
* @param mainENSNodeHash The main ENS Node Hash
* @param authKey The TEXT record of the authKey we are using for validation
* @param authENSNodeHash The auth ENS Node Hash
*/
function validateSender(
address ensRegistry,
address mainAddress,
bytes32 mainENSNodeHash,
string calldata authKey,
bytes32 authENSNodeHash
) internal view returns (bool) {
return validate(ensRegistry, mainAddress, mainENSNodeHash, authKey, msg.sender, authENSNodeHash);
}
/**
* Validate that the authAddress is an authentication address for mainAddress
*
* @param ensRegistry Address of ENS registry
* @param mainAddress The main address we want to authenticate for.
* @param mainENSNodeHash The main ENS Node Hash
* @param authAddress The address of the authentication wallet
* @param authENSNodeHash The auth ENS Node Hash
*/
function validate(
address ensRegistry,
address mainAddress,
bytes32 mainENSNodeHash,
string calldata authKey,
address authAddress,
bytes32 authENSNodeHash
) internal view returns (bool) {
_verifyMainENS(ensRegistry, mainAddress, mainENSNodeHash, authKey, authAddress);
_verifyAuthENS(ensRegistry, mainAddress, authKey, authAddress, authENSNodeHash);
return true;
}
// *********************
// Helper Functions
// *********************
function _verifyMainENS(
address ensRegistry,
address mainAddress,
bytes32 mainENSNodeHash,
string calldata authKey,
address authAddress
) private view {
// Check if the ENS nodes resolve correctly to the provided addresses
address mainResolver = ENS(ensRegistry).resolver(mainENSNodeHash);
require(mainResolver != address(0), "Main ENS not registered");
require(mainAddress == Resolver(mainResolver).addr(mainENSNodeHash), "Main address is wrong");
// Verify the authKey TEXT record is set to authAddress by mainENS
string memory authText = Resolver(mainResolver).text(mainENSNodeHash, string(abi.encodePacked("eip5131:", authKey)));
require(
keccak256(bytes(authText)) == keccak256(bytes(_addressToString(authAddress))),
"Invalid auth address"
);
}
function _verifyAuthENS(
address ensRegistry,
address mainAddress,
string memory authKey,
address authAddress,
bytes32 authENSNodeHash
) private view {
// Check if the ENS nodes resolve correctly to the provided addresses
address authResolver = ENS(ensRegistry).resolver(authENSNodeHash);
require(authResolver != address(0), "Auth ENS not registered");
require(authAddress == Resolver(authResolver).addr(authENSNodeHash), "Auth address is wrong");
// Verify the TEXT record is appropriately set by authENS
string memory vaultText = Resolver(authResolver).text(authENSNodeHash, "eip5131:vault");
require(
keccak256(abi.encodePacked(authKey, ":", _addressToString(mainAddress))) ==
keccak256(bytes(vaultText)),
"Invalid auth text record"
);
}
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function sha3HexAddress(address addr) private pure returns (bytes32 ret) {
uint256 value = uint256(uint160(addr));
bytes memory buffer = new bytes(40);
for (uint256 i = 39; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
return keccak256(buffer);
}
function _addressToString(address addr) private pure returns (string memory ptr) {
// solhint-disable-next-line no-inline-assembly
assembly {
ptr := mload(0x40)
// Adjust mem ptr and keep 32 byte aligned
// 32 bytes to store string length; address is 42 bytes long
mstore(0x40, add(ptr, 96))
// Store (string length, '0', 'x') (42, 48, 120)
// Single write by offsetting across 32 byte boundary
ptr := add(ptr, 2)
mstore(ptr, 0x2a3078)
// Write string backwards
for {
// end is at 'x', ptr is at lsb char
let end := add(ptr, 31)
ptr := add(ptr, 71)
} gt(ptr, end) {
ptr := sub(ptr, 1)
addr := shr(4, addr)
} {
let v := and(addr, 0xf)
// if > 9, use ascii 'a-f' (no conditional required)
v := add(v, mul(gt(v, 9), 39))
// Add ascii for '0'
v := add(v, 48)
mstore8(ptr, v)
}
// return ptr to point to length (32 + 2 for '0x' - 1)
ptr := sub(ptr, 33)
}
return string(ptr);
}
}
```
### Security Considerations
The core purpose of this EIP is to enhance security and promote a safer way to authenticate wallet control and asset ownership when the main wallet is not needed and assets held by the main wallet do not need to be moved. Consider it a way to do 'read only' authentication.
### Copyright
Copyright and related rights waived via [CC0](https://eips.ethereum.org/LICENSE).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-14: On Chain Source Parameter
Using the reveal secret as a way to have on chain information about the source of the registration.
### Abstract
We have many reasons to measure user registration names. Knowing our ecosystem and which apps are popular is essential for identifying the creators who contribute. Retroactive funding via grants is often better than proactive funding, as it allows us to detect what has already worked, rather than relying on guesses. This community often sees unexpected successes that we can't predict.
At the same time, it's important to make the process transparent, open source, and privacy-preserving. Source data would also help create referral programs.
### Specification
The ETH Registrar Controller takes a random secret as part of its input. This secret parameter is random data that obscures the name before the final step of the registration process is complete. It is 32 bytes of entropy and the ens manager app on app.ens.domains generates it by calling `require('crypto').randomBytes(32)`.
This proposal suggests a social convention that generates the secret from a combination of the first **4 bytes of the namehash**, plus another **4 bytes for user referrals**, combined with the appropriate number of random bytes.
In hex formatted string it means that the first 8 chars of the secret would be the platform name and the next 8 would be used as an identifier of the user referral. For example, if the above was registered via ensfairy, the secret would be:
> 0x **1b7f8b3c** **612c63bc** c635528d3b7196bc89d13566c1be2068af0cad6fb3ecebf0
With this, we can attribute registrations using the first 16 chars of the secret. The loss of entropy of 64 bits is not relevant, since the only goal of the secret is to obscure the details of the bid to avoid front-running during the short period (usually a few minutes, but it could be as long as a week) before the reveal transaction is executed. The secret still retains 192 bits, which is highly secure, especially for such a short time frame.
### User Referral Data
The goal of this ENSIP is to empower app makers and anyone who wants to start a registration campaign. Any app that conforms to this standard should accept a referral link in the form of `?ensref=12345678` (or a similar scheme for mobile apps and other platforms). When a new user arrives at the site via a referral code, the platform should try to remember the user if they later register an ENS name, by appending the code to the platform code, followed by the rest of the secret. Standard cookie and private data regulations apply. While we encourage users to derive their code from a namehash, any random code should be accepted.
The extra data can be used in this example:
* Alice refers Bob to an ENS registrar app using a custom link like `app.ens.domains/?ensref=deadbeef`
* If Bob clicks the link, the information is saved on the cookies/local storage (until it's overwritten by another referral code, Bob clears his memory, or the code expires).
* Later, Bob wants to register a name; the secret will be prepended by the first 8 letters of the platform, followed by the code provided by Alice.
This allows individuals who don't own a name registrar app, but have their own audience, to have a cross-registrar referral, which registrars can choose to share revenue with.
### Privacy Concerns
This action makes it public which apps users are using to register names, and may reveal who they are friends with or who they follow. It could also reveal some demographic information about accounts - if a registrar app is known to be popular in a certain country or to only have a UI in a certain language, it can indicate that a specific Ethereum address might be from that demographic. This is not unlike seeing a user send funds to a known exchange address.
To address these concerns, we ask app makers to make the process transparent and allow users to opt-out of either the referral code or the whole platform code being added to their secret.
This would also enable comparison of different clients' usage - again, this is by design. If a given platform doesn't want any of their numbers to be public, they can simply not implement it.
### A Reverse Code Registry
Since the source code is derived from the namehash, it's not reversible. Therefore, some sort of registry of names is needed to make sense of these names. Such registrars could be made on-chain or simply be a git text file with multiple forks across many repos. A registrar definition is outside the scope of this ENSIP, as if the ground truth was on-chain it would be relatively easy to game.
With a purely random number, it would take about 30,000 registrants to create a 10% chance of an accidental collision, and by 77,163 codes that chance increases to 50%. This means it should be quite rare for an accidental collision to happen, but it is still trivial to create such a collision or to spam a registry. Therefore, instead of trying to play the security cat and mouse game, we would rather leave the "truth" of the codes to their usage. If someone is using them to create a ranking website or launch a referral program, each should simply exercise common sense to maintain their own copy of the registry for the very top of the ranking, where it should be easier to disambiguate.
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-15: Name Normalization
### Abstract
This ENSIP standardizes Ethereum Name Service (ENS) name normalization process outlined in [ENSIP-1 § Name Syntax](/ensip/1#name-syntax).
### Motivation
* Since [ENSIP-1](/ensip/1) (originally [EIP-137](https://eips.ethereum.org/EIPS/eip-137)) was finalized in 2016, Unicode has [evolved](https://unicode.org/history/publicationdates.html) from version 8.0.0 to 15.0.0 and incorporated many new characters, including complex emoji sequences.
* ENSIP-1 does not state the version of Unicode.
* ENSIP-1 implies but does not state an explicit flavor of IDNA processing.
* [UTS-46](https://unicode.org/reports/tr46/) is insufficient to normalize emoji sequences. Correct emoji processing is only possible with [UTS-51](https://www.unicode.org/reports/tr51/).
* Validation tests are needed to ensure implementation compliance.
* The success of ENS has encouraged spoofing via the following techniques:
1. Insertion of zero-width characters.
2. Using names which normalize differently between algorithms.
3. Using names which appear differently between applications and devices.
4. Substitution of confusable (look-alike) characters.
5. Mixing incompatible scripts.
### Specification
* Unicode version `16.0.0`
* Normalization is a living specification and should use the latest stable version of Unicode.
* [`spec.json`](https://github.com/adraffy/ens-normalize.js/blob/main/derive/output/spec.json) contains all [necessary data](#description-of-specjson) for normalization.
* [`nf.json`](https://github.com/adraffy/ens-normalize.js/blob/main/derive/output/nf.json) contains all [necessary data](#description-of-nfjson) for [Unicode Normalization Forms](https://unicode.org/reports/tr15/) NFC and NFD.
#### Definitions
* Terms in **bold** throughout this document correspond with [components of `spec.json`](#description-of-specjson).
* A string is a sequence of Unicode codepoints.
* Example: `"abc"` is `61 62 63`
* An [Unicode emoji](https://www.unicode.org/reports/tr51/) is a [single entity](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) composed of one or more codepoints:
* An **Emoji Sequence** is the preferred form of an emoji, resulting from input that [tokenized](#tokenize) into an `Emoji` token.
* Example: `💩︎︎ [1F4A9]` → `Emoji[1F4A9 FE0F]`
* `1F4A9 FE0F` is the **Emoji Sequence**.
* [`spec.json`](#description-of-specjson) contains the complete [list of valid](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/emoji.md) **Emoji Sequences**.
* [Derivation](#derivation) defines which emoji are normalizable.
* Not all Unicode emoji are valid.
* `‼ [203C] double exclamation mark` → *error: Disallowed character*
* `🈁 [1F201] Japanese “here” button` → `Text["ココ"]`
* An **Emoji Sequence** may contain characters that are disallowed:
* `👩❤️👨 [1F469 200D 2764 FE0F 200D 1F468] couple with heart: woman, man` — contains ZWJ
* `#️⃣ [23 FE0F 20E3] keycap: #` — contains `23 (#)`
* `🏴 [1F3F4 E0067 E0062 E0065 E006E E0067 E007F]` — contains `E00XX`
* An **Emoji Sequence** may contain other emoji:
* Example: `❤️ [2764 FE0F] red heart` is a substring of `❤️🔥 [2764 FE0F 200D 1F525] heart on fire`
* Single-codepoint emoji may have various [presentation styles](https://www.unicode.org/reports/tr51/#Presentation_Style) on input:
* Default: `❤ [2764]`
* Text: `❤︎ [2764 FE0E]`
* Emoji: `❤️ [2764 FE0F]`
* However, these all [tokenize](#tokenize) to the same **Emoji Sequence**.
* All **Emoji Sequence** have explicit emoji-presentation.
* The convention of ignoring presentation is difficult to change because:
* Presentation characters (`FE0F` and `FE0E`) are **Ignored**
* [ENSIP-1](/ensip/1) did not treat emoji differently from text
* Registration hashes are immutable
* [Beautification](#annex-beautification) can be used to restore emoji-presentation in normalized names.
#### Algorithm
* Normalization is the process of canonicalizing a name before for [hashing](/ensip/1#namehash-algorithm).
* It is idempotent: applying normalization multiple times produces the same result.
* For user convenience, leading and trailing whitespace should be trimmed before normalization, as all whitespace codepoints are disallowed. Inner characters should remain unmodified.
* No string transformations (like case-folding) should be applied.
1. [Split](#split) the name into [labels](/ensip/1#name-syntax).
2. [Normalize](#normalize) each label.
3. [Join](#join) the labels together into a name again.
#### Normalize
1. [Tokenize](#tokenize) — transform the label into `Text` and `Emoji` tokens.
* If there are no tokens, the label cannot be normalized.
2. Apply [NFC](https://unicode.org/reports/tr15/#Norm_Forms) to each `Text` token.
* Example: `Text["à"]` → `[61 300] → [E0]` → `Text["à"]`
3. Strip `FE0F` from each `Emoji` token.
4. [Validate](#validate) — check if the tokens are valid and obtain the **Label Type**.
* The **Label Type** and **Restricted** state may be presented to user for additional security.
5. Concatenate the tokens together.
* Return the normalized label.
Examples:
1. `"_$A" [5F 24 41]` → `"_$a" [5F 24 61]` — *ASCII*
2. `"E︎̃" [45 FE0E 303]` → `"ẽ" [1EBD]` — *Latin*
3. `"𓆏🐸" [1318F 1F438]` → `"𓆏🐸" [1318F 1F438]` — *Restricted: Egyp*
4. `"nı̇ck" [6E 131 307 63 6B]` → *error: Disallowed character*
#### Tokenize
Convert a label into a list of `Text` and `Emoji` tokens, each with a payload of codepoints. The complete list of character types and [emoji sequences](#appendix-additional-resources) can be found in [`spec.json`](#description-of-specjson).
1. Allocate an empty codepoint buffer.
2. Find the longest **Emoji Sequence** that matches the remaining input.
* Example: `👨🏻💻 [1F468 1F3FB 200D 1F4BB]`
* Match (1): `👨️ [1F468] man`
* Match (2): `👨🏻 [1F468 1F3FB] man: light skin tone`
* Match (4): `👨🏻💻 [1F468 1F3FB 200D 1F4BB] man technologist: light skin tone` — longest match!
* `FE0F` is optional from the input during matching.
* Example: `👨❤️👨 [1F468 200D 2764 FE0F 200D 1F468]`
* Match: `1F468 200D 2764 FE0F 200D 1F468` — fully-qualified
* Match: `1F468 200D 2764 200D 1F468` — missing `FE0F`
* No match: `1F468 FE0F 200D 2764 FE0F 200D 1F468` — extra `FE0F`
* No match: `1F468 200D 2764 FE0F FE0F 200D 1F468` — has (2) `FE0F`
* This is equivalent to `/^(emoji1|emoji2|...)/` where `\uFE0F` is replaced with `\uFE0F?` and `*` is replaced with `\x2A`.
3. If an **Emoji Sequence** is found:
* If the buffer is nonempty, emit a `Text` token, and clear the buffer.
* Emit an `Emoji` token with the fully-qualified matching sequence.
* Remove the matched sequence from the input.
4. Otherwise:
1. Remove the leading codepoint from the input.
2. Determine the character type:
* If **Valid**, append the codepoint to the buffer.
* This set can be precomputed from the union of characters in all groups and their NFD decompositions.
* If **Mapped**, append the corresponding mapped codepoint(s) to the buffer.
* If **Ignored**, do nothing.
* Otherwise, the label cannot be normalized.
5. Repeat until all the input is consumed.
6. If the buffer is nonempty, emit a final `Text` token with its contents.
* Return the list of emitted tokens.
Examples:
1. `"xyz👨🏻" [78 79 7A 1F468 1F3FB]` → `Text["xyz"]` + `Emoji["👨🏻"]`
2. `"A💩︎︎b" [41 FE0E 1F4A9 FE0E FE0E 62]` → `Text["a"]` + `Emoji["💩️"]` + `Text["b"]`
3. `"a™️" [61 2122 FE0F]` → `Text["atm"]`
#### Validate
Given a list of `Emoji` and `Text` tokens, determine if the label is valid and return the **Label Type**. If any assertion fails, the name cannot be normalized.
1. If only `Emoji` tokens:
* Return `"Emoji"`
2. If a single `Text` token and every characters is ASCII (`00..7F`):
* `5F (_) LOW LINE` can only occur at the start.
* Must match `/^_*[^_]*$/`
* Examples: `"___"` and `"__abc"` are valid, `"abc__"` and `"_abc_"` are invalid.
* The 3rd and 4th characters must not both be `2D (-) HYPHEN-MINUS`.
* Must not match `/^..--/`
* Examples: `"ab-c"` and `"---a"`are valid, `"xn--"` and `----` are invalid.
* Return `"ASCII"`
* The label is free of **Fenced** and **Combining Mark** characters, and not confusable.
3. Concatenate all the tokens together.
* `5F (_) LOW LINE` can only occur at the start.
* The first and last characters cannot be **Fenced**.
* Examples: `"a’s"` and `"a・a"` are valid, `"’85"` and `"joneses’"` and `"・a・"` are invalid.
* **Fenced** characters cannot be contiguous.
* Examples: `"a・a’s"` is valid, `"6’0’’"` and `"a・・a"` are invalid.
4. The first character of every `Text` token must not be a **Combining Mark**.
5. Concatenate the `Text` tokens together.
6. Find the first **Group** that contain every text character:
* If no group is found, the label cannot be normalized.
7. If the group is not **CM Whitelisted**:
* Apply NFD to the concatenated text characters.
* For every contiguous sequence of **NSM** characters:
* Each character must be unique.
* Example: `"x̀̀" [78 300 300]` has (2) grave accents.
* The number of **NSM** characters cannot exceed **Maximum NSM** (4).
* Example: ` "إؐؑؒؓؔ" [625 610 611 612 613 614]` has (6) **NSM**.
8. [Wholes](#wholes) — check if text characters form a confusable.
9. The label is valid.
* Return the name of the group as the **Label Type**.
Examples:
1. `Emoji["💩️"]` + `Emoji["💩️"]` → `"Emoji"`
2. `Text["abc$123"]` → `"ASCII"`
3. `Emoji["🚀️"]` + `Text["à"]` → `"Latin"`
#### Wholes
A label is [whole-script confusable](https://unicode.org/reports/tr39/#def_whole_script_confusables) if a similarly-looking valid label can be constructed using one alternative character from a different group. The complete list of **Whole Confusables** can be found in [`spec.json`](#description-of-specjson). Each **Whole Confusable** has a set of non-confusing characters (`"valid"`) and a set of confusing characters (`"confused"`) where each character may be the member of one or more groups.
Example: **Whole Confusable** for `"g"`
| Type | Code | Form | Character | Latn | Hani | Japn | Kore | Armn | Cher | Lisu |
| :------: | -----: | :--: | :----------------------- | :--: | :--: | :--: | :--: | :--: | :--: | :--: |
| valid | `67` | `g` | LATIN SMALL LETTER G | A | A | A | A | | | |
| confused | `581` | `ց` | ARMENIAN SMALL LETTER CO | | | | | B | | |
| confused | `13C0` | `Ꮐ` | CHEROKEE LETTER NAH | | | | | | C | |
| confused | `13F3` | `Ᏻ` | CHEROKEE LETTER YU | | | | | | C | |
| confused | `A4D6` | `ꓖ` | LISU LETTER GA | | | | | | | D |
1. Allocate an empty character buffer.
2. Start with the set of **ALL** groups.
3. For each unique character in the label:
* If the character is **Confused** (a member of a **Whole Confusable**):
* Retain groups with **Whole Confusable** characters excluding the **Confusable Extent** of the matching **Confused** character.
* If no groups remain, the label is not confusable.
* The **Confusable Extent** is the fully-connected graph formed from different groups with the same confusable and different confusables of the same group.
* The mapping from **Confused** to **Confusable Extent** can be precomputed.
* In the table above, **Whole Confusable** for `"g"`, the rectangle formed by each capital letter is a **Confusable Extent**:
* `A` is \[`g`] ⊗ \[*Latin*, *Han*, *Japanese*, *Korean*]
* `B` is \[`ց`] ⊗ \[*Armn*]
* `C` is \[`Ꮐ`, `Ᏻ`] ⊗ \[*Cher*]
* `D` is \[`ꓖ`] ⊗ \[*Lisu*]
* A **Confusable Extent** can span multiple characters and multiple groups. Consider the (incomplete) **Whole Confusable** for `"o"`:
* `6F (o) LATIN SMALL LETTER O` → *Latin*, *Han*, *Japanese*, and *Korean*
* `3007 (〇) IDEOGRAPHIC NUMBER ZERO` → *Han*, *Japanese*, *Korean*, and *Bopomofo*
* **Confusable Extent** is \[`o`, `〇`] ⊗ \[*Latin*, *Han*, *Japanese*, *Korean*, *Bopomofo*]
* If the character is **Unique**, the label is not confusable.
* This set can be precomputed from characters that appear in exactly one group and are not **Confused**.
* Otherwise:
* Append the character to the buffer.
4. If any **Confused** characters were found:
* If there are no buffered characters, the label is confusable.
* If any of the remaining groups contain all of the buffered characters, the label is confusable.
* Example: `"0х" [30 445]`
1. `30 (0) DIGIT ZERO`
* Not **Confused** or **Unique**, add to buffer.
2. `445 (х) CYRILLIC SMALL LETTER HA`
* **Confusable Extent** is \[`х`, `4B3 (ҳ) CYRILLIC SMALL LETTER HA WITH DESCENDER`] ⊗ \[*Cyrillic*]
* **Whole Confusable** excluding the extent is \[`78 (x) LATIN SMALL LETTER X`, ...] → \[*Latin*, ...]
* Remaining groups: **ALL** ∩ \[*Latin*, ...] → \[*Latin*, ...]
3. There was (1) buffered character:
* *Latin* also contains `30` → `"0x" [30 78]`
4. The label is confusable.
5. The label is not confusable.
A label composed of confusable characters isn't necessarily confusable.
* Example: `"тӕ" [442 4D5]`
1. `442 (т) CYRILLIC SMALL LETTER TE`
* **Confusable Extent** is \[`т`] ⊗ \[*Cyrillic*]
* **Whole Confusable** excluding the extent is \[`3C4 (τ) GREEK SMALL LETTER TAU`] → \[*Greek*]
* Remaining groups: **ALL** ∩ \[*Greek*] → \[*Greek*]
2. `4D5 (ӕ) CYRILLIC SMALL LIGATURE A IE`
* **Confusable Extent** is \[`ӕ`] ⊗ \[*Greek*]
* **Whole Confusable** excluding the extent is \[`E6 (æ) LATIN SMALL LETTER AE`] → \[*Latin*]
* Remaining groups: \[*Greek*] ∩ \[*Latin*] → ∅
3. No groups remain so the label is not confusable.
#### Split
* Partition a name into labels, separated by `2D (.) FULL STOP`, and return the resulting array.
* Example: `"abc.123.eth"` → `["abc", "123", "eth"]`
* The empty string is 0-labels: `""` → `[]`
#### Join
* Assemble an array of labels into a name, inserting `2D (.) FULL STOP` between each label, and return the resulting string.
* Example: `["abc", "123", "eth"]` → `"abc.123.eth"`
### Description of `spec.json`
* **Groups** (`"groups"`) — [groups](#appendix-additional-resources) of characters that can constitute a label
* `"name"` — ASCII name of the group (or abbreviation if **Restricted**)
* Examples: *Latin*, *Japanese*, *Egyp*
* **Restricted** (`"restricted"`) — **`true`** if [Excluded](https://www.unicode.org/reports/tr31#Table_Candidate_Characters_for_Exclusion_from_Identifiers) or [Limited-Use](https://www.unicode.org/reports/tr31/#Table_Limited_Use_Scripts) script
* Examples: *Latin* → **`false`**, *Egyp* → **`true`**
* `"primary"` — subset of characters that define the group
* Examples: `"a"` → *Latin*, `"あ"` → *Japanese*, `"𓀀"` → *Egyp*
* `"secondary"` — subset of characters included with the group
* Example: `"0"` → *Common* but mixable with *Latin*
* **CM Whitelist(ed)** (`"cm"`) — (optional) set of allowed compound sequences in NFC
* Each compound sequence is a character followed by one or more **Combining Marks**.
* Example: `à̀̀` → `E0 300 300`
* Currently, every group that is **CM Whitelist** has zero compound sequences.
* **CM Whitelisted** is effectively **`true`** if `[]` otherwise **`false`**
* **Ignored** (`"ignored"`) — [characters](#appendix-additional-resources) that are ignored during normalization
* Example: `34F (�) COMBINING GRAPHEME JOINER`
* **Mapped** (`"mapped"`) — characters that are mapped to a sequence of **valid** characters
* Example: `41 (A) LATIN CAPITAL LETTER A` → `[61 (a) LATIN SMALL LETTER A]`
* Example: `2165 (Ⅵ) ROMAN NUMERAL SIX` → `[76 (v) LATIN SMALL LETTER V, 69 (i) LATIN SMALL LETTER I]`
* **Whole Confusable** (`"wholes"`) — groups of characters that look similar
* `"valid"` — subset of confusable characters that are allowed
* Example: `34 (4) DIGIT FOUR`
* **Confused** (`"confused"`) — subset of confusable characters that confuse
* Example: `13CE (Ꮞ) CHEROKEE LETTER SE`
* **Fenced** (`"fenced"`) — [characters](#appendix-additional-resources) that cannot be first, last, or contiguous
* Example: `2044 (⁄) FRACTION SLASH`
* **Emoji Sequence(s)** (`"emoji"`) — valid [emoji sequences](#appendix-additional-resources)
* Example: `👨💻 [1F468 200D 1F4BB] man technologist`
* **Combining Marks / CM** (`"cm"`) — [characters](#appendix-additional-resources) that are [Combining Marks](https://unicode.org/faq/char_combmark.html)
* **Non-spacing Marks / NSM** (`"nsm"`) — valid [subset](#appendix-additional-resources) of **CM** with general category (`"Mn"` or `"Me"`)
* **Maximum NSM** (`"nsm_max"`) — maximum sequence length of unique **NSM**
* **Should Escape** (`"escape"`) — [characters](#appendix-additional-resources) that shouldn't be printed
* **NFC Check** (`"nfc_check"`) — valid [subset](#appendix-additional-resources) of characters that [may require NFC](https://unicode.org/reports/tr15/#NFC_QC_Optimization)
### Description of `nf.json`
* `"decomp"` — [mapping](https://www.unicode.org/reports/tr44/tr44-30.html#Character_Decomposition_Mappings) from a composed character to a sequence of (partially)-decomposed characters
* [`UnicodeData.txt`](https://www.unicode.org/reports/tr44/tr44-30.html#UnicodeData.txt) where `Decomposition_Mapping` exists and does not have a [formatting tag](https://www.unicode.org/reports/tr44/tr44-30.html#Formatting_Tags_Table)
* `"exclusions"` — set of characters for which the `"decomp"` mapping is not applied when forming a composition
* [`CompositionExclusions.txt`](https://www.unicode.org/reports/tr44/tr44-30.html#CompositionExclusions.txt)
* `"ranks"` — sets of characters with increasing [`Canonical_Combining_Class`](https://www.unicode.org/reports/tr44/tr44-30.html#Canonical_Combining_Class_Values)
* [`UnicodeData.txt`](https://www.unicode.org/reports/tr44/tr44-30.html#UnicodeData.txt) grouped by `Canonical_Combining_Class`
* Class `0` is not included
* `"qc"` — set of characters with property [`NFC_QC`](https://www.unicode.org/reports/tr44/tr44-30.html#Decompositions_and_Normalization) of value `N` or `M`
* [`DerivedNormalizationProps.txt`](https://www.unicode.org/reports/tr44/tr44-30.html#DerivedNormalizationProps.txt)
* **NFC Check** (from [`spec.json`](#description-of-specjson)) is a subset of this set
### Derivation
* [IDNA 2003](https://unicode.org/Public/idna/15.1.0/IdnaMappingTable.txt)
* `UseSTD3ASCIIRules` is **`true`**
* `VerifyDnsLength` is **`false`**
* `Transitional_Processing` is **`false`**
* The following [deviations](https://unicode.org/reports/tr46/#Table_Deviation_Characters) are **valid**:
* `DF (ß) LATIN SMALL LETTER SHARP S`
* `3C2 (ς) GREEK SMALL LETTER FINAL SIGMA`
* `CheckHyphens` is **`false`** ([WHATWG URL Spec § 3.3](https://url.spec.whatwg.org/#idna))
* `CheckBidi` is **`false`**
* [ContextJ](https://datatracker.ietf.org/doc/html/rfc5892#appendix-A.1):
* `200C (�) ZERO WIDTH NON-JOINER` (ZWNJ) is **disallowed everywhere**.
* `200D (�) ZERO WIDTH JOINER` (ZWJ) is **only allowed** in emoji sequences.
* [ContextO](https://datatracker.ietf.org/doc/html/rfc5892#appendix-A.3):
* `B7 (·) MIDDLE DOT` is **disallowed**.
* `375 (͵) GREEK LOWER NUMERAL SIGN` is **disallowed**.
* `5F3 (׳) HEBREW PUNCTUATION GERESH` and `5F4 (״) HEBREW PUNCTUATION GERSHAYIM` are *Greek*.
* `30FB (・) KATAKANA MIDDLE DOT` is **Fenced** and *Han*, *Japanese*, *Korean*, and *Bopomofo*.
* Some [Extended Arabic Numerals](https://en.wikipedia.org/wiki/Arabic_numerals) are **mapped**:
* `6F0 (۰)` → `660 (٠) ARABIC-INDIC DIGIT ZERO`
* `6F1 (۱)` → `661 (١) ARABIC-INDIC DIGIT ONE`
* `6F2 (۲)` → `662 (٢) ARABIC-INDIC DIGIT TWO`
* `6F3 (۳)` → `663 (٣) ARABIC-INDIC DIGIT THREE`
* `6F7 (۷)` → `667 (٧) ARABIC-INDIC DIGIT SEVEN`
* `6F8 (۸)` → `668 (٨) ARABIC-INDIC DIGIT EIGHT`
* `6F9 (۹)` → `669 (٩) ARABIC-INDIC DIGIT NINE`
* [Punycode](https://datatracker.ietf.org/doc/html/rfc3492) is not decoded.
* The following ASCII characters are **valid**:
* `24 ($) DOLLAR SIGN`
* `5F (_) LOW LINE` with [restrictions](#validate)
* Only label separator is `2E (.) FULL STOP`
* No character maps to this character.
* This simplifies name detection in unstructured text.
* The following alternatives are **disallowed**:
* `3002 (。) IDEOGRAPHIC FULL STOP`
* `FF0E (.) FULLWIDTH FULL STOP`
* `FF61 (。) HALFWIDTH IDEOGRAPHIC FULL STOP`
* [Many characters](#appendix-additional-resources) are **disallowed** for various reasons:
* Nearly all punctuation are **disallowed**.
* Example: `589 (։) ARMENIAN FULL STOP`
* All parentheses and brackets are **disallowed**.
* Example: `2997 (⦗) LEFT BLACK TORTOISE SHELL BRACKET`
* Nearly all vocalization annotations are **disallowed**.
* Example: `294 (ʔ) LATIN LETTER GLOTTAL STOP`
* Obsolete, deprecated, and ancient characters are **disallowed**.
* Example: `463 (ѣ) CYRILLIC SMALL LETTER YAT`
* Combining, modifying, reversed, flipped, turned, and partial variations are **disallowed**.
* Example: `218A (↊) TURNED DIGIT TWO`
* When multiple weights of the same character exist, the variant closest to "heavy" is selected and the rest **disallowed**.
* Example: `🞡🞢🞣🞤✚🞥🞦🞧` → `271A (✚) HEAVY GREEK CROSS`
* This occasionally selects an emoji.
* Example: ✔️ or `2714 (✔︎) HEAVY CHECK MARK` is selected instead of `2713 (✓) CHECK MARK`
* Many visually confusable characters are **disallowed**.
* Example: `131 (ı) LATIN SMALL LETTER DOTLESS I`
* Many ligatures, *n*-graphs, and *n*-grams are **disallowed.**
* Example: `A74F (ꝏ) LATIN SMALL LETTER OO`
* Many esoteric characters are **disallowed**.
* Example: `2376 (⍶) APL FUNCTIONAL SYMBOL ALPHA UNDERBAR`
* Many hyphen-like characters are **mapped** to `2D (-) HYPHEN-MINUS`:
* `2010 (‐) HYPHEN`
* `2011 (‑) NON-BREAKING HYPHEN`
* `2012 (‒) FIGURE DASH`
* `2013 (–) EN DASH`
* `2014 (—) EM DASH`
* `2015 (―) HORIZONTAL BAR`
* `2043 (⁃) HYPHEN BULLET`
* `2212 (−) MINUS SIGN`
* `23AF (⎯) HORIZONTAL LINE EXTENSION`
* `23E4 (⏤) STRAIGHTNESS`
* `FE58 (﹘) SMALL EM DASH`
* `2E3A (⸺) TWO-EM DASH` → `"--"`
* `2E3B (⸻) THREE-EM DASH` → `"---"`
* Characters are assigned to **Groups** according to [Unicode Script\_Extensions](https://www.unicode.org/reports/tr24/#Script_Extensions_Def).
* **Groups** may contain [multiple scripts](#appendix-additional-resources):
* Only *Latin*, *Greek*, *Cyrillic*, *Han*, *Japanese*, and *Korean* have access to *Common* characters.
* *Latin*, *Greek*, *Cyrillic*, *Han*, *Japanese*, *Korean*, and *Bopomofo* only permit specific **Combining Mark** sequences.
* *Han*, *Japanese*, and *Korean* have access to `a-z`.
* **Restricted** groups are always single-script.
* [Unicode augmented script sets](https://www.unicode.org/reports/tr39/#Mixed_Script_Detection)
* Scripts *Braille*, *Linear A*, *Linear B*, and *Signwriting* are **disallowed**.
* `27 (') APOSTROPHE` is **mapped** to `2019 (’) RIGHT SINGLE QUOTATION MARK` for convenience.
* Ethereum symbol (`39E (Ξ) GREEK CAPITAL LETTER XI`) is case-folded and *Common*.
* Emoji:
* All emoji are [fully-qualified](https://www.unicode.org/reports/tr51/#def_fully_qualified_emoji).
* Digits (`0-9`) are [not emoji](#appendix-additional-resources).
* Emoji [mapped to non-emoji by IDNA](#appendix-additional-resources) cannot be used as emoji.
* Emoji [disallowed by IDNA](#appendix-additional-resources) with default text-presentation are **disabled**:
* `203C (‼️) double exclamation mark`
* `2049 (⁉️) exclamation question mark `
* Remaining emoji characters are marked as **disallowed** (for text processing).
* All `RGI_Emoji_ZWJ_Sequence` are **enabled**.
* All `Emoji_Keycap_Sequence` are **enabled**.
* All `RGI_Emoji_Tag_Sequence` are **enabled**.
* All `RGI_Emoji_Modifier_Sequence` are **enabled**.
* All `RGI_Emoji_Flag_Sequence` are **enabled**.
* `Basic_Emoji` of the form `[X FE0F]` are **enabled**.
* Emoji with default emoji-presentation are **enabled** as `[X FE0F]`.
* Remaining single-character emoji are **enabled** as `[X FE0F]` (explicit emoji-presentation).
* All singular Skin-color Modifiers are **disabled**.
* All singular Regional Indicators are **disabled**.
* Blacklisted emoji are **disabled**.
* Whitelisted emoji are **enabled**.
* Confusables:
* Nearly all [Unicode Confusables](https://www.unicode.org/Public/security/15.1.0/confusables.txt)
* Emoji are not confusable.
* ASCII confusables are case-folded.
* Example: `61 (a) LATIN SMALL LETTER A` confuses with `13AA (Ꭺ) CHEROKEE LETTER GO`
### Backwards Compatibility
* 99% of names are still valid.
* Preserves as much [Unicode IDNA](https://unicode.org/reports/tr46/) and [WHATWG URL](https://url.spec.whatwg.org/#idna) compatibility as possible.
* Only [valid emoji sequences](#appendix-additional-resources) are permitted.
### Security Considerations
* Unicode presentation may vary between applications and devices.
* Unicode text is ultimately subject to font-styling and display context.
* Unsupported characters (`�`) may appear unremarkable.
* Normalized single-character emoji sequences do not retain their explicit emoji-presentation and may display with [text or emoji](https://www.unicode.org/reports/tr51/#Presentation_Style) presentation styling.
* `❤︎` — text-presentation and default-color
* `❤︎` — text-presentation and green -color
* `❤️` — emoji-presentation and green -color
* Unsupported emoji sequences with ZWJ may appear indistinguishable from those without ZWJ.
* `💩💩 [1F4A9 1F4A9]`
* `💩💩 [1F4A9 200D 1F4A9]` → *error: Disallowed character*
* Names composed of labels with varying bidi properties [may appear differently](https://discuss.ens.domains/t/bidi-label-ordering-spoof/15824) depending on context.
* Normalization does not enforce single-directional names.
* Names may be composed of labels of different directions but normalized labels are never bidirectional.
* \[LTR].\[RTL] `bahrain.مصر`
* \[LTR+RTL] `bahrainمصر` → *error: Illegal mixture: Latin + Arabic*
* Not all normalized names are visually unambiguous.
* This ENSIP only addresses **single-character** [confusables](https://www.unicode.org/reports/tr39/).
* There exist confusable **multi-character** sequences:
* `"ஶ்ரீ" [BB6 BCD BB0 BC0]`
* `"ஸ்ரீ" [BB8 BCD BB0 BC0]`
* There exist confusable emoji sequences:
* `🚴 [1F6B4]` and `🚴🏻 [1F6B4 1F3FB]`
* `🇺🇸 [1F1FA 1F1F8]` and `🇺🇲 [1F1FA 1F1F2]`
* `♥ [2665] BLACK HEART SUIT` and `❤ [2764] HEAVY BLACK HEART`
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
### Appendix: Reference Specifications
* [EIP-137: Ethereum Domain Name Service](https://eips.ethereum.org/EIPS/eip-137)
* [ENSIP-1: ENS](/ensip/1)
* [UAX-15: Normalization Forms](https://unicode.org/reports/tr15/)
* [UAX-24: Script Property](https://www.unicode.org/reports/tr24/)
* [UAX-29: Text Segmentation](https://unicode.org/reports/tr29/)
* [UAX-31: Identifier and Pattern Syntax](https://www.unicode.org/reports/tr31/)
* [UTS-39: Security Mechanisms](https://www.unicode.org/reports/tr39/)
* [UAX-44: Character Database](https://www.unicode.org/reports/tr44/)
* [UTS-46: IDNA Compatibility Processing](https://unicode.org/reports/tr46/)
* [UTS-51: Emoji](https://www.unicode.org/reports/tr51)
* [RFC-3492: Punycode](https://datatracker.ietf.org/doc/html/rfc3492)
* [RFC-5891: IDNA: Protocol](https://datatracker.ietf.org/doc/html/rfc5891)
* [RFC-5892: The Unicode Code Points and IDNA](https://datatracker.ietf.org/doc/html/rfc5892)
* [Unicode CLDR](https://github.com/unicode-org/cldr)
* [WHATWG URL: IDNA](https://url.spec.whatwg.org/#idna)
### Appendix: Additional Resources
* [Supported Groups](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/groups.md)
* [Supported Emoji](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/emoji.md)
* [Additional Disallowed Characters](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/disallowed.csv)
* [Ignored Characters](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/ignored.csv)
* [Should Escape Characters ](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/escape.csv)
* [Combining Marks](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/cm.csv)
* [Non-spacing Marks](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/nsm.csv)
* [Fenced Characters](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/fenced.csv)
* [NFC Quick Check](https://github.com/adraffy/ens-normalize.js/blob/main/tools/ensip/nfc_check.csv)
### Appendix: Validation Tests
A list of [validation tests](https://github.com/adraffy/ens-normalize.js/blob/main/validate/tests.json) are provided with the following interpretation:
* Already Normalized: `{name: "a"}` → `normalize("a")` is `"a"`
* Need Normalization: `{name: "A", norm: "a"}` → `normalize("A")` is `"a"`
* Expect Error: `{name: "@", error: true}` → `normalize("@")` throws
### Annex: Beautification
Follow [algorithm](#algorithm), except:
* Do not strip `FE0F` from `Emoji` tokens.
* Replace `3BE (ξ) GREEK SMALL LETTER XI` with `39E (Ξ) GREEK CAPITAL LETTER XI` if the label isn't *Greek*.
* Example: `normalize("‐Ξ1️⃣") [2010 39E 31 FE0F 20E3]` is `"-ξ1⃣" [2D 3BE 31 20E3]`
* Example: `beautify("-ξ1⃣") [2D 3BE 31 20E3]"` is `"-Ξ1️⃣" [2D 39E 31 FE0F 20E3]`
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-16: Metadata Event Discovery
### Abstract
This ENSIP specifies APIs for querying metadata directly on the resolver for EIP-3668 (CCIP Read: Secure offchain data retrieval) enabled names. EIP-3668 will power many domains in the future, however since the retrieval mechanism uses wildcard + offchain resolver, there is no standardised way to retrieve important metadata information such as which L2/offchain database the records are stored on and where JSON RPC endpoint is to find event log information.
### Motivation
With EIP-3668 subdomains already starting to see wide adoption, it is important that there is a standardised way to discover and access metadata about offchain names.
This ENSIP allows third-party indexing services to listen to the `MetadataChanged` event to automatically discover and index metadata from different chains and smart contracts, without relying on centralised RPC endpoint repositories.
### Specification
Compliant resolvers MUST implement the following interface:
```solidity
// To be included in
// https://github.com/ensdomains/ens-contracts/blob/staging/contracts/resolvers/Resolver.sol
interface IOffchainResolverMetadataProvider {
/**
* @dev Returns metadata for discovering the location of offchain name data
* @param name DNS-encoded name to query
* @return rpcURLs The JSON RPC endpoint for querying offchain data (optional, may be empty array)
* @return chainId The chain ID where the data is stored (format for non-EVM systems to be determined)
* @return baseRegistry The base registry address on the target chain that emits events (optional, may be zero address)
*/
function metadata(bytes calldata name)
external
view
returns (
string[] memory rpcURLs,
uint256 chainId,
address baseRegistry
);
event MetadataChanged(
bytes name, // DNS-encoded name
string[] rpcURLs, // JSON RPC endpoint (optional, may be empty array)
uint256 chainId, // Chain identifier (format for non-EVM systems to be determined)
address baseRegistry // Base registry address (optional, may be zero address)
);
}
```
**Requirements:**
* `name` must be provided to call `metadata` function. When indexing `MetadataChanged` event, indexers MUST apply the `name` to all names that have the suffixes of the `name`.
* `chainId` must be provided. For EVM-compatible chains, `chainId` SHOULD match the chain's EIP-155 identifier. A chainId of 0 means a non-EVM chain or off-chain database.
* `rpcURLs` is optional and may be an empty array.
* `baseRegistry` is optional and may be the zero address. If a non-zero address is specified, events will be emitted from this address. The interface of this contract is yet to be determined.
#### metadata function
The metadata function allows resolvers to dynamically provide information about where offchain data for a given name can be queried. This function returns the same information as would be emitted in a MetadataChanged event: the JSON RPC endpoint URLs, the chain ID where the data resides, and the base registry address on the target chain.
#### MetadataChanged Event
The MetadataChanged event emits the same information the `metadata` function returns so that indexers can subscribe to the event as the details change rather than periodically querying the function.
**Key Terminology:**
* **registry** = A contract that manages name ownership and hierarchical relationships for a set of subnames. The base registry manages top-level domains (also known as root registry within the v2 contract), while subregistries manage names under a specific parent
* **subregistry** = A registry contract that manages subnames under a parent name. Linked from a parent registry via SubregistryUpdate events
* **registry id/tokenId** = The unique identifier for a name NFT, derived from the labelhash and version id that increments every time the permission of the name changes effectively invalidating any permissions or approvals tied to the old token ID.
* **EAC(Enhanced Access Control)** = a general-purpose access control base class. `resource` is a unique key to manage the resource which changes every time `tokenId` changes. For more detail, read [the namechain README](https://github.com/ensdomains/namechain/tree/main/contracts#access-control). EAC may not be the only way to manage access control and other events may be added in future.
* **node** = In v1, node is a unique identifier of the name derived by a `namehash` logic. In ENS v2, `node` is a placeholder node for compatibility with standard resolver behavior and always set to 0. The full ENS name attached to the resolver needs to be reconstructed by traversing registry hierarchy set by `SubregistryUpdate`.
#### rpcUrls Events
`rpcUrls` url endpoint emits the following jsonrpc events when chainId is not `0`. When chainId is `0` it may emit custom events yet to be determined.
##### Registry Events
```solidity
// Emitted when a new subname is registered.
// A subname without expiration should set type(uint256).max
// Context can attach any arbitrary data, such as resource id to keep track of EAC
event NameRegistered(
uint256 indexed tokenId,
string label,
uint64 expiration,
address registeredBy,
uint256 context
);
// Emitted when a new token id is generated
event TokenRegenerated(
uint256 oldTokenId,
uint256 newTokenId,
uint256 context
);
// Standard ERC1155 transfer event for name ownership changes
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 value // must always be 1
);
// Standard ERC1155 transfer event for multiple name ownership changes
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
// Emitted when a name is renewed
event ExpiryUpdated(
uint256 indexed tokenId,
uint64 newExpiration
);
// Emitted when subregistry is updated
event SubregistryUpdated(
uint256 indexed id,
address subregistry
);
// Emitted when resolver is updated
event ResolverUpdated(
uint256 indexed id,
address resolver
);
```
##### Resolver Events
```solidity
event AddressChanged(
bytes32 indexed node,
uint256 coinType,
bytes newAddress
);
event AddrChanged(
bytes32 indexed node,
address a
);
event TextChanged(
bytes32 indexed node,
string indexed indexedKey,
string key,
string value
);
event ContenthashChanged(
bytes32 indexed node,
bytes hash
);
event NameChanged(
bytes32 indexed node,
string name)
;
```
### Rationale
This ENSIP addresses a key limitation of EIP-3668: while it enables offchain data retrieval, it provides no standardized way for third parties to discover where that data lives or how to index it.
By providing metadata at the resolver level, this ENSIP enables:
1. **Automatic indexer discovery** - Indexers can discover new L2/offchain data sources by listening to events, without requiring manual configuration or centralized registries of RPC endpoints.
2. **Flexible data sources** - The optional nature of `rpcURLs` and `baseRegistry` accommodates different deployment patterns: from fully decentralized L2 registries that emit events, to custom databases that may emit APIs yet to be determined that are more suitable to index non-EVM chains or offchain database names.
3. **Future extensibility** - By requiring `chainId` but leaving the non-EVM format undefined, this ENSIP establishes the pattern while remaining open to future non-EVM integrations.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-17: Gasless DNS Resolution
### Abstract
This standard describes a mechanism by which users can specify ENS resolvers and resolution data as DNS TXT records, resulting in a system where DNS names are resolvable in ENS with no onchain actions required.
### Motivation
ENS has had DNS integration for some time, facilitated by the ability to prove the contents of a DNS TXT record onchain, and thereby claim the corresponding name in the ENS registry. This has several shortcomings, the most notable of which is the high transaction fees associated, as verifying a DNSSEC proof often costs in excess of 1,000,000 gas.
Wildcard resolution (ENSIP-10) and CCIP-Read (EIP-3668) now permit a new approach, by which DNSSEC proofs are fetched and verified at resolution time instead. This permits users to enable ENS resolution of their names simply by setting a TXT record on their DNS name and enabling DNSSEC.
### Specification
A new resolver, `OffchainDNSResolver`, is deployed and set as the resolver for all DNS TLDs; this resolver will be consulted whenever resolution is attempted for a nonexistent subdomain of these TLDs. The resolver then initiates a CCIP-Read request to a gateway which fetches and returns DNSSEC proofs for TXT records on that name. In the CCIP-Read callback function, the resolver verifies the DNSSEC proofs using an updated version of the DNSSEC oracle, and if they verify correctly, decodes the address of a resolver and optional extra data from the TXT record. The resolution request is then completed by invoking the resolver, optionally passing the extra data contained in the TXT record to enable it to vary its response dynamically.
#### TXT record format
Compliant TXT records MUST adhere to this format:
```ts
ENS1 [context]
```
Where:
* `ENS1` is a fixed string, identifying this TXT record as a gasless ENS record.
* `resolver-name-or-address` is either the 0x-prefixed hexadecimal address or the ENS name of the resolver to use to resolve queries for this name. If an ENS name is supplied, the name MUST be resolvable without using ENSIP-10 - meaning that the name MUST have a resolver set in the ENS registry, and the resolver MUST implement the `addr` function, which MUST NOT initiate a CCIP-Read request using `OffchainData`.
* `context` is arbitrary additional data that may be passed to the resolver to complete the request (see below).
#### Resolution Process
##### Summary
The `OffchainDNSResolver` decodes or resolves the address of the resolver to use from `resolver-name-or-address`, and calls whichever of `IExtendedDNSResolver.resolve`, `IExtendedResolver.resolve` or a legacy resolution function is first supported. If either `resolve` function is invoked, nested CCIP-Read requests are handled correctly.
##### Detailed Description
`OffchainDNSResolver` implements `resolve` by initiating a CCIP-Read request, reverting with `OffchainLookup` and specifying the address of a CCIP-Read gateway capable of fetching and returning DNSSEC signed DNS records. The callback function for the CCIP-Read request implements the following logic:
1. Use the DNSSEC oracle to verify the returned RRSet. If verification fails, revert.
2. For each record in the returned RRSet:
1. Check if the RR name matches the name being resolved and the record type is TXT. If either check fails, continue to the next record.
2. Check if the first field in the TXT record starts with `ENS1 `. If not, continue to the next record.
3. Decode `resolver-name-or-address` and `context` from the text record.
4. If `resolver-name-or-address` contains a `.` character:
1. Compute the namehash of `resolver-name-or-address`.
2. Call `resolver(bytes32)` on the registry, passing in the namehash. If the registry returns `0`, continue to the next TXT record.
3. Call `addr(bytes32)` on the resolver address returned in step ii. If the resolver returns `0`, continue to the next TXT record.
4. Treat the returned address as the resolver address to use in subsequent steps.
5. If `resolver-name-or-address` does not contain a '.' character, treat it as a hexadecimal address and decode it. Treat the decoded address as the resolver address to use in subsequent steps.
6. Using ERC165, check if the returned resolver supports `IExtendedDNSResolver`. If it does, call `resolve(bytes name, bytes query, bytes context)`, passing `context` from the TXT record as the last argument. The call to `resolve` may use CCIP-Read; if it does, reverts will be handled appropriately. Return the result of this call as the result of the initial resolution request and halt.
7. Using ERC165, check if the returned resolver supporst `IExtendedResolver`. If it does, call `resolve(bytes name, bytes query)`. The call to `resolve` may use CCIP-Read; if it does, reverts will be handled appropriately. Return the result of this call as the result of the initial resolution request and halt.
8. Otherwise, call the resolver with calldata equal to the `query` originally supplied to `OffchainDNSResolver.resolve` and return its result as the result of the initial resolution request and halt. This resolution path does NOT support nested CCIP-Read requests.
The `IExtendedDNSResolver` interface is defined as follows:
```go
interface IExtendedDNSResolver {
function resolve(
bytes memory name,
bytes memory data,
bytes memory context
) external view returns (bytes memory);
```
This acts as an extension of `IExtendedResolver` defined in ENSIP-10, providing the additional `context` argument, containing any supplementary data from the TXT record.
Note that a TXT record may contain multiple text fields; in this implementation only the first field of each TXT record is considered. TXT record fields are limited to a maximum of 255 bytes each.
#### DNSSEC Gateway API
The DNSSEC Gateway implements the following API over CCIP-Read:
```go
struct RRSetWithSignature {
bytes rrset;
bytes sig;
}
interface IDNSGateway {
function resolve(
bytes memory name,
uint16 qtype
) external returns (RRSetWithSignature[] memory);
}
```
Where:
* `name` is a DNS-encoded name to query.
* `qtype` is a DNS QTYPE as defined in RFC1034 - for example, `TXT` = 16.
The returned `rrset`s are in the format described in section 5.3.2 of RFC4035: The RRDATA section from the RRSIG without the signature data, followed by a series of canonicalised RR records that the signature applies to. One RRSET is returned for each step in the chain of trust, starting with the DNSKEY RRSET for the DNS root `.`, and ending with the requested RRSET, if it exists.
A Solidity DNSSEC implementation for decoding and verifying RRSET data is available at [https://github.com/ensdomains/ens-contracts/blob/staging/contracts/dnssec-oracle/](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/dnssec-oracle/).
### Backwards Compatibility
DNS names imported using the existing functionality will continue to function as before, and new names can still be imported using the DNS import functionality. If an imported name exists, it is used to resolve the request, and any TXT records for gasless DNSSEC are ignored. If desired, the owner of the name can set the resolver to `address(0)` to cause resolution to fall back to gasless DNSSEC.
### Security Considerations
Gasless DNSSEC relies on a gateway and CCIP-Read to fetch cryptographic proofs of the chain of trust between the DNS root and the desired text record. It uses the same code, and hence has the same trust model, as the DNS import functionality; forging a DNS record would require access to a signing key somewhere in the chain of trust between DNS root and the record in question.
Due to the use of a gateway service to generate responses, there is additional risk of unavailability: the gateway could be out of operation, or could choose to selectively refuse to answer (censor) certain queries.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-18: Profile Text Records
### Abstract
This ENSIP which extends [ENSIP-5: Text Records](https://docs.ens.domains/ensip/5) defines a set of text records that should be used for profile information, along with the format that each should have.
### Motivation
ENS names have become increasingly popular to use as an identifying profile across the Ethereum ecosystem. Although many apps have started integrating ENS "profiles", the only defined global text record keys are in ENSIP-5. These global keys were defined based on the usecase of ENS names at the time, and were not created with profiles in mind.
This specification extends the existing set of global keys, as well as creating a new subset within global keys called "profile keys".
### Specification
The Profile Keys are a subset of Global Keys, the newly defined global keys are specified in the "Global Keys" section.
#### Profile Keys
##### `alias`
**Description:** A display alias
**Format:** Any text
**Example:** `ENS`
**Design Considerations:** This should be displayed near the ENS name, but should not be displayed as a replacement for it and should be below it in the visual hierarchy. You can also choose not to show the alias at all.
##### `theme`
**Description:** A user customised theme to use
**Format:** An array of comma separated hex colours.
Order should be as follows: `,,,,`.
Colours can be full or half length hex codes (e.g. `FFFFFF`, or `FFF`). A colour scheme can be incomplete but still valid by skipping a value similar to CSV (e.g. `000000,,F6F6F6,FFFFFF,FFF700`)
**Example:** `3889FF,000,F6F6F6,FFFFFF,FFF700`
**Design Considerations:** These colours can be used wherever a profile context is used (e.g. more than just the name), but separate colour schemes should never be used together on the same page. The scheme can also be extended to site-wide themability based on the primary name of the connected wallet. Selected accent and text colours should maintain a 4.5:1 contrast ratio against the selected background colour. Contrast ratio should be validated on record submission, as well as retrieval. If on retrieval colours do not meet the required contrast ratio, they should not be used. If the context requires that colours from a specific theme be used (e.g. an app theme), you can use the closest match to a colour in the theme.
**Other Notes:** If allowing a user to select a theme that is specific to one vendor (e.g. `com.example`), you should use a vendor specific version of this record e.g. `com.example.theme`
##### `avatar`
**Description:** An avatar image
**Format:** See [ENSIP-12: Avatar Text Records](ensip-12-avatar-text-records.md)
**Example:** See [ENSIP-12: Avatar Text Records](ensip-12-avatar-text-records.md)
**Design Considerations:** This should be displayed next to the ENS name wherever possible. The image should be displayed with an aspect ratio of 1:1. If the source doesn't match the target ratio, the image should be cropped from the centre to fill the ratio. The image should not have any visible blank space.
##### `header`
**Description:** A header image
**Format:** See [ENSIP-12: Avatar Text Records](ensip-12-avatar-text-records.md)
**Example:** See [ENSIP-12: Avatar Text Records](ensip-12-avatar-text-records.md)
**Design Considerations:** This should be displayed above all other profile content, or not at all. The image should be displayed with an aspect ratio of between 3:1 and 6:1. If the source doesn't match the target ratio, the image should be cropped from the centre to fill the ratio. The image should not have any visible blank space.
##### `email`
**Description:** An email that can be used as contact
**Format:** Standard email address
**Example:** `test@example.com`
**Design Considerations:** None.
##### `description`
**Description:** A biography
**Format:** Any string not exceeding 160 characters in length.
**Example:** `Human readable names for Ethereum.`
**Design Considerations:** None.
##### `location`
**Description:** A location
**Format:** Any location, if location is layered should use `, ` for separation (e.g. `Melbourne, Australia`)
**Example:** `Melbourne, Australia`
**Design Considerations:** This value should not be assumed to be real coordinates or properly formatted place, as it may be a non-existent location
##### `url`
**Description:** A website URL
**Format:** Any valid HTTP or HTTPS link.
**Example:** `https://ens.domains`
**Design Considerations:** This link should be clickable, and wherever possible shown at the bottom of the profile.
##### `timezone`
**Description:** A timezone
**Format:** Any timezone name from the [tz database](https://www.iana.org/time-zones). Follows ` /[/]`
**Example:** `Australia/Melbourne`
**Design Considerations:** None.
##### `language`
**Description:** A language
**Format:** A two letter language code from [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
**Example:** `en`
**Design Considerations:** None.
##### `primary-contact`
**Description:** The record key for a primary contact
**Format:** `email`, or any existing profile service key
**Example:** `com.github`
**Design Considerations:** When resolving `primary-contact` for a profile, the value should resolve to the service (which could be logo or name) and the corresponding value. Direct links to the service should be supported on a best-effort basis (e.g. `com.github` => `https://github.com/`)
#### Global Keys
Profile Keys are a subset of Global Keys, therefore these global keys extend the existing global keys defined in ENSIP-5.
* `alias`
* `theme`
* `header`
* `timezone`
* `language`
* `primary-contact`
##### Profile Service Keys
A profile service key is a profile key derived from the root of the service's domain. E.g. `com.github`, `org.telegram`, etc.
When creating a profile service key record, the value should be **void of optional service-specific formatting** such as prefixes like `/u/` or `@`.
In the case that the value is always displayed in a certain format, the formatting may be kept. However, any parsing or processing done on said value should attempt to be compatible with values that do not have the formatting applied.
#### Image files
When **setting** an image for an avatar or header, it is **strongly recommended** to limit the file size to an absolute maximum of 10MB. The image being set should be validated against this limit, whether it is a URL, or an NFT. Ideally, if creating an image to be set on behalf of the user, the file size should be limited to 2MB. Additionally, maintainers of image endpoints should support dimensions of images to be limited via query string `?width={width}&height={height}` wherever possible.
When **retrieving** an image for an avatar or header, images should attempt to be loaded if 10MB or less in file size. Loading images above 10MB is not required, but ideally loading should still be attempted. If retrieving an image via URL, a query string can be optionally appended to the URL to limit the dimensions via `?width={width}&height={height}`. However, the query string may have no effect.
### Backwards Compatibility
The `alias` key replaces the pre-existing `name` key. When displaying an alias, you should consider also resolving the `name` key and displaying it, if `alias` is not available.
### Security Considerations
None.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-19: Multichain Primary Names
### Abstract
This ENSIP standardizes [reverse](#reverse-resolution) and [primary name](#algorithm) resolution for all coin types, and defines how this resolution process operates across the [multichain Ethereum](#multichain-ethereum) ecosystem.
### Motivation
[ENSIP-1](/ensip/1) established the resolution of Ethereum addresses by name. [ENSIP-9](/ensip/9) introduced coin types and assigned the Ethereum address to a coin type. [ENSIP-11](/ensip/11) defined an algorithm to convert between chains and coin types.
[ENSIP-3](/ensip/3) established the reverse resolution process for Ethereum addresses. However, the generalization of this process for arbitrary coin types does not exist.
Since EVM-compatible chains have become the [primary scaling solution](https://ethereum.org/en/developers/docs/scaling/) for Ethereum, an Ethereum-wide default name is essential to ensure consistent identity resolution across all chains.
Additionally, because EVM-compatible chains have the same address encoding, chain-agonstic addresses—such as externally owned accounts (EoA) and deterministic deployment proxies—motivate an Ethereum-wide default address.
With the rise of [smart contract accounts](https://ethereum.org/en/developers/docs/accounts/) (SCA) and presence of different address derivation schemes, a modern ENS identity likely has multiple addresses accross the Ethereum ecosystem.
### Specification
Primary name resolution is a two-phase procedure that takes `addressBytes` and `coinType` as input, and returns no name or a verified primary name.
#### Definitions
* `addressBytes` — the target address as bytes, according to [ENSIP-9 § Address Encoding](/ensip/9#address-encoding).
* `[addressAsHex]` — prefix-free lowercase hexadecimal representation of `addressBytes`.
* eg. `0x0000ABcD` → `"0000abcd"`
* `coinType` — the target coin type, according to [ENSIP-9](/ensip/9).
* `coinType = 60` corresponds to the mainnet Ethereum address.
* L1 testnets (like Sepolia) may also use this `coinType`.
* `coinType` can be derived from a 31-bit EVM `chainId`, according to [ENSIP-11](/ensip/11).
* `chainId = 0` corresponds to the default EVM chain.
* `[coinTypeAsHex]` — prefix-free lowercase hexadecimal representation of `coinType` without leading zeros.
* equivalent to `BigInt(coinType).toString(16)` in JavaScript.
* eg. `4095` → `"fff"`
* `chainFromCoinType(coinType)`
* If `coinType = 60`, returns `1`.
* If `0x8000_0000 ≤ coinType ≤ 0xffff_ffff`, returns `coinType ^ 0x8000_0000`.
* Otherwise, returns `0`.
| Network | `coinType` | `chainFromCoinType()` | EVM |
| :-------- | --------------: | --------------------: | :-: |
| *Default* | `0x8000_0000` | `0` | ✓ |
| Ethereum | `60` | `1` | ✓ |
| Chain(2) | `0x8000_0002` | `2` | ✓ |
| Bitcoin | `0` | `0` | |
| ? | `0x1_8000_0002` | `0` | |
* `resolve(name, data)` — an [ENSIP-10](/ensip/10) implementation.
#### Algorithm
##### Reverse Resolution
1. Generate `reverseName` with `coinType` where:
| `coinType` | `reverseName` |
| ------------: | :----------------------------------------- |
| `60` | `"[addressAsHex].addr.reverse"` |
| `0x8000_0000` | `"[addressAsHex].default.reverse"` |
| `*` | `"[addressAsHex].[coinTypeAsHex].reverse"` |
2. Compute `reverseNode = namehash(reverseName)`.
3. Resolve `name = resolve(reverseName, abi.encodeCall(INameResolver.name, (reverseNode)))`.
4. If `name` is empty, no primary name exists for this address.
* Stop and display the address.
5. `name` is the primary name if and only if it resolves to the same `addressBytes`.
##### Forward Resolution
6. Compute `node = namehash(name)`.
7. Resolve `resolvedAddress = resolve(name, callData)` where:
| `coinType` | `callData` |
| ---------: | :-------------------------------------------------------- |
| `60` | `abi.encodeCall(IAddrResolver.addr, (node))` |
| `*` | `abi.encodeCall(IAddressResolver.addr, (node, coinType))` |
8. If `resolvedAddress != addressBytes`, no primary name exists for this address.
* Stop and display the address.
9. `name` is the primary name.
#### Multichain Ethereum
A new standalone registrar contract will maintain an `address` → `name` mapping and grant accounts of the host chain the ability to manage their `name` via various trustless mechanisms.
Unlike reverse registrations in [ENSIP-3](/ensip/3), the new registrar is registry-independent and does not support custom resolvers or records.
Resolving `addr(node, coinType)` on a reverse namespace will return the address of the corresponding registrar.
##### Default Primary Name
A new registrar contract will be deployed on L1 for default names. An [ENSIP-10](/ensip/10) wildcard resolver registered at `"reverse"` will utilize the default registrar. The default resolver will intercept `"default.reverse"` and `"[coinTypeAsHex].reverse"` for every `chainFromCoinType(coinType) > 0` and lookup names when `addressAsHex` is a valid EVM address.
##### Chain-specific Primary Name
New registrars will be deployed per chain, but only those that post state to L1 (such as [rollups](https://ethereum.org/en/developers/docs/scaling/#rollups)) may have a corresponding ENSIP-10 wildcard resolver at `"[coinTypeAsHex].reverse"`.
Each resolver will trustlessly verify registrar lookups on the corresponding chain when `addressAsHex` is a valid EVM address. If no name is associated with the address, the resolver will return the default name from the default registrar.
##### Example
> The resolver for `chainId = 2` is registered at `"80000002.reverse"`.
>
> The primary name of `0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5` on this chain corresponds to resolving the `name()` of `"b8c2c29ee19d8307cb7255e1cd9cbde883a267d5.80000002.reverse"`.
>
> If this chain was not a rollup, the reverse name would be intercepted by the default resolver, and the primary name becomes the default name.
#### Default Address
Similar to [ENSIP-9 § Backwards Compatibility](/ensip/9/#backwards-compatibility) which states:
> the value returned by `addr(node)` from ENSIP-1 should always match the value returned `addr(node, 60)`
If `chainFromCoinType(coinType) > 0`, the value returned by `addr(node, coinType)`, when no address is stored for `coinType`, should always match the value returned by `addr(node, 0x8000_0000)`.
### Backwards Compatibility
This specification requires no modification to ENSIP-10 resolution.
Unlike the new registrar [defined above](#multichain-ethereum), the [ENSIP-3](/ensip/3/#appendix-1-registrar-implementation) registrar assigned a resolver to `"[addressAsHex].addr.reverse"`. To clear this registration, the reverse resolver must be replaced with a default-aware resolver or the resolver must be unset. An unaware resolver with an unset name will not fallback to the default name.
Most resolvers do not implement the [default address logic](#default-address) and will need redeployed. Alternatively, the same address can be set for all relevant coin types to replicate the default behavior.
#### Deprecating Reverse Name Avatars
[ENSIP-12](/ensip/12) defined avatars for reverse names, which allowed accounts to have avatars without an ENS name. Adoption of this is virtually non-existent, and ENS names are more accessible than ever before (free), which effectively removes the need for it entirely.
The reverse resolvers defined in this specification do not support `text()`.
#### Deprecating Mainnet as Default
ENS has not been explicit about how to use the mainnet address record `addr()` and it is often used as a default when a chain address is not present. Additionally, mainnet primary names have historically been used on other chains as there was no alternative.
Clients must remove all logic related to default address and name handling.
##### Example
> User A on chain C wants to transfer assets to user B, who operates a SCA on L1.
>
> 1. User A enters the mainnet address of user B.
> 2. The application verifies and displays the mainnet primary name of user B.
> 3. User A confidently executes the transfer on chain C.
>
> Due to the specifics of SCA creation, user B likely has no ability to claim the matching counterfactual address on chain C, and the assets are unrecoverable.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
### Annex: Supported Chains
#### Mainnet
| Network | `chainId` | `reverseNamespace` | Registrar Contract |
| :-------- | --------: | -------------------: | :--------------------------------------------------------------------------------------------------------------------------------- |
| *Default* | `0` | `"default.reverse"` | [`0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9`](https://etherscan.io/address/0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9) |
| Ethereum | `1` | `"addr.reverse"` | |
| Optimism | `10` | `"8000000a.reverse"` | [`0x0000000000D8e504002cC26E3Ec46D81971C1664`](https://optimistic.etherscan.io/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Base | `8453` | `"80002105.reverse"` | [`0x0000000000D8e504002cC26E3Ec46D81971C1664`](https://basescan.org/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Arbitrum | `42161` | `"8000a4b1.reverse"` | [`0x0000000000D8e504002cC26E3Ec46D81971C1664`](https://arbiscan.io/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Linea | `59144` | `"8000e708.reverse"` | [`0x0000000000D8e504002cC26E3Ec46D81971C1664`](https://lineascan.build/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
| Scroll | `534352` | `"80082750.reverse"` | [`0x0000000000D8e504002cC26E3Ec46D81971C1664`](https://scrollscan.com/address/0x0000000000D8e504002cC26E3Ec46D81971C1664) |
#### Sepolia
| Network | `chainId` | `reverseNamespace` | Registrar Contract |
| :-------- | ---------: | -------------------: | :----------------------------------------------------------------------------------------------------------------------------------------- |
| *Default* | `0` | `"default.reverse"` | [`0x4F382928805ba0e23B30cFB75fC9E848e82DFD47`](https://sepolia.etherscan.io/address/0x4F382928805ba0e23B30cFB75fC9E848e82DFD47) |
| Ethereum | `1` | `"addr.reverse"` | |
| Linea | `59141` | `"8000e705.reverse"` | [`0x00000BeEF055f7934784D6d81b6BC86665630dbA`](https://sepolia.lineascan.build/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Base | `84532` | `"80014a34.reverse"` | [`0x00000BeEF055f7934784D6d81b6BC86665630dbA`](https://sepolia.basescan.org/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Arbitrum | `421614` | `"80066eee.reverse"` | [`0x00000BeEF055f7934784D6d81b6BC86665630dbA`](https://sepolia.arbiscan.io/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Scroll | `534351` | `"8008274f.reverse"` | [`0x00000BeEF055f7934784D6d81b6BC86665630dbA`](https://sepolia.scrollscan.com/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
| Optimism | `11155420` | `"80aa37dc.reverse"` | [`0x00000BeEF055f7934784D6d81b6BC86665630dbA`](https://sepolia-optimistic.etherscan.io/address/0x00000BeEF055f7934784D6d81b6BC86665630dbA) |
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-2: Initial Hash Registrar
### Abstract
This ERC describes the implementation, as deployed to the main ethereum network on 2017-05-04, of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). The corresponding source code is [here](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol).
For more background, refer to ENSIP-1.
> Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.
>
> \- ENSIP-1
A well designed and governed registrar is essential to the success of the ENS described in ENSIP-1, but is described separately in this document as it is external to the core ENS protocol.
In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol) in order to facilitate discussion.
The intent is to replace the Initial Registrar contract with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.
### Motivation
The following factors should be considered in order to optimize for adoption of the ENS, and good governance of the Initial Registrar's namespace.
**Upgradability:** The Initial Registrar should be safely upgradeable, so that knowledge gained during its deployment can be used to replace it with an improved and permanent registrar.
**Effective allocation:** Newly released namespaces often create a land grab situation, resulting in many potentially valuable names being purchased but unused, with the hope of re-selling at a profit. This reduces the availability of the most useful names, in turn decreasing the utility of the name service to end users.
Achieving an effective allocation may or may not require human intervention for dispute resolution and other forms of curation. The Initial Registrar should not aim to create to most effective possible allocation, but instead limit the cost of misallocation in the long term.
**Security:** The registrar will hold a balance of ether without an explicit limit. It must be designed securely.
**Simplicity:** The ENS specification itself emphasizes a separation of concerns, allowing the most essential element, the registry to be as simple as possible. The interim registrar in turn should be as simple as possible while still meeting its other design goals.
**Adoption:** Successful standards become more successful due to network effects. The registrar should consider what strategies will encourage the adoption of the ENS in general, and the namespace it controls in particular.
### Specification
#### Initial restrictions
The Initial Registrar is expected to be in service for approximately two years, prior to upgrading. This should be sufficient time to learn, observe, and design an updated system.
During the initial two year period, the available name space will be restricted to the `.eth` TLD.
This restriction is enforced by the owner of the ENS root node who should not assign any nodes other than `.eth` to the Initial Registrar. The ENS's root node should be controlled by multiple parties using a multisig contract.
The Initial Registrar will also prohibit registration of names 6 characters or less in length.
#### Name format for hash registration
Names submitted to the initial registrar must be hashed using Ethereum's sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in ENSIP-1.
For example, in order to register `abcdefg.eth`, one should submit `sha3('abcdefg')`, not `sha3(sha3(0, 'eth'), 'abcdefg')`.
#### Auctioning names
The registrar will allocate the available names through a Vickrey auction:
> A Vickrey auction is a type of sealed-bid auction. Bidders submit written bids without knowing the bid of the other people in the auction. The highest bidder wins but the price paid is the second-highest bid. This type of auction... gives bidders an incentive to bid their true value.
>
> \- [Vickrey Auction, Wikipedia](https://en.wikipedia.org/wiki/Vickrey_auction)
The auction lifecycle of a name has 5 possible states, or Modes.
1. **Not-yet-available:** The majority of names will be initially unavailable for auction, and will become available some time during the 8 weeks after launch.
2. **Open:** The earliest availability for a name is determined by the most significant byte of its sha3 hash. `0x00` would become available immediately, `0xFF` would become available after 8 weeks, and the availability of other names is distributed accordingly. Once a name is available, it is possible to start an auction on it.
3. **Auction:** Once the auction for a name has begun, there is a 72 hour bidding period. Bidders must submit a payment of ether, along with sealed bids as a hash of `sha3(bytes32 hash, address owner, uint value, bytes32 salt)`. The bidder may obfuscate the true bid value by sending a greater amount of ether.
4. **Reveal:** After the bidding period, a 48 hour reveal period commences. During this time, bidders must reveal the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below. If no bids are revealed, the name will return to the Open state.
5. **Owned:** After the reveal period has finished, the winning bidder must submit a transaction to finalize the auction, which then calls the ENS's `setSubnodeOwner` function, recording the winning bidder's address as the owner of the hash of the name.
The following table outlines important parameters which define the Registrar's auction mechanism.
**Registrar Parameters**
| Name | Description | Value |
| ------------------ | --------------------------------------------------------------------------------------------------- | ---------- |
| totalAuctionLength | The full time period from start of auction to end of the reveal period. | 5 days |
| revealPeriod | The length of the time period during which bidding is no longer allowed, and bids must be revealed. | 48 hours |
| launchLength | The time period during which all names will become available for auction. | 8 weeks |
| minPrice | The minimum amount of ether which must be locked up in exchange for ownership of a name. | 0.01 ether |
#### Deeds
The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in a separate `Deed` contracts. A deed contract is first created and funded when a sealed bid is submitted. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash. Non-winning bids are refunded.
A deed for an owned name may be transferred to another account by its owner, thus transferring ownership and control of the name.
After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them.
Deeds for non-winning bids can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.
The following table outlines what portion of the balance held in a deed contract will be returned upon closure, and to whom. The remaining balance will be burnt.
**Refund schedule**
| Reason for Deed closure | Refund Recipient | Refund Percentage |
| ------------------------------------------------------ | ---------------- | ----------------- |
| A valid non-winning bid is revealed. | Bidder | 99.5% |
| A bid submitted after the auction period is revealed. | Bidder | 99.5% |
| An otherwise valid bid is revealed on an owned name. 1 | Bidder | 0.5% |
| An expired sealed bid is cancelled. 2 | Canceler | 0.5% |
| A registered hash is reported as invalid. 3 | Reporter | 50% |
| A registered hash is reported as invalid. 3 | Owner | 50% |
**Notes:**
1. This incentivizes all bids to be revealed in time. If bids could be revealed late, an extortion attack on the current highest bidder could be made by threatening to reveal a new second highest bid.
2. A bid which remains sealed after more than 2 weeks and 5 days may be cancelled by anyone to collect a small reward.
3. Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.
#### Deployment and Upgrade process
The Initial Registrar requires the ENS's address as a constructor, and should be deployed after the ENS. The multisig account owning the root node in the ENS should then set the Initial Registrar's address as owner of the `eth` node.
The Initial Registrar is expected to be replaced by a Permanent Registrar approximately 2 years after deployment. The following process should be used for the upgrade:
1. The Permanent Registrar contract will be deployed.
2. The multisig account owning the root node in the ENS will assign ownership of the `.eth` node to the Permanent Registrar.
3. Owners of hashes in the Initial Registrar will be responsible for registering their deeds to the Permanent Registrar. A couple options are considered here:
1. Require owners to transfer their ownership prior to a cutoff date in order to maintain ownership and/or continue name resolution services.
2. Have the Permanent Registrar query the Initial Registrar for ownership if it is lacking an entry.
#### Planned deactivation
In order to limit dependence on the Initial Registrar, new auctions will stop after 4 years, and all ether held in deeds after 8 years will become unreachable.
#### Registrar Interface
`function state(bytes32 _hash) constant returns (Mode)`
* Implements a state machine returning the current state of a name
`function entries(bytes32 _hash) constant returns (Mode, address, uint, uint, uint)`
* Returns the following information regarding a registered name:
* state
* deed address
* registration date
* balance of the deed
* highest value bid at auction
`function getAllowedTime(bytes32 _hash) constant returns (uint timestamp)`
* Returns the time at which the hash will no longer be in the initial `not-yet-available` state.
`function isAllowed(bytes32 _hash, uint _timestamp) constant returns (bool allowed)`
* Takes a hash and a time, returns true if and only if it has passed the initial `not-yet-available` state.
`function startAuction(bytes32 _hash);`
* Moves the state of a hash from Open to Auction. Throws if state is not Open.
`function startAuctions(bytes32[] _hashes);`
* Starts multiple auctions on an array of hashes. This enables someone to open up an auction for a number of dummy hashes when they are only really interested in bidding for one. This will increase the cost for an attacker to simply bid blindly on all new auctions. Dummy auctions that are open but not bid on are closed after a week.
`function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) constant returns (bytes32 sealedBid);`
* Takes the parameters of a bid, and returns the sealedBid hash value required to participate in the bidding for an auction. This obfuscates the parameters in order to mimic the mechanics of placing a bid in an envelope.
`function newBid(bytes32 sealedBid);`
* Bids are sent by sending a message to the main contract with a sealedBid hash and an amount of ether. The hash contains information about the bid, including the bidded name hash, the bid value, and a random salt. Bids are not tied to any one auction until they are revealed. The value of the bid itself can be masqueraded by sending more than the value of your actual bid. This is followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. Since this is an auction, it is expected that most public hashes, like known domains and common dictionary words, will have multiple bidders pushing the price up.
`function startAuctionsAndBid(bytes32[] hashes, bytes32 sealedBid)`
* A utility function allowing a call to `startAuctions` followed by `newBid` in a single transaction.
`function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt);`
* Once the bidding period is completed, there is a reveal period during with the properties of a bid are submitted to reveal them. The registrar hashes these properties using the `shaBid()` function above to verify that they match a pre-existing sealed bid. If the unsealedBid is the new best bid, the old best bid is returned to its bidder.
`function cancelBid(bytes32 seal);`
* Cancels an unrevealed bid according to the rules described in the notes on the refund schedule above.
`function finalizeAuction(bytes32 _hash);`
After the registration date has passed, this function can be called to finalize the auction, which then calls the ENS function `setSubnodeOwner()` updating the ENS record to set the winning bidder as owner of the node.
`function transfer(bytes32 _hash, address newOwner);`
* Update the owner of the ENS node corresponding to the submitted hash to a new owner. This function must be callable only by the current owner.
`function releaseDeed(bytes32 _hash);`
* After some time, the owner can release the property and get their ether back.
`function invalidateName(string unhashedName);`
* Since registration is done on the hash of a name, the registrar itself cannot validate names. This function can be used to report a name which is 6 characters long or less. If it has been registered, the submitter will earn 10% of the deed value. We are purposefully handicapping the simplified registrar as a way to force it into being restructured in a few years.
`function eraseNode(bytes32[] labels)`
* Allows anyone to delete the owner and resolver records for a subdomain of a name that is not currently owned in the registrar. For instance, to zero `foo.bar.eth` on a registrar that owns `.eth`, pass an array containing `[sha3('foo'), sha3('bar')]`.
`function transferRegistrars(bytes32 _hash) onlyOwner(_hash);`
* Used during the upgrade process to a permanent registrar. If this registrar is no longer the owner of the root node in the ENS, this function will transfer the deed to the current owner, which should be a new registrar. This function throws if this registrar still owns its root node.
### Rationale
#### Starting with a temporary registrar
Anticipating and designing for all the potential issues of name allocation names is unlikely to succeed. This approach chooses not to be concerned with getting it perfect, but allows us to observe and learn with training wheels on, and implement improvements before expanding the available namespace to shorter names or another TLD.
#### Valid names >= 7 characters
Preserving the shortest, and often most valuable, domain names for the upgraded registrar provides the opportunity to implement processes for dispute resolution (assuming they are found to be necessary).
#### Delayed release of names
A slower release allows for extra time to identify, and address any issues which may arise after launch.
#### Restricting TLD to `.eth`
Choosing a single TLD helps to maximize network effects by focusing on one namespace.
A three letter TLD is a pattern made familiar by it's common usage in internet domain names. This familiarity significantly increases the potential of the ENS to be integrated into pre-existing DNS systems, and reserved as a [special-use domain name](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml#special-use-domain). A recent precedent for this is the [reservation of the `.onion` domain](https://tools.ietf.org/html/rfc7686).
#### Holding ether as collateral
This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service.
### Prior work
This document borrows heavily from several sources:
* ENSIP-1 outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.
* [ERC-26](https://github.com/ethereum/EIPs/issues/26) was the first ERC to propose a name service at the contract layer
* @alexvandesande's current implementation of the [HashRegistrar](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol)
#### Edits:
* 2016-10-26 Added link Alex's design in abstract
* 2016-11-01 change 'Planned deactivation' to h3'
* 2017-03-13 Update timelines for bidding and reveal periods
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-20: Wildcard Writing
### Abstract
This ENSIP proposes a standardized mechanism for managing offchain domains within the Ethereum Name Service (ENS) ecosystem. It addresses the growing trend of storing domains off the Ethereum blockchain to reduce transaction fees while maintaining compatibility with existing ENS components. The proposal outlines methods for domain registration, transferring, and setting records, ensuring a consistent approach to offchain domain management.
### Motivation
With the acceptance of CCIP-Read by the Ethereum community, there has been a notable shift towards storing domains in locations other than the Ethereum blockchain to avoid high transaction fees. This shift has revealed a significant gap: the lack of standardized methods for managing offchain domains. By establishing a standardized offchain resolver implementation and user flow, we can ensure a consistent approach enabling applications that support this ENSIP flow to integrate this feature and enhance user experience seamlessly, increasing scalability, providing cost-effective solutions, and reducing client complexity by providing a common way to interact with all the offchain providers.
### Specification
This ENSIP relies on the following standards:
* [ERC-712](https://eips.ethereum.org/EIPS/eip-712) Typed structured data
* [EIP-7884](https://ercs.ethereum.org/ERCS/erc-7884) Operation Router
* [EIP-7528](https://eips.ethereum.org/EIPS/eip-7528) Token Standard for Fungible Gas
#### Wildcard Writing interface
The Wildcard Writing standard is defined by multiple interfaces, which, except for the OffchainRegister, are optional according to the provider's needs.
```solidity
/// @notice The details of a registration request.
/// @param name The DNS-encoded name being registered (e.g. "alice.eth", "alice.bob.eth")
/// @param owner The address that will own the registered name
/// @param duration The length of time in seconds to register the name for
/// @param secret The secret to be used for the registration based on commit/reveal
/// @param resolver The address of the resolver used as entrypoint on the L1
/// @param extraData Additional registration data encoded as bytes
struct RegisterRequest {
bytes name;
address owner;
uint256 duration;
bytes32 secret;
address resolver;
bytes extraData;
}
interface OffchainRegister {
/// @notice Struct containing registration parameters for a name
/// @param price The total price in wei required to register the name
/// @param available Whether the name is available for registration
/// @param token Token address (ERC-7528 ether address or ERC-20 contract)
/// @param commitTime The commit duration in seconds
/// @param extraData Additional registration data encoded as bytes
struct RegisterParams {
uint256 price;
bool available;
address token;
uint256 commitTime;
bytes extraData;
}
/// @notice Returns the registration parameters for a given name and duration
/// @dev This function calculates and returns the registration parameters needed to register a name
/// @param name The DNS-encoded name to query for registration parameters (e.g. "alice.eth", "alice.bob.eth")
/// @param duration The duration in seconds for which the name should be registered
/// @return A struct containing the registration parameters
function registerParams(
bytes calldata name,
uint256 duration
)
external
view
returns (RegisterParams memory);
/// @notice Registers a domain name
/// @param request The registration request details
/// @dev Forwards the registration request to the L2 contracts for processing
function register(RegisterRequest calldata request) external payable;
}
interface OffchainTransferrable {
/// @notice Transfers ownership of a name to a new address
/// @param name The DNS-encoded name to transfer (e.g. "alice.eth", "alice.bob.eth")
/// @param owner The current owner of the name
/// @param newOwner The address to transfer ownership to
function transferFrom(
bytes calldata name,
address owner,
address newOwner
)
external;
}
interface OffchainCommitable {
/// @notice Produces the commit hash from the register request
/// @param request The registration request details
/// @return commitHash The hash that should be committed before registration
function makeCommitment(RegisterRequest calldata request)
external
pure
returns (bytes32 commitHash);
/// @notice Commits a hash of registration data to prevent frontrunning
/// @param commitment The hash of the registration request data that will be used in a future register call
/// @dev The commitment must be revealed after the minimum commit age and before the maximum commit age
function commit(bytes32 commitment) external;
}
```
#### Client flow
It relies on the approach specified by the [EIP-7884](https://ethereum-magicians.org/t/operation-router/22633) to first gather the required data for the subsequent transaction to be made directly to the given entity, a contract or an offchain gateway.
The onchain flow is composite as follows:
```mermaid
sequenceDiagram
Note over Client: calldata = encode(setText(node, key, value))
rect rgb(220, 240, 220)
Note over Client,L1Resolver: view call
Client ->> L1Resolver: getOperationHandler(calldata)
L1Resolver -->> Client: revert OperationHandledOnchain(chainId, address)
end
Client ->> L2Resolver: setText(node, key, value)
```
The offchain version of this flow looks like the following:
```mermaid
sequenceDiagram
Note over Client: calldata = encode(setText(node, key, value))
rect rgb(220, 240, 220)
Note over Client,L1 Contract: view call
Client ->> L1 Contract: getOperationHandler(calldata)
L1 Contract -->> Client: revert OperationHandledOffchain(sender, url, data)
end
Client ->> Client: EIP-712 signature
rect rgb(220, 220, 240)
Note over Client,Gateway: off-chain
Client->>Gateway: POST url {sender, data, signature}
Gateway->>Gateway: Verify EIP-712 signature
Gateway->>Gateway: Process mutation
Gateway -->> Client: response
end
```
These flows can be optimized by relying on the ENS' Universal Resolver ENSIP-10 `resolve` implementation reducing the number of RPC requests.
#### Subdomain registering
As the initial step in registering a subdomain, the `registerParams` function has been implemented to support a variety of use cases. This function plays a crucial role in creating a flexible and extensible offchain subdomain registration system.
The function has the following signature:
```solidity
struct RegisterParams {
uint256 price;
bool available;
address token;
uint256 commitTime;
bytes extraData;
}
function registerParams(
bytes memory name,
uint256 duration
)
external
view
returns (RegisterParams memory);
```
Parameters:
* `name`: DNS-encoded name to be registered
* `duration`: The duration in seconds for the registration
Return:
* `price`: the amount of ETH charged per second
* `available`: whether the domain is available for registering
* `token`: ERC-20 token address to be used as payment according to the EIP-7528
* `commitTime`: the amount of seconds the commit should wait before being revealed. `0` means that the commit/reveal pattern isn't being used
* `extraData`: any given encoded data
The register function MUST have the following signature:
```solidity
struct RegisterRequest {
bytes name;
address owner;
uint256 duration;
bytes32 secret;
address resolver;
bytes extraData;
}
function register(RegisterRequest calldata request) external payable;
```
Parameters:
* `name`: DNS-encoded name to be registered
* `owner`: subdomain owner's address
* `duration`: the duration in seconds of the registration
* `secret`: random seed to be used for commit/reveal
* `resolver`: the address of the resolver used as entrypoint on the L1
* `extraData`: any additional data (e.g. signatures from an external source)
**Behavior:**
* **L1 Resolver**: it MUST revert with the respective error specified by the [EIP-7884](https://ethereum-magicians.org/t/operation-router/22633).
* **L2 contract / Gateway**: it MUST register the subdomain.
Although implementing the `register` on the layer 1 contract is OPTIONAL given that it is already handled by the `getOperationHandler`, it is possible for the contract to implement it directly in order to expose it on its ABI. If so, it MUST revert with the same error it would if called through the `getOperationHandler`.
#### Architecture
Onchain subdomain registering:
```mermaid
sequenceDiagram
participant Client
participant L1 Resolver
participant L2 Contract
Client->>L1 Resolver: getOperationHandler(encodedFunc)
L1 Resolver-->>Client: revert OperationHandledOnchain(chainId, address)
Client->>L2 Contract: registerParams(name,duration)
L2 Contract-->>Client: return RegisterParams
alt RegisterParams.available
Client->>L2 Contract: register{value: RegisterParams.price}(RegisterRequest)
end
```
Offchain subdomain registering:
```mermaid
sequenceDiagram
participant Client
participant L1 Resolver
participant Gateway
participant Database
Client->>L1 Resolver: getOperationHandler(encodedFunc)
L1 Resolver-->>Client: revert OperationHandledOffchain(domain, url, message)
rect rgb(200, 230, 255)
note over Client,Database: offchain request
Client->>Gateway: registerParams(name,duration)
Gateway-->>Client: return RegisterParams
alt RegisterParams.available
Client->>Client: sign request with EIP-712
Client->>Gateway: register(RegisterRequest)
Gateway->>Gateway: validate signer ownership
Gateway->>Database: DB Insert
end
end
```
#### Commit/Reveal Process
The `OffchainCommitable` interface enables a commit-reveal pattern for subdomain registration to prevent front-running attacks. This interface is OPTIONAL and should be implemented by providers who want to add this security measure to their registration process.
The interface has the following functions:
```solidity
function makeCommitment(RegisterRequest calldata request)
external
pure
returns (bytes32 commitHash);
function commit(bytes32 commitment) external;
```
Parameters for `makeCommitment`:
* `request`: The complete registration request containing all parameters needed for registration
Parameters for `commit`:
* `commitment`: The hash generated by `makeCommitment` that represents the future registration request
**Behavior:**
* **L1 Resolver**: it MUST revert with the respective error specified by the EIP-5559. the same it would if called through the `getOperationHandler`
* **L2 contract**: it MUST store the commitment and track when it was made to enforce the commit time specified in `registerParams`.
#### Architecture
The onchain flow would look as follows:
```mermaid
sequenceDiagram
participant Client
participant L1 Resolver
participant L2 Contract
Client->>L1 Resolver: getOperationHandler(encodedFunc)
L1 Resolver-->>Client: revert OperationHandledOnchain(chainId, address)
Client->>L2 Contract: registerParams(name,duration)
L2 Contract-->>Client: return RegisterParams
alt registerParams.available
alt registerParams.commitTime > 0
Client->>L2 Contract: makeCommitment(RegisterRequest)
L2 Contract-->>Client: return commitment
Client->>L2 Contract: commit(commitment)
Client->>Client: wait for the commit time to be over
end
Client->>L2 Contract: register{value: registerParams.price}(RegisterRequest)
end
```
#### Transfer Subdomain
This interface is responsible for enabling the transfer of the domain's ownership, both the EIP-721 and within the Registry.
The transfer function MUST have the following signature:
```solidity
function transferFrom(bytes calldata name, address owner, address newOwner) external payable;
```
With the arguments being:
1. `node`: the ENS name DNS-encoded
2. `owner`: the address of the domain's current owner
3. `newOwner`: the Ethereum address to receive the domain
The interface for enabling domain transfers MUST be implemented by the one deployed to the given L2. The one deployed to L1 is OPTIONAL for the same reason as the `register` function.
**Behavior:**
1. **L1 Resolver**: it MUST revert with the respective error described by EIP-5559.
2. **L2 contract**: it MUST handle the actual domain transfer operation.
#### Architecture
The flow would look as follows:
```mermaid
sequenceDiagram
participant Client
participant L1 Resolver
participant L2 Contract
participant L2 NameWrapper
Client->>L1 Resolver: getOperationHandler(encodedFunc)
L1 Resolver-->>Client: revert OperationHandledOnchain(chainId, address)
Client ->>L2 Contract: address(node)
L2 Contract-->>Client: return ETH address
alt address different from new owner
Client->>L2 Contract: setAddress(node, newOwner)
end
Client->>L2 Contract: transferFrom(name, owner, newOwner)
alt signer is the owner
L2 Contract->>L2 NameWrapper: safeTransferFrom
end
```
### Rationale
The proposed interfaces standardize the management of offchain domains within the ENS ecosystem. By leveraging [EIP-7884](https://ethereum-magicians.org/t/operation-router/22633) for offchain writing and maintaining compatibility with existing ENS components, this proposal ensures a seamless integration of offchain domain management into current ENS workflows.
### Backwards Compatibility
This ENSIP introduces new functionality relying on an mechanism similar to what is being used on the CCIP-Read standard making it a fully backward compatible standard.
Setting multiple records should still be handled by the Resolver's `multicallWithNodeCheck` function.
### Security Considerations
All the implementations MUST include appropriate access controls to ensure only authorized parties (e.g., the current owner) can modify the domains, as well as consider emitting events to log write operations for transparency and off-chain tracking.
The data related to domains stored in any place other than Ethereum SHOULD be fetch through the [ENSIP-16: Offchain Metadata](https://docs.ens.domains/ensip/16) to optimize queries and provide features that wouldn't be available otherwise.
#### Offchain
1. The authentication logic for domain ownership is shifted entirely to the signing step performed by the Client. Implementations MUST ensure robust signature verification to prevent unauthorized access or modifications.
2. The Gateway that receives redirected calls is responsible for ownership validation. Proper security measures MUST be implemented in the Gateway to prevent unauthorized actions.
3. The use of EIP-712 signatures for authentication provides a secure method for verifying domain ownership. However, implementers SHOULD be aware of potential signature replay attacks and implement appropriate mitigations.
4. The offchain storage of domain information introduces potential risks related to data availability and integrity. Implementers SHOULD consider redundancy and data verification mechanisms to mitigate these risks.
Further security analysis and auditing are RECOMMENDED before deploying this system in a production environment, with special attention given to the unique security considerations of both onchain and offchain implementations.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-21: Batch Gateway Offchain Lookup Protocol
### Abstract
This standard establishes the Batch Gateway Offchain Lookup Protocol (BGOLP).
### Motivation
[EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) describes a serial `OffchainLookup` mechanism. To perform more than one `OffchainLookup`, lookups can be performed in sequence using recursive calls.
This proposal standardizes an existing ENS solution, colloquially called the "Batch Gateway", utilized first by the [`UniversalResolver`](https://etherscan.io/address/0xce01f8eee7E479C928F8919abD53E553a36CeF67#code). It is effectively [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled) for `OffchainLookup` reverts.
### Specification
The BGOLP has the following Solidity interface:
```solidity
/// @dev Interface selector: `0xa780bab6`
interface IBatchGateway {
/// @notice An HTTP error occurred.
/// @dev Error selector: `0x01800152`
error HttpError(uint16 status, string message);
/// @dev Information extracted from an `OffchainLookup` revert.
struct Request {
address sender; // same as `OffchainLookup.sender`
string[] urls; // same as `OffchainLookup.urls`
bytes data; // same as `OffchainLookup.callData`
}
/// @notice Perform multiple `OffchainLookup` in parallel.
/// @notice Callers should enable EIP-3668.
/// @param requests The array of requests to lookup in parallel.
/// @return failures The failure status of the corresponding request.
/// @return responses The response or error data of the corresponding request.
function query(
Request[] memory requests
) external view returns (bool[] memory failures, bytes[] memory responses);
}
```
1. Given an array of `OffchainLookup` reverts, transform each error into a `Request`.
2. Revert `OffchainLookup` with `abi.encodeCall(IBatchedGateway.query, (requests))` as the calldata.
* The reverter must supply its own BGOLP gateway(s).
* `x-batch-gateway:true` is defined as a special-purpose URL, which indicates an EIP-3668 client may substitute a local BGOLP implementation. If present, the client should always use the local gateway and ignore the other options. All compliant BGOLP gateways are **equivalent**.
3. Upon receiving the callback, decode the response, and propagate the inner callbacks accordingly. It is the developers responsibility to continue the EIP-3668 process.
#### Batch Gateway Response
* The length of `failures` and `responses` must equal the number of `requests`.
* `failures[i]` is `false` if a response was received according to EIP-3668, even if it was error data.
* `failures[i]` is `true` if the request could not be completed.
* If a HTTP error is encountered, encode the response using `HttpError`.
* Otherwise, encode the reason with `Error(string)`.
* `responses[i]` is the response or error data.
### Rationale
This standard is a prerequisite for local BGOLP implementations in client frameworks.
A local BGOLP gateway is a privacy and latency improvement.
### Backwards Compatibility
The `UniversalResolver` is the only known contract that uses the BGOLP. Its design permits client-supplied gateways. In nearly all implementations, clients are using the default.
### Security Considerations
A local BGOLP gateway is **always preferable** as an external gateway leaks information and adds latency.
BGOLP gateways **should curtail the maximum number of simultaneous requests** in aggregate and per host to avoid DDOS attacks.
BGOLP gateways **should not be trusted**. Each individual `OffchainLookup` must secure its own protocol.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
### Annex: Fault Tolerance
To perform an `OffchainLookup` that does not terminate unexpectedly, a single lookup with `n` gateways can be transformed into a BGOLP lookup with `n` requests, each with a single gateway. In exchange for fault tolerance, the response time will match the slowest gateway and successful responses will be replicated.
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-22: Contract Features
### Abstract
This ENSIP standardizes [ERC-7996](https://eips.ethereum.org/EIPS/eip-7996) contract features relevant to ENS, enabling new optimizations while preserving compatibility with existing deployments.
### Motivation
ENS has maintained backwards compatibility with contracts created in 2016 through extensive use of [ERC-165](https://eips.ethereum.org/EIPS/eip-165). Unfortunately, not all contract capabilities can be expressed through an unique interface.
Features allow expression of contract capabilities that preserve existing interfaces. This proposal standardizes features related to the ENS protocol.
### Specification
Contract features are defined in EIP-7996.
#### Resolver with Features
Any resolver that supports features must adhere to the following criteria:
* If the resolver utilizes [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) (CCIP-Read), it must support [recursive calls](https://eips.ethereum.org/EIPS/eip-3668#recursive-calls-in-ccip-aware-contracts) and its gateway must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS).
* The resolver must be compiled with [EIP-140](https://eips.ethereum.org/EIPS/eip-140) support.
Therefore, when resolution calldata is not a `multicall`, the resolver may be invoked directly without [batch gateway](./21) infrastructure.
#### eth.ens.resolver.extended.multicall — `0x96b62db8`
If a resolver is an [`IExtendedResolver`](./10) and supports this feature, `resolve(name, data)` must handle `multicall(bytes[])` as expected.
For resolvers that utilize CCIP-Read, this feature permits a single `OffchainLookup` request to fetch multiple records, which greatly reduces latency and network traffic.
A resolver with this feature may always be invoked directly without batch gateway infrastructure.
### Backwards Compatibility
Callers unaware of features or any specific feature experience no change in behavior.
### Security Considerations
As stated in ERC-7996, declaring support for a feature does not guarantee that the contract implements it.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-23: Universal Resolver
### Abstract
This ENSIP standardizes [IUniversalResolver](#specification) (UR), an universal entrypoint for resolving ENS names. UR incorporates onchain algorithms for [ENSIP-1: ENS](./1), [ENSIP-10: Wildcard Resolution](./10), [ENSIP-19: Multichain Primary Names](./19), [ENSIP-21: Batch Gateway](./21), and [ENSIP-22: Contract Features](./22) to reduce integration complexities.
### Motivation
The process of resolving ENS names requires multiple onchain calls and in-depth knowledge of the [latest standards](/).
Resolution has become more complex over time, especially with the introduction of wildcard resolution and multichain primary names. [ENSv2](https://ens.domains/ensv2) will also introduce a new registry design and many other improvements.
Maintaining these changes across multiple client frameworks demands significant development effort. The growth and evolution of the ENS protocol should not be constrained by the pace of client deployments or hindered by outdated libraries.
UR offers a standard entrypoint for client frameworks to perform ENS resolution. It lifts many algorithms out of client frameworks and puts them onchain for transparency and security. This ENSIP standardizes an interface for [forward](#resolve) and [primary name](#reverse) resolution.
### Specification
UR has the following Solidity [interface](https://github.com/ensdomains/ens-contracts/blob/20e34971fd55f9e3b3cf4a5825d52e1504d36493/contracts/universalResolver/IUniversalResolver.sol):
```solidity
/// @dev Interface selector: `0xcd191b34`
interface IUniversalResolver {
/// @notice A resolver could not be found for the supplied name.
/// @dev Error selector: `0x77209fe8`
error ResolverNotFound(bytes name);
/// @notice The resolver is not a contract.
/// @dev Error selector: `0x1e9535f2`
error ResolverNotContract(bytes name, address resolver);
/// @notice The resolver did not respond.
/// @dev Error selector: `0x7b1c461b`
error UnsupportedResolverProfile(bytes4 selector);
/// @notice The resolver returned an error.
/// @dev Error selector: `0x95c0c752`
error ResolverError(bytes errorData);
/// @notice The resolved address from reverse resolution does not match the supplied address.
/// @dev Error selector: `0xef9c03ce`
error ReverseAddressMismatch(string primary, bytes primaryAddress);
/// @notice An HTTP error occurred on a resolving gateway.
/// @dev Error selector: `0x01800152`
error HttpError(uint16 status, string message);
/// @notice Find the resolver address for `name`.
/// Does not perform any validity checks on the resolver.
/// @param name The name to search.
/// @return resolver The found resolver, or null if not found.
/// @return node The namehash of `name`.
/// @return resolverOffset The offset into `name` corresponding to `resolver`.
function findResolver(
bytes memory name
)
external
view
returns (address resolver, bytes32 node, uint256 resolverOffset);
/// @notice Performs ENS forward resolution for the supplied name and data.
/// Caller should enable EIP-3668.
/// @param name The DNS-encoded name to resolve.
/// @param data The ABI-encoded resolver calldata.
/// For a multicall, encode as `multicall(bytes[])`.
/// @return result The ABI-encoded response for the calldata.
/// For a multicall, the results are encoded as `(bytes[])`.
/// @return resolver The resolver that was used to resolve the name.
function resolve(
bytes calldata name,
bytes calldata data
) external view returns (bytes memory result, address resolver);
/// @notice Performs ENS primary name resolution for the supplied address and coin type, as specified in ENSIP-19.
/// Caller should enable EIP-3668.
/// @param lookupAddress The byte-encoded address to resolve.
/// @param coinType The coin type of the address to resolve.
/// @return primary The verified primary name, or null if not set.
/// @return resolver The resolver that was used to resolve the primary name.
/// @return reverseResolver The resolver that was used to resolve the reverse name.
function reverse(
bytes calldata lookupAddress,
uint256 coinType
)
external
view
returns (
string memory primary,
address resolver,
address reverseResolver
);
}
```
#### findResolver
This function performs onchain [registry traversal](./#registry-specification) of a DNS-encoded `name`. It returns the first non-null `resolver` address, the namehash of `name` as `node`, and the `resolverOffset` into `name` that corresponds to the resolver. If no resolver is found, `resolver` is null.
`findResolver()` does not perform any validity checks on the resolver and simply returns the value in the registry. The resolver may not be a contract or a resolver.
##### Pseudocode Example
```js
name = dnsEncode("sub.nick.eth") = "\x03sub\x04nick\x03eth\x00"
1. registry[namehash("\x03sub\x04nick\x03eth\x00")] = null ❌️
2. registry[namehash(/*-4-*/"\x04nick\x03eth\x00")] = 0x2222222222222222222222222222222222222222 ✅️ // "nick.eth"
3. registry[namehash(/*-----9-----*/"\x03eth\x00")] = ... // not
4. registry[namehash(/*---------13-------*/"\x00")] = ... // checked
findResolver(name)
resolver = registry[namehash("\x04nick\x03eth\x00")] = 0x2222222222222222222222222222222222222222
node = namehash("\x03sub\x04nick\x03eth\x00") = 0xe3d81fd7b7e26b124642b4f160ea05f65a28ecfac48ab767c02530f7865e1c4c
offset = 4 // name.slice(4) = "\x04nick\x03eth\x00" = dnsEncode("nick.eth")
```
#### resolve
This function performs forward resolution using the `resolver` found by [`findResolver()`](#findresolver). It provides a standard interface for interacting [ENSIP-1](./1) and [ENSIP-10](./10) resolvers for onchain and offchain resolution. Provided a DNS-encoded `name` and ABI-encoded `data`, it returns the ABI-encoded resolver `result` and the valid `resolver` address.
UR automatically handles wrapping calldata and unwrapping responses when interacting with an [`IExtendedResolver`](./10#pseudocode) and safely interacts with contracts deployed before [EIP-140: REVERT Instruction](https://eips.ethereum.org/EIPS/eip-140).
##### Resolution Errors
* If no resolver was found, reverts `ResolverNotFound`.
* If the resolver was not a contract, reverts `ResolverNotContract`.
* If [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) (CCIP-Read) was required and it was not handled by the client, reverts `OffchainLookup`.
* If CCIP-Read was handled but the `OffchainLookup` failed, reverts `HTTPError`.
##### Resolver Errors
* If the called function was not implemented, reverts `UnsupportedResolverProfile`.
* If the called function reverted, reverts `ResolverError`.
##### Smart Multicall
Traditionally, resolvers have been written to answer direct profile requests, eg. `addr()` returns one address. To perform multiple requests, the caller must perform multiple independent requests (in sequence, parallel, or via batched RPC) or utilize an [external multicall contract](https://www.multicall3.com/) which does not support CCIP-Read.
UR supports multicall with CCIP-Read and [`eth.ens.resolver.extended.multicall`](./22#ethensresolverextendedmulticall--0x96b62db8) feature. To perform multiple calls:
```solidity
bytes[] memory calls = new bytes[](3);
calls[0] = abi.encodeCall(IAddrResolver.addr, (node));
calls[1] = abi.encodeCall(ITextResolver.text, (node, "avatar"));
calls[2] = hex"00000000"; // invalid selector
```
```ts
const calls = [
encodeFunctionData({ functionName: "addr", args: [node] }),
encodeFunctionData({ functionName: "text", args: [node, "avatar"] }),
"0x00000000", // invalid selector
];
```
Using the following [interface](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/resolvers/IMulticallable.sol):
```solidity
interface IMulticallable {
function multicall(bytes[] calldata data) external view returns (bytes[] memory);
}
```
Encode the calls, invoke [`resolve()`](#resolve) normally, and decode the result:
```solidity
bytes memory data = abi.encodeCall(IMulticallable.multicall, (calls));
(bytes memory result, address resolver) = UR.resolve(name, data); // note: could revert OffchainLookup
bytes[] memory results = abi.decode(result, (bytes));
```
```ts
const data = encodeFunctionData({ functionName: "multicall", args: [calls] });
const [result, resolver] = await UR.read.resolve(name, data);
const results = decodeFunctionResult({ functionName: "multicall", data: result });
```
The same [resolution errors](#resolution-errors) apply but [resolver errors](#resolver-errors) are handled differently. The call **always succeeds** and decodes into an array of results. The number of calls is always equal to the number of results. If `results[i]` is not multiple of 32 bytes, it is an ABI-encoded error for the corresponding `calls[i]`.
```solidity
address ethAddress = abi.decode(results[0], (address));
string avatar = abi.decode(results[1], (string));
// results[2] == abi.encodeWithSelector(UnsupportedResolverProfile.selector, bytes4(0x00000000));
```
```ts
const ethAddress = decodeFunctionResult({ functionName: "addr", data: results[0] });
const avatar = decodeFunctionResult({ functionName: "text", data: results[1] });
const error = decodeErrorResult({ data: result[2] }); // { errorName: "UnsupportedResolverProfile", args: ["0x00000000"] }
```
#### reverse
This function performs multichain primary name resolution according to [ENSIP-19](./19). Provided a [byte-encoded](./9) `lookupAddress` and desired `coinType`, it returns the verified primary `name` and the addresses of forward `resolver` and `reverseResolver`. UR supports CCIP-Read during the forward and reverse phases.
If the primary `name` is [unnormalized](./15), eg. `normalize("Nick.eth") != "nick.eth"`, then `name` and `resolver` are invalid.
* If [reverse resolution](./19#reverse-resolution) of the reverse name was not successful, reverts a [`resolve()` error](#resolution-errors).
* If the resolved primary name was null, returns `("", address(0), )`.
* If [forward resolution](./19#forward-resolution) of the primary name was not successful, also reverts a [`resolve()` error](#resolution-errors).
* If the resolved address of `coinType` doesn't equal the `lookupAddress`, reverts `ReverseAddressMismatch`.
`reverse()` is effectively (2) sequential `resolve()` calls.
##### Pseudocode Example
```js
// valid primary name: vitalik.eth on mainnet
reverse("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", 60)
1. reverse: resolve("d8da6bf26964af9d7eed9e03e53415d37aa96045.addr.reverse", name()) = "vitalik.eth"
2. forward: resolve("vitalik.eth", addr(60)) = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
3. 0xd8dA == 0xd8dA => ✅️ "vitalik.eth"
// invalid primary name: imposter vitalik.eth
reverse("0x314159265dD8dbb310642f98f50C066173C1259b", 60)
1. reverse: resolve("314159265dd8dbb310642f98f50c066173c1259b.addr.reverse", name()) = "vitalik.eth"
2. forward: resolve("vitalik.eth", addr(60)) = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
3. 0x3141 != 0xd8d => ❌️ ReverseAddressMismatch()
// no primary name: burn address on Base mainnet
resolve("0x000000000000000000000000000000000000dEaD", 0x80000000 ^ 8453)
1. reverse: resolve("000000000000000000000000000000000000dead.addr.reverse", name()) => ❌️ ResolverNotFound()
```
### Backwards Compatibility
UR supports **ALL** known resolver types if the caller supports CCIP-Read. Otherwise, it can only resolve onchain names.
It is a **complete replacement** for existing ENS resolution procedures. Client frameworks should focus on building calldata and handling responses and rely on UR to facilitate resolution.
### Security Considerations
UR uses a batch gateway to perform CCIP-Read requests. If the client does not support ENSIP-21, a trustless external batch gateway service is used which adds latency and leaks information.
UR is deployed as an immutable contract and as an ENS DAO-managed upgradeable proxy. The main purpose of the proxy is to facilitate a seamless transition to ENSv2 and track the latest standards. Client frameworks should default to the proxy so their libraries are future-proof, with the option to specify an alternative implementation.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-24: Arbitrary Data Resolution
### Abstract
This ENSIP proposes a new resolver profile for resolving arbitrary `bytes` data.
### Motivation
ENS has seen significant adoption across the blockchain ecosystem, but the current resolver profiles are too restrictive for many emerging applications.
There is a clear need for a richer record type that can store unstructured binary data. This would provide a flexible, gas-efficient mechanism for associating any data with an ENS name. This would enable direct support for resolution of things like:
* Hashed data commitments for off-chain data verification
* Interoperable addresses
* Context data
### Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
#### Overview
This ENSIP introduces a new interface for the resolution of arbitrary `bytes` data:
```
/// @dev Interface selector: `0xecbfada3`
interface IDataResolver {
/// @notice For a specific `node`, get the data associated with the key, `key`.
/// @param node The node (namehash) for which data is being fetched.
/// @param key The key.
/// @return The associated arbitrary `bytes` data.
function data(
bytes32 node,
string calldata key
) external view returns (bytes memory);
}
```
The [ERC-165] identifier for this interface is `0xecbfada3`.
The `key` argument is a `string` type for simplicity and clarity.
Resolvers implementing this ENSIP MUST emit the following event when data is changed:
```
/// @notice For a specific `node`, the data associated with a `key` has changed.
event DataChanged(
bytes32 indexed node,
string indexed indexedKey,
string key,
bytes indexed indexedData
);
```
Resolvers MAY implement the following interface
```
/// @dev Interface selector: `0x29fb1892`
interface ISupportedDataKeys {
/// @notice For a specific `node`, get an array of supported data keys.
/// @param node The node (namehash).
/// @return The keys for which we have associated data.
function supportedDataKeys(bytes32 node) external view returns (string[] memory);
}
```
The [ERC-165] identifier for this interface is `0x29fb1892`.
If implemented this function MUST return an array of `string` keys which the resolver MAY store data for.
#### Rationale
Retrofitting the `addr(bytes32 node, uint coinType)` function defined in ENSIP-9 as a getter for resolving arbitrary bytes was considered, but whilst cool, its usage is hacky and not semantically clear to developers.
We considered simply storing `bytes` data as a `string` within text records but this is inefficient, expensive, and impractical.
The `DataChanged` event emits both the `key` and the `indexedKey`. This allows for efficient event filtering whilst immediately exposing useful key data. `indexedData` is also emitted to allow data integrity checks whilst avoiding chain bloat.
The optional `ISupportedDataKeys` interface allows for data key discovery. The intended usage of this interface is to enable data discovery for small, known, and bounded sets of keys without the need for external dependencies.
#### Example
Below is an illustrative snippet that shows how to set and retrieve arbitrary data:
```
pragma solidity ^0.8.25;
interface IDataResolver {
event DataChanged(
bytes32 indexed node,
string indexed indexedKey,
string key,
bytes indexed indexedData
);
function data(
bytes32 node,
string calldata key
) external view returns (bytes memory);
}
contract Resolver is IDataResolver {
mapping(bytes32 node => mapping(string key => bytes data)) private dataStore;
function data(bytes32 node, string calldata key) external view returns (bytes memory) {
return dataStore[node][key];
}
// setData function can be used to set the data (not shown)
}
```
Set and retrieve arbitrary data:
```
// Pseudo javascript example
// Store arbitrary data
const tx = await resolver.setData(node, "agent-context", "0x0001ABCD...");
await tx.wait();
// Retrieve arbitrary data
const result = await resolver.data(node, "agent-context");
```
### Backwards Compatibility
This proposal introduces a new resolver profile and does not affect existing ENS functionality. It introduces no breaking changes.
### Security Considerations
None.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
[ERC-165]: https://eips.ethereum.org/EIPS/eip-165
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-3: Reverse Resolution
Specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS (formerly [EIP-181](https://eips.ethereum.org/EIPS/eip-181)).
### Abstract
This ENSIP specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS. This permits associating a human-readable name with any Ethereum blockchain address. Resolvers can be certain that the reverse record was published by the owner of the Ethereum address in question.
### Motivation
While name services are mostly used for forward resolution - going from human-readable identifiers to machine-readable ones - there are many use-cases in which reverse resolution is useful as well:
* Applications that allow users to monitor accounts benefit from showing the name of an account instead of its address, even if it was originally added by address.
* Attaching metadata such as descriptive information to an address allows retrieving this information regardless of how the address was originally discovered.
* Anyone can configure a name to resolve to an address, regardless of ownership of that address. Reverse records allow the owner of an address to claim a name as authoritative for that address.
### Specification
Reverse ENS records are stored in the ENS hierarchy in the same fashion as regular records, under a reserved domain, `addr.reverse`. To generate the ENS name for a given account's reverse records, convert the account to hexadecimal representation in lower-case, and append `addr.reverse`. For instance, the ENS registry's address at `0x112234455c3a32fd11230c42e7bccd4a84e02010` has any reverse records stored at `112234455c3a32fd11230c42e7bccd4a84e02010.addr.reverse`.
Note that this means that contracts wanting to do dynamic reverse resolution of addresses will need to perform hex encoding in the contract.
#### Registrar
The owner of the `addr.reverse` domain will be a registrar that permits the caller to take ownership of the reverse record for their own address. It provides the following methods:
##### function claim(address owner) returns (bytes32 node)
When called by account `x`, instructs the ENS registry to transfer ownership of the name `hex(x) + '.addr.reverse'` to the provided address, and return the namehash of the ENS record thus transferred.
Allowing the caller to specify an owner other than themselves for the relevant node facilitates contracts that need accurate reverse ENS entries delegating this to their creators with a minimum of code inside their constructor:
```solidity
reverseRegistrar.claim(msg.sender)
```
##### function claimWithResolver(address owner, address resolver) returns (bytes32 node)
When called by account `x`, instructs the ENS registry to set the resolver of the name `hex(x) + '.addr.reverse'` to the specified resolver, then transfer ownership of the name to the provided address, and return the namehash of the ENS record thus transferred. This method facilitates setting up a custom resolver and owner in fewer transactions than would be required if calling `claim`.
##### function setName(string name) returns (bytes32 node)
When called by account `x`, sets the resolver for the name `hex(x) + '.addr.reverse'` to a default resolver, and sets the name record on that name to the specified name. This method facilitates setting up simple reverse records for users in a single transaction.
#### Resolver interface
A new resolver interface is defined, consisting of the following method:
```solidity
function name(bytes32 node) constant returns (string);
```
Resolvers that implement this interface must return a valid ENS name for the requested node, or the empty string if no name is defined for the requested node.
The interface ID of this interface is 0x691f3431.
Future ENSIPs may specify more record types appropriate to reverse ENS records.
### Appendix 1: Registrar implementation
This registrar, written in Solidity, implements the specifications outlined above.
```solidity
pragma solidity ^0.4.10;
import "./AbstractENS.sol";
contract Resolver {
function setName(bytes32 node, string name) public;
}
/**
* @dev Provides a default implementation of a resolver for reverse records,
* which permits only the owner to update it.
*/
contract DefaultReverseResolver is Resolver {
AbstractENS public ens;
mapping(bytes32=>string) public name;
/**
* @dev Constructor
* @param ensAddr The address of the ENS registry.
*/
function DefaultReverseResolver(AbstractENS ensAddr) {
ens = ensAddr;
}
/**
* @dev Only permits calls by the reverse registrar.
* @param node The node permission is required for.
*/
modifier owner_only(bytes32 node) {
require(msg.sender == ens.owner(node));
_;
}
/**
* @dev Sets the name for a node.
* @param node The node to update.
* @param _name The name to set.
*/
function setName(bytes32 node, string _name) public owner_only(node) {
name[node] = _name;
}
}
contract ReverseRegistrar {
// namehash('addr.reverse')
bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
AbstractENS public ens;
Resolver public defaultResolver;
/**
* @dev Constructor
* @param ensAddr The address of the ENS registry.
* @param resolverAddr The address of the default reverse resolver.
*/
function ReverseRegistrar(AbstractENS ensAddr, Resolver resolverAddr) {
ens = ensAddr;
defaultResolver = resolverAddr;
}
/**
* @dev Transfers ownership of the reverse ENS record associated with the
* calling account.
* @param owner The address to set as the owner of the reverse record in ENS.
* @return The ENS node hash of the reverse record.
*/
function claim(address owner) returns (bytes32 node) {
return claimWithResolver(owner, 0);
}
/**
* @dev Transfers ownership of the reverse ENS record associated with the
* calling account.
* @param owner The address to set as the owner of the reverse record in ENS.
* @param resolver The address of the resolver to set; 0 to leave unchanged.
* @return The ENS node hash of the reverse record.
*/
function claimWithResolver(address owner, address resolver) returns (bytes32 node) {
var label = sha3HexAddress(msg.sender);
node = sha3(ADDR_REVERSE_NODE, label);
var currentOwner = ens.owner(node);
// Update the resolver if required
if(resolver != 0 && resolver != ens.resolver(node)) {
// Transfer the name to us first if it's not already
if(currentOwner != address(this)) {
ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, this);
currentOwner = address(this);
}
ens.setResolver(node, resolver);
}
// Update the owner if required
if(currentOwner != owner) {
ens.setSubnodeOwner(ADDR_REVERSE_NODE, label, owner);
}
return node;
}
/**
* @dev Sets the `name()` record for the reverse ENS record associated with
* the calling account. First updates the resolver to the default reverse
* resolver if necessary.
* @param name The name to set for this address.
* @return The ENS node hash of the reverse record.
*/
function setName(string name) returns (bytes32 node) {
node = claimWithResolver(this, defaultResolver);
defaultResolver.setName(node, name);
return node;
}
/**
* @dev Returns the node hash for a given account's reverse records.
* @param addr The address to hash
* @return The ENS node hash.
*/
function node(address addr) constant returns (bytes32 ret) {
return sha3(ADDR_REVERSE_NODE, sha3HexAddress(addr));
}
/**
* @dev An optimised function to compute the sha3 of the lower-case
* hexadecimal representation of an Ethereum address.
* @param addr The address to hash
* @return The SHA3 hash of the lower-case hexadecimal encoding of the
* input address.
*/
function sha3HexAddress(address addr) private returns (bytes32 ret) {
addr; ret; // Stop warning us about unused variables
assembly {
let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000
let i := 40
loop:
i := sub(i, 1)
mstore8(i, byte(and(addr, 0xf), lookup))
addr := div(addr, 0x10)
i := sub(i, 1)
mstore8(i, byte(and(addr, 0xf), lookup))
addr := div(addr, 0x10)
jumpi(loop, i)
ret := sha3(0, 40)
}
}
}
```
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-4: Support for contract ABIs
A mechanism for storing ABI definitions in ENS, for easy lookup of contract interfaces by callers (formerly [EIP-205](https://eips.ethereum.org/EIPS/eip-205)).
### Abstract
ABIs are important metadata required for interacting with most contracts. At present, they are typically supplied out-of-band, which adds an additional burden to interacting with contracts, particularly on a one-off basis or where the ABI may be updated over time. The small size of ABIs permits an alternative solution, storing them in ENS, permitting name lookup and ABI discovery via the same process.
ABIs are typically quite compact; the largest in-use ABI we could find, that for the DAO, is 9450 bytes uncompressed JSON, 6920 bytes uncompressed CBOR, and 1128 bytes when the JSON form is compressed with zlib. Further gains on CBOR encoding are possible using a CBOR extension that permits eliminating repeated strings, which feature extensively in ABIs. Most ABIs, however, are far shorter than this, consisting of only a few hundred bytes of uncompressed JSON.
This ENSIP defines a resolver profile for retrieving contract ABIs, as well as encoding standards for storing ABIs for different applications, allowing the user to select between different representations based on their need for compactness and other considerations such as onchain access.
### Specification
#### ABI encodings
In order to allow for different tradeoffs between onchain size and accessibility, several ABI encodings are defined. Each ABI encoding is defined by a unique constant with only a single bit set, allowing for the specification of 256 unique encodings in a single uint.
The currently recognised encodings are:
| ID | Description |
| -- | -------------------- |
| 1 | JSON |
| 2 | zlib-compressed JSON |
| 4 | CBOR |
| 8 | URI |
This table may be extended in future through the ENSIP process.
Encoding type 1 specifies plaintext JSON, uncompressed; this is the standard format in which ABIs are typically encoded, but also the bulkiest, and is not easily parseable onchain.
Encoding type 2 specifies zlib-compressed JSON. This is significantly smaller than uncompressed JSON, and is straightforward to decode offchain. However, it is impractical for onchain consumers to use.
Encoding type 4 is [CBOR](https://cbor.io). CBOR is a binary encoding format that is a superset of JSON, and is both more compact and easier to parse in limited environments such as the EVM. Consumers that support CBOR are strongly encouraged to also support the [stringref extension](http://cbor.schmorp.de/stringref) to CBOR, which provides significant additional reduction in encoded size.
Encoding type 8 indicates that the ABI can be found elsewhere, at the specified URI. This is typically the most compact of the supported forms, but also adds external dependencies for implementers. The specified URI may use any schema, but HTTP, IPFS, and Swarm are expected to be the most common.
#### Resolver profile
A new resolver interface is defined, consisting of the following method:
```solidity
function ABI(bytes32 node, uint256 contentType) constant returns (uint256, bytes);
```
The interface ID of this interface is 0x2203ab56.
contentType is a bitfield, and is the bitwise OR of all the encoding types the caller will accept. Resolvers that implement this interface must return an ABI encoded using one of the requested formats, or `(0, "")` if they do not have an ABI for this function, or do not support any of the requested formats.
The `abi` resolver profile is valid on both forward and reverse records.
#### ABI lookup process
When attempting to fetch an ABI based on an ENS name, implementers should first attempt an ABI lookup on the name itself. If that lookup returns no results, they should attempt a reverse lookup on the Ethereum address the name resolves to.
Implementers should support as many of the ABI encoding formats as practical.
### Rationale
Storing ABIs onchain avoids the need to introduce additional dependencies for applications wishing to fetch them, such as swarm or HTTP access. Given the typical compactness of ABIs, we believe this is a worthwhile tradeoff in many cases.
The two-step resolution process permits different names to provide different ABIs for the same contract, such as in the case where it's useful to provide a minimal ABI to some callers, as well as specifying ABIs for contracts that did not specify one of their own. The fallback to looking up an ABI on the reverse record permits contracts to specify their own canonical ABI, and prevents the need for duplication when multiple names reference the same contract without the need for different ABIs.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-5: Text Records
A standard for storage of text records in ENS (formerly [EIP-634](https://eips.ethereum.org/EIPS/eip-634)).
### Abstract
This ENSIP defines a resolver profile for ENS that permits the lookup of arbitrary key-value text data. This allows ENS name holders to associate e-mail addresses, URLs and other informational data with a ENS name.
### Motivation
There is often a desire for human-readable metadata to be associated with otherwise machine-driven data; used for debugging, maintenance, reporting and general information.
In this ENSIP we define a simple resolver profile for ENS that permits ENS names to associate arbitrary key-value text.
### Specification
#### Resolver Profile
A new resolver interface is defined, consisting of the following method:
```solidity
interface IERC634 {
/// @notice Returns the text data associated with a key for an ENS name
/// @param node A nodehash for an ENS name
/// @param key A key to lookup text data for
/// @return The text data
function text(bytes32 node, string key) view returns (string text);
}
```
The EIP-165 interface ID of this interface is `0x59d1d43c`.
The `text` data may be any arbitrary UTF-8 string. If the key is not present, the empty string must be returned.
#### Global Keys
Global Keys must be made up of lowercase letters, numbers and the hyphen (-).
* **avatar** - a URL to an image used as an avatar or logo
* **description** - A description of the name
* **display** - a canonical display name for the ENS name; this MUST match the ENS name when its case is folded, and clients should ignore this value if it does not (e.g. `"ricmoo.eth"` could set this to `"RicMoo.eth"`)
* **email** - an e-mail address
* **keywords** - A list of comma-separated keywords, ordered by most significant first; clients that interpresent this field may choose a threshold beyond which to ignore
* **mail** - A physical mailing address
* **notice** - A notice regarding this name
* **location** - A generic location (e.g. `"Toronto, Canada"`)
* **phone** - A phone number as an E.164 string
* **url** - a website URL
#### Service Keys
Service Keys must be made up of a *reverse dot notation* for a namespace which the service owns, for example, DNS names (e.g. `.com`, `.io`, etc) or ENS name (i.e. `.eth`). Service Keys must contain at least one dot.
This allows new services to start using their own keys without worrying about colliding with existing services and also means new services do not need to update this document.
The following services are common, which is why recommendations are provided here, but ideally a service would declare its own key.
* **com.github** - a GitHub username
* **com.peepeth** - a Peepeth username
* **com.linkedin** - a LinkedIn username
* **com.twitter** - a Twitter username
* **io.keybase** - a Keybase username
* **org.telegram** - a Telegram username
This technique also allows for a service owner to specify a hierarchy for their keys, such as:
* **com.example.users**
* **com.example.groups**
* **com.example.groups.public**
* **com.example.groups.private**
#### Legacy Keys
The following keys were specified in earlier versions of this ENSIP.
Their use is not likely very wide, but applications attempting maximal compatibility may wish to query these keys as a fallback if the above replacement keys fail.
* **vnd.github** - a GitHub username (renamed to `com.github`)
* **vnd.peepeth** - a peepeth username (renamed to `com.peepeth`)
* **vnd.twitter** - a Twitter username (renamed to `com.twitter`)
### Rationale
#### Application-specific vs general-purpose record types
Rather than define a large number of specific record types (each for generally human-readable data) such as `url` and `email`, we follow an adapted model of DNS's `TXT` records, which allow for a general keys and values, allowing future extension without adjusting the resolver, while allowing applications to use custom keys for their own purposes.
### Backwards Compatibility
Not applicable.
### Security Considerations
None.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-6: DNS-in-ENS
Defines a resolver profile for ENS that provides features for storage and lookup of DNS records (formerly [EIP-1185](https://eips.ethereum.org/EIPS/eip-1185)).
### Abstract
This ENSIP defines a resolver profile for ENS that provides features for storage and lookup of DNS records. This allows ENS to be used as a store of authoritative DNS information.
### Motivation
ENS is a highly desirable store for DNS information. It provides the distributed authority of DNS without conflating ownership and authoritative serving of information. With ENS, the owner of a domain has full control over their own DNS records. Also, ENS has the ability (through smart contracts) for a domain's subdomains to be irrevocably assigned to another entity.
### Specification
The resolver profile to support DNS on ENS follows the resolver specification as defined in #137.
Traditionally, DNS is a zone-based system in that all of the records for a zone are kept together in the same file. This has the benefit of simplicity and atomicity of zone updates, but when transposed to ENS can result in significant gas costs for simple changes. As a result, the resolver works on the basis of record sets. A record set is uniquely defined by the tuple (domain, name, resource record type), for example the tuple (example.com, [www.example.com](http://www.example.com), A) defines the record set of A records for the name [www.example.com](http://www.example.com) in the domain example.com. A record set can contain 0 or more values, for example if [www.example.com](http://www.example.com) has A records 1.2.3.4 and 5.6.7.8 then the aforementioned tuple will have two values.
The choice to work at the level of record sets rather than zones means that this specification cannot completely support some features of DNS, such as zone transfers and DNSSEC. It would be possible to build a different resolver profile that works at the zone level, however it would be very expensive to carry out updates and so is not considered further for this ENSIP.
The DNS resolver interface consists of two functions to set DNS information and two functions to query DNS information.
#### setDNSRecords(bytes32 node, bytes data)
`setDNSRecords()` sets, updates or clears 1 or more DNS records for a given node. It has function signature `0x0af179d7`.
The arguments for the function are as follows:
* node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137
* data: 1 or more DNS records in DNS wire format. Any record that is supplied without a value will be cleared. Note that all records in the same RRset should be contiguous within the data; if not then the later RRsets will overwrite the earlier one(s)
#### clearDNSZone(bytes32 node)
`clearDNSZone()` removes all DNS records for the domain. It has function signature `0xad5780af`.
Although it is possible to clear records individually with `setDNSRecords()` as described above this requires the owner to know all of the records that have been set (as the resolver has no methods to iterate over the records for a given domain), and might require multiple transactions. `clearDNSZone()` removes all zone information in a single operation.
The arguments for the function is as follows:
* node: the namehash of the fully-qualified domain in ENS for which to clear the records. Namehashes are defined in #137
#### dnsRecords(bytes32 node, bytes32 name, uint16 resource) view returns (bytes)
`dnsRecords()` obtains the DNS records for a given node, name and resource. It has function signature `0x2461e851`.
The arguments for the function are as follows:
* node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137
* name: the `keccak256()` hash of the name of the record in DNS wire format.
* resource: the resource record ID. Resource record IDs are defined in [https://en.wikipedia.org/wiki/List\\\_of\\\_DNS\\\_record\\\_types](https://en.wikipedia.org/wiki/List\\_of\\_DNS\\_record\\_types)
The function returns all matching records in DNS wire format. If there are no records present the function will return nothing.
#### hasDNSRecords(bytes32 node, bytes32 name) view returns (bool)
`hasDNSRecords()` reports if there are any records for the provided name in the domain. It has function signature `0x4cbf6ba4`.
This function is needed by DNS resolvers when working with wildcard resources as defined in [https://tools.ietf.org/html/rfc4592](https://tools.ietf.org/html/rfc4592)
The arguments for the function are as follows:
* node: the namehash of the fully-qualified domain in ENS for which to set the records. Namehashes are defined in #137
* name: the `keccak256()` hash of the name of the record in DNS wire format.
The function returns `true` if there are any records for the provided node and name, otherwise `false`.
### Backwards Compatibility
Not applicable.
### Implementation
The reference implementation of the DNS resolver is at [https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/DNSResolver.sol](https://github.com/wealdtech/wealdtech-solidity/blob/master/contracts/ens/DNSResolver.sol)
[https://github.com/wealdtech/ethereal.git](https://github.com/wealdtech/ethereal.git) can be used to test the functionality of the resolver with the "dns set", "dns get" and "dns clear" commands.
### Test Cases
Test cases for the DNS resolver are at [https://github.com/wealdtech/wealdtech-solidity/blob/master/test/ens/DNSResolver.js](https://github.com/wealdtech/wealdtech-solidity/blob/master/test/ens/DNSResolver.js)
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-7: Contenthash field
Introduces a field for storing content addresses and hashes in ENS (formerly [EIP-1577](https://eips.ethereum.org/EIPS/eip-1577)).
### Abstract
This ENSIP introduces the new `contenthash` field for ENS resolvers, allowing for a better defined system of mapping names to network and content addresses. Additionally the `content` and `multihash` fields are deprecated.
### Motivation
Multiple applications including [Metamask](https://metamask.io) and mobile clients such as [Status](https://status.im) have begun resolving ENS names to content hosted on distributed systems such as [IPFS](https://ipfs.io) and [Swarm](https://swarm-guide.readthedocs.io). Due to the various ways content can be stored and addressed, a standard is required so these applications know how to resolve names and that domain owners know how their content will be resolved.
The `contenthash` field allows for easy specification of network and content addresses in ENS.
### Specification
The field `contenthash` is introduced, which permits a wide range of protocols to be supported by ENS names. Resolvers supporting this field MUST return `true` when the `supportsInterface` function is called with argument `0xbc1c58d1`.
The fields `content` and `multihash` are deprecated.
The value returned by `contenthash` MUST be represented as a machine-readable [multicodec](https://github.com/multiformats/multicodec). The format is specified as follows:
```go
```
protoCodes and their meanings are specified in the [multiformats/multicodec](https://github.com/multiformats/multicodec) repository.
The encoding of the value depends on the content type specified by the protoCode. Values with protocodes of 0xe3 and 0xe4 represent IPFS and Swarm content; these values are encoded as v1 [CIDs](https://github.com/multiformats/cid) without a base prefix, meaning their value is formatted as follows:
```go
```
When resolving a `contenthash`, applications MUST use the protocol code to determine what type of address is encoded, and resolve the address appropriately for that protocol, if supported.
#### Example
**IPFS**
Input data:
```go
storage system: IPFS (0xe3)
CID version: 1 (0x01)
content type: dag-pb (0x70)
hash function: sha2-256 (0x12)
hash length: 32 bytes (0x20)
hash: 29f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f
```
Binary format:
```go
0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f
```
Text format:
```txt
ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4
```
#### Swarm
Input data:
```go
storage system: Swarm (0xe4)
CID version: 1 (0x01)
content type: swarm-manifest (0xfa)
hash function: keccak256 (0x1b)
hash length: 32 bytes (0x20)
hash: d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162
```
Binary format:
```go
0xe40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162
```
Text format:
```go
bzz://d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162
```
Example usage with swarm hash:
```go
$ swarm hash ens contenthash d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162
> e40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162
```
#### Fallback
In order to support names that have an IPFS or Swarm hash in their `content` field, a grace period MUST be implemented offering those name holders time to update their names. If a resolver does not support the `multihash` interface, it MUST be checked whether they support the `content` interface. If they do, the value of that field SHOULD be treated in a context dependent fashion and resolved. This condition MUST be enforced until at least March 31st, 2019.
#### Implementation
To support `contenthash`, a new resolver has been developed and can be found [here](https://github.com/ensdomains/resolvers/blob/master/contracts/PublicResolver.sol), you can also find this smart contract deployed on:
* Mainnet : [0xd3ddccdd3b25a8a7423b5bee360a42146eb4baf3](https://etherscan.io/address/0xd3ddccdd3b25a8a7423b5bee360a42146eb4baf3)
* Ropsten : [0xde469c7106a9fbc3fb98912bb00be983a89bddca](https://ropsten.etherscan.io/address/0xde469c7106a9fbc3fb98912bb00be983a89bddca)
There are also implementations in multiple languages to encode and decode `contenthash`:
* [JavaScript](https://github.com/pldespaigne/content-hash)
* [Python](https://github.com/filips123/ContentHashPy)
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-8: Interface Discovery
Defines a method of associating contract interfaces with ENS names and addresses, and of discovering those interfaces (formerly [EIP-1844](https://eips.ethereum.org/EIPS/eip-1844)).
### Abstract
This ENSIP specifies a method for exposing interfaces associated with an ENS name or an address (typically a contract address) and allowing applications to discover those interfaces and interact with them. Interfaces can be implemented either by the target contract (if any) or by any other contract.
### Motivation
EIP 165 supports interface discovery - determining if the contract at a given address supports a requested interface. However, in many cases it's useful to be able to discover functionality associated with a name or an address that is implemented by other contracts.
For example, a token contract may not itself provide any kind of 'atomic swap' functionality, but there may be associated contracts that do. With ENS interface discovery, the token contract can expose this metadata, informing applications where they can find that functionality.
### Specification
A new profile for ENS resolvers is defined, consisting of the following method:
```solidity
function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address);
```
The EIP-165 interface ID of this interface is `0xb8f2bbb4`.
Given an ENS name hash `node` and an EIP-165 `interfaceID`, this function returns the address of an appropriate implementer of that interface. If there is no interface matching that interface ID for that node, 0 is returned.
The address returned by `interfaceImplementer` MUST refer to a smart contract.
The smart contract at the returned address SHOULD implement EIP-165.
Resolvers implementing this interface MAY utilise a fallback strategy: If no matching interface was explicitly provided by the user, query the contract returned by `addr()`, returning its address if the requested interface is supported by that contract, and 0 otherwise. If they do this, they MUST ensure they return 0, rather than reverting, if the target contract reverts.
This field may be used with both forward resolution and reverse resolution.
### Rationale
A naive approach to this problem would involve adding this method directly to the target contract. However, doing this has several shortcomings:
1. Each contract must maintain its own list of interface implementations.
2. Modifying this list requires access controls, which the contract may not have previously required.
3. Support for this must be designed in when the contract is written, and cannot be retrofitted afterwards.
4. Only one canonical list of interfaces can be supported.
Using ENS resolvers instead mitigates these shortcomings, making it possible for anyone to associate interfaces with a name, even for contracts not previously built with this in mind.
### Backwards Compatibility
There are no backwards compatibility issues.
### Implementation
The PublicResolver in the [ensdomains/resolvers](https://github.com/ensdomains/resolvers/) repository implements this interface.
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { EnsipHeader } from "../../components/EnsipHeader";
## ENSIP-9: Multichain Address resolution
Introduces new overloads for the `addr` field for ENS resolvers, which permit resolution of addresses for other blockchains via ENS (formerly [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304)).
### Motivation
With the increasing uptake of ENS by multi-coin wallets, wallet authors have requested the ability to resolve addresses for non-Ethereum chains inside ENS. This specification standardises a way to enter and retrieve these addresses in a cross-client fashion.
### Specification
A new accessor function for resolvers is specified:
```solidity
function addr(bytes32 node, uint coinType) external view returns(bytes memory);
```
The EIP165 interface ID for this function is 0xf1cb7e06.
When called on a resolver, this function must return the cryptocurrency address for the specified namehash and coin type. A zero-length string must be returned if the specified coin ID does not exist on the specified node.
`coinType` is the cryptocurrency coin type index from [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md).
The return value is the cryptocurrency address in its native binary format. Detailed descriptions of the binary encodings for several popular chains are provided in the Address Encoding section below.
A new event for resolvers is defined:
```solidity
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
```
Resolvers MUST emit this event on each change to the address for a name and coin type.
#### Recommended accessor functions
The following function provides the recommended interface for changing the addresses stored for a node. Resolvers SHOULD implement this interface for setting addresses unless their needs dictate a different interface.
```solidity
function setAddr(bytes32 node, uint coinType, bytes calldata addr);
```
`setAddr` adds or replaces the address for the given node and coin type. The parameters for this function are as per those described in `addr()` above.
This function emits an `AddressChanged` event with the new address; see also the backwards compatibility section below for resolvers that also support `addr(bytes32)`.
#### Address Encoding
In general, the native binary representation of the address should be used, without any checksum commonly used in the text representation.
A table of encodings for common blockchains is provided, followed by a more detailed description of each format. In the table, 'encodings' lists the address encodings supported by that chain, along with any relevant parameters. Details of those address encodings are described in the following sections.
| Cryptocurrency | Coin Type | Encoding |
| ---------------- | --------- | -------------------------------------------------- |
| Bitcoin | 0 | P2PKH(0x00), P2SH(0x05), SegWit('bc') |
| Litecoin | 2 | P2PKH(0x30), P2SH(0x32), P2SH(0x05), SegWit('ltc') |
| Dogecoin | 3 | P2PKH(0x1e), P2SH(0x16) |
| Monacoin | 22 | P2PKH(0x32), P2SH(0x05) |
| Ethereum | 60 | ChecksummedHex |
| Ethereum Classic | 61 | ChecksummedHex |
| Rootstock | 137 | ChecksummedHex(30) |
| Ripple | 144 | Ripple |
| Bitcoin Cash | 145 | P2PKH(0x00), P2SH(0x05), CashAddr |
| Binance | 714 | Bech32('bnb') |
**P2PKH(version)**
Pay to Public Key Hash addresses are [base58check](https://en.bitcoin.it/wiki/Base58Check_encoding) encoded. After decoding, the first byte is a version byte. For example, the Bitcoin address `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` base58check decodes to the 21 bytes `0062e907b15cbf27d5425399ebf6f0fb50ebb88f18`.
P2PKH addresses have a version byte, followed by a 20 byte pubkey hash. Their canonical encoding is their scriptPubkey encoding (specified [here](https://en.bitcoin.it/wiki/Transaction#Types_of_Transaction)) is `OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG`.
The above example address is thus encoded as the 25 bytes `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac`.
**P2SH(version)**
P2SH addresses are base58check encoded in the same manner as P2PKH addresses. P2SH addresses have a version, followed by a 20 byte script hash. Their scriptPubkey encoding (specified [here](https://en.bitcoin.it/wiki/Transaction#Pay-to-Script-Hash)) is `OP_HASH160 OP_EQUAL`. A Bitcoin address of `3Ai1JZ8pdJb2ksieUV8FsxSNVJCpoPi8W6` decodes to the 21 bytes `0562e907b15cbf27d5425399ebf6f0fb50ebb88f18` and is encoded as the 23 bytes `a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1887`.
**SegWit(hrp)**
SegWit addresses are encoded with [bech32](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). Bech32 addresses consist of a human-readable part - 'bc' for Bitcoin mainnet - and a machine readable part. For SegWit addresses, this decodes to a 'witness version', between 0 and 15, and a 'witness program', as defined in [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki).
The scriptPubkey encoding for a bech32 address, as defined in BIP141, is `OP_n`, where `n` is the witness version, followed by a push of the witness program. Note this warning from BIP173:
> Implementations should take special care when converting the address to a scriptPubkey, where witness version n is stored as OP\_n. OP\_0 is encoded as 0x00, but OP\_1 through OP\_16 are encoded as 0x51 though 0x60 (81 to 96 in decimal). If a bech32 address is converted to an incorrect scriptPubKey the result will likely be either unspendable or insecure.
For example, the Bitcoin SegWit address `BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4` decodes to a version of `0` and a witness script of `751e76e8199196d454941c45d1b3a323f1433bd6`, and then encodes to a scriptPubkey of `0014751e76e8199196d454941c45d1b3a323f1433bd6`.
**ChecksummedHex(chainId?)**
To translate a text format checksummed hex address into binary format, simply remove the '0x' prefix and hex decode it. `0x314159265dD8dbb310642f98f50C066173C1259b` is hex-decoded and stored as the 20 bytes `314159265dd8dbb310642f98f50c066173c1259b`.
A checksum format is specified by EIP-55, and extended by [RSKIP60](https://github.com/rsksmart/RSKIPs/blob/master/IPs/RSKIP60.md), which specifies a means of including the chain ID in the checksum. The checksum on a text format address must be checked. Addresses with invalid checksums that are not all uppercase or all lowercase MUST be rejected with an error. Implementations may choose whether to accept non-checksummed addresses, but the authors recommend at least providing a warning to users in this situation.
When encoding an address from binary to text, an EIP55/RSKIP60 checksum MUST be used - so the correct encoding of the above address for Ethereum is `0x314159265dD8dbb310642f98f50C066173C1259b`.
**Ripple**
Ripple addresses are encoded using a version of base58check with an alternative alphabet, described [here](https://xrpl.org/base58-encodings.html). Two types of ripple addresses are supported, 'r-addresses', and 'X-addresss'. r-addresses consist of a version byte followed by a 20 byte hash, while X-addresses consist of a version byte, a 20 byte hash, and a tag, specified [here](https://github.com/xrp-community/standards-drafts/issues/6).
Both address types should be stored in ENS by performing ripple's version of base58check decoding and storing them directly (including version byte). For example, the ripple address `rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn` decodes to and is stored as `004b4e9c06f24296074f7bc48f92a97916c6dc5ea9`, while the address `X7qvLs7gSnNoKvZzNWUT2e8st17QPY64PPe7zriLNuJszeg` decodes to and is stored as `05444b4e9c06f24296074f7bc48f92a97916c6dc5ea9000000000000000000`.
**CashAddr**
Bitcoin Cash defines a new address format called 'CashAddr', specified [here](https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md). This uses a variant of bech32 encoding to encode and decode (non-segwit) Bitcoin Cash addresses, using a prefix of 'bitcoincash:'. A CashAddr should be decoded using this bech32 variant, then converted and stored based on its type (P2PKH or P2SH) as described in the relevant sections above.
**Bech32**
[Bech32](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) addresses consist of a human-readable part - for example, 'bnb' for Binance - and a machine readable part. The encoded data is simply the address, which can be converted to binary and stored directly.
For example, the BNB address `bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2` decodes to the binary representation `40c2979694bbc961023d1d27be6fc4d21a9febe6`, which is stored directly in ENS.
#### Example
An example implementation of a resolver that supports this ENSIP is provided here:
```solidity
pragma solidity ^0.5.8;
contract AddrResolver is ResolverBase {
bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de;
bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06;
uint constant private COIN_TYPE_ETH = 60;
event AddrChanged(bytes32 indexed node, address a);
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
mapping(bytes32=>mapping(uint=>bytes)) _addresses;
/**
* Sets the address associated with an ENS node.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param a The address to set.
*/
function setAddr(bytes32 node, address a) external authorised(node) {
setAddr(node, COIN_TYPE_ETH, addressToBytes(a));
}
/**
* Returns the address associated with an ENS node.
* @param node The ENS node to query.
* @return The associated address.
*/
function addr(bytes32 node) public view returns (address) {
bytes memory a = addr(node, COIN_TYPE_ETH);
if(a.length == 0) {
return address(0);
}
return bytesToAddress(a);
}
function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) {
emit AddressChanged(node, coinType, a);
if(coinType == COIN_TYPE_ETH) {
emit AddrChanged(node, bytesToAddress(a));
}
_addresses[node][coinType] = a;
}
function addr(bytes32 node, uint coinType) public view returns(bytes memory) {
return _addresses[node][coinType];
}
function supportsInterface(bytes4 interfaceID) public pure returns(bool) {
return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || super.supportsInterface(interfaceID);
}
}
```
#### Implementation
An implementation of this interface is provided in the [ensdomains/resolvers](https://github.com/ensdomains/resolvers/) repository.
### Backwards Compatibility
If the resolver supports the `addr(bytes32)` interface defined in ENSIP-1, the resolver MUST treat this as a special case of this new specification in the following ways:
1. The value returned by `addr(node)` from ENSIP-1 should always match the value returned by `addr(node, 60)` (60 is the coin type ID for Ethereum).
2. Anything that causes the `AddrChanged` event from ENSIP-1 to be emitted must also emit an `AddressChanged` event from this ENSIP, with the `coinType` specified as 60, and vice-versa.
### Tests
The table below specifies test vectors for valid address encodings for each cryptocurrency described above.
| Cryptocurrency | Coin Type | Text | Onchain (hex) |
| -------------- | --------- | -------------------------------------------------------- | ---------------------------------------------------------------- |
| Bitcoin | 0 | `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` | `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac` |
| | | `3Ai1JZ8pdJb2ksieUV8FsxSNVJCpoPi8W6` | `a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1887` |
| | | `BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4` | `0014751e76e8199196d454941c45d1b3a323f1433bd6` |
| Litecoin | 2 | `LaMT348PWRnrqeeWArpwQPbuanpXDZGEUz` | `76a914a5f4d12ce3685781b227c1f39548ddef429e978388ac` |
| | | `MQMcJhpWHYVeQArcZR3sBgyPZxxRtnH441` | `a914b48297bff5dadecc5f36145cec6a5f20d57c8f9b87` |
| | | `ltc1qdp7p2rpx4a2f80h7a4crvppczgg4egmv5c78w8` | `0014687c150c26af5493befeed7036043812115ca36c` |
| Dogecoin | 3 | `DBXu2kgc3xtvCUWFcxFE3r9hEYgmuaaCyD` | `76a9144620b70031f0e9437e374a2100934fba4911046088ac` |
| | | `AF8ekvSf6eiSBRspJjnfzK6d1EM6pnPq3G` | `a914f8f5d99a9fc21aa676e74d15e7b8134557615bda87` |
| Monacoin | 22 | `MHxgS2XMXjeJ4if2PRRbWYcdwZPWfdwaDT` | `76a9146e5bb7226a337fe8307b4192ae5c3fab9fa9edf588ac` |
| Ethereum | 60 | `0x314159265dD8dbb310642f98f50C066173C1259b` | `314159265dd8dbb310642f98f50c066173c1259b` |
| Rootstock | 137 | `0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD` | `5aaeb6053f3e94c9b9a09f33669435e7ef1beaed` |
| Ripple | 144 | `rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn` | `004b4e9c06f24296074f7bc48f92a97916c6dc5ea9` |
| | | `X7qvLs7gSnNoKvZzNWUT2e8st17QPY64PPe7zriLNuJszeg` | `05444b4e9c06f24296074f7bc48f92a97916c6dc5ea9000000000000000000` |
| Bitcoin Cash | 145 | `1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu` | `76a91476a04053bda0a88bda5177b86a15c3b29f55987388ac` |
| | | `bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a` | `76a91476a04053bda0a88bda5177b86a15c3b29f55987388ac` |
| | | `3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC` | `a91476a04053bda0a88bda5177b86a15c3b29f55987387` |
| | | `bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq` | `a91476a04053bda0a88bda5177b86a15c3b29f55987387` |
| Binance | 714 | `bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2` | `40c2979694bbc961023d1d27be6fc4d21a9febe6` |
### Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
import { Table } from '../../components/ui/Table'
import ensips from '../../data/generated/ensips.json'
## ENS Improvement Proposals
This page contains a summary of all the ENS Improvement Proposals (ENSIPs) that have been proposed, and their current status.
Improvement Proposals have included anything from new contract features, to text record standards, protocol features, and more.
### ENSIPs
[ensip.title, ensip.status])} />
### Propose an ENSIP
Feel free to [open a pull request](https://github.com/ensdomains/ensips/pulls) on the `ensdomains/ensips` repository.
import { Badge } from '../../components/ui/Badge'
import { Card } from '../../components/ui/Card'
## Hosting a Decentralized Website \[Introduction to hosting a decentralized website using ENS]
### ContentHash
The ContentHash is a very popular component of an ENS name, first introduced in [ENSIP-7](/ensip/7).
It can be queried by hitting the [contenthash(bytes32)](/resolvers/interfaces#0xbc1c58d1) function on a name's resolver.
You can also [set the contenthash on a name](/resolvers/interfaces#0x304e6ade) if the resolver supports it.
{['ipfs://bafy...', 'bzz://2477', 'ar://HGa8...'].map((tag) => (
{tag}
))}
### Hosting & Pinning
When it comes to hosting your files there are many options to choose from.
{['IPFS / Filecoin', 'Swarm', 'Arweave'].map((tag) => (
{tag}
))}
Popular options include [IPFS](https://ipfs.io), [Swarm](https://ethswarm.org), and [Arweave](https://arweave.org).
Depending on what option you go with your files are either permanently stored on a network,
or require to be actively stored on at least one machine, also known as "pinning".
#### Deploy your sites
Several helpful tools and platforms exist that you can use to deploy your website to IPFS, Swarm, or Arweave.
| Tool | Network Support |
| ---------------------------------------------------------------- | ---------------- |
| [Omnipin](https://omnipin.eth.link) | IPFS and Swarm |
| [Orbiter](https://orbiter.host) | IPFS |
| [IPFS Deploy Action](https://github.com/ipfs/ipfs-deploy-action) | IPFS |
| [4EVERLAND](https://4everland.org) | IPFS and Arweave |
### Setting your ContentHash
If you are using the public resolver (the default for names registered using the ENS Manager App), you can set the contenthash directly from within the [ENS Manager App](https://app.ens.domains).
If you are using a custom resolver, or are writing your own resolver you will be able to have more fine grained control over the contenthash field.
See [ENSIP-7](/ensip/7) for more information on the contenthash field.
### Browser Support & Gateways
At the moment of writing, major browsers such as Chrome, Firefox and Safari do not natively support accessing decentralized websites.
If you want to directly access .eth websites without relying on third-party infrastructure, you can use [Brave](https://brave.com) or [Opera](https://opera.com), which both support .eth resolution.
Certain browser extensions such as [MetaMask](https://metamask.io) are also able to resolve .eth names.
In order to access dweb without having to install a new browser or an extension, you can use one of the following ENS gateways:
* [eth.link](https://eth.link) for IPFS, Swarm and Arweave
* [eth.limo](https://eth.limo) for IPFS, Swarm and Arweave
* [eth.sucks](https://eth.sucks) for IPFS
* [bzz.link](https://bzz.link) for Swarm
If a website is hosted on IPFS, it is also possible to access it directly from IPFS gateways.
In order to access a decentralized website through an IPFS gateway, convert dots to dashes and append the `.ipns` namespace (e.g. `ens.eth` becomes `ens-eth.ipns.`).
Below is a list of IPFS gateways that support ENS:
* [inbrowser.link](https://inbrowser.link) - trustlessly verifies content client-side
* [dweb.link](https://dweb.link) - official IPFS subdomain gateway
## Supported TLD List \[Any DNS TLD that supports DNSSEC can be used with ENS]
Alongside the `.eth` Top Level Domain, the ENS Protocol also supports most of your favourite DNS Top Level Domains (such as `.com`, `.cash` or `.domains`).
All DNS TLDs are owned by the [DNS Registrar](/registry/dns) by default, but TLD operators can claim ownership of their TLD in ENS to implement custom logic.
Below is a list of all known custom TLD implementations:
{/* TODO: Generate this at build time */}
| TLD | Registrar |
| ------- | --------------------------------------------------------------------------------------------------------------------- |
| .art | [0x828D6e836e586B53f1da3403FEda923AEd431019](https://etherscan.io/address/0x828D6e836e586B53f1da3403FEda923AEd431019) |
| .box | [0x0b9BB06Ebf35A755998B60353546ae8A055554d2](https://etherscan.io/address/0x0b9BB06Ebf35A755998B60353546ae8A055554d2) |
| .hiphop | [0x04ebA57401184A97C919b0B6b4e8dDE263BCb920](https://etherscan.io/address/0x04ebA57401184A97C919b0B6b4e8dDE263BCb920) |
| .club | [0x1eb4b8506fca65e6B229E346dfBfd349956A66e3](https://etherscan.io/address/0x1eb4b8506fca65e6B229E346dfBfd349956A66e3) |
| .kred | [0x56ca9514363F68d622931dce1566070f86Ce5550](https://etherscan.io/address/0x56ca9514363F68d622931dce1566070f86Ce5550) |
| .luxe | [0xA86ba3b6d83139a49B649C05DBb69E0726DB69cf](https://etherscan.io/address/0xA86ba3b6d83139a49B649C05DBb69E0726DB69cf) |
## ENS DAO Constitution
The ENS constitution is a set of binding rules that determine what governance actions are legitimate for the DAO to take.
Each article has examples of permissible and non permissible actions. These examples are illustrative and should not be considered a binding part of the text of the constitution itself.
### I. Name ownership shall not be infringed
ENS governance will not enact any change that infringes on the rights of ENS users to retain names they own, or unfairly discriminate against name owners' ability to extend, transfer, or otherwise use their names.
#### **Examples**
**Permissible**: ENS governance may enact a change affecting the registration or extension costs of all names based on transparent criteria such as length, as long as it pursues a goal outlined in this constitution.
**Not Permissible**: ENS governance must not enact a change increasing or reducing the extension costs of a list of existing ENS names, as this would unfairly benefit or penalise a handpicked group.
### II. Fees are primarily an incentive mechanism
The primary purpose of registration fees is as an incentive mechanism to prevent the namespace becoming overwhelmed with speculatively registered names. A secondary purpose is to provide enough revenue to the DAO to fund ongoing development and improvement of ENS. ENS governance will not enact any fee other than for these purposes.
#### **Examples**
**Permissible**: ENS governance may increase the price of name registrations in order to address excessive speculative registrations induced by a price that is set too low, or because the current price is insufficient to fund ongoing ENS operations at a reasonable level.
**Not Permissible**: ENS governance must not enact a change imposing a fee for claiming DNS domains inside ENS, because such a fee would be purely an income generating measure and not an incentive mechanism.
### III. Income funds ENS and other public goods
Any income generated to the ENS treasury is to be used first of all to ensure the long-term viability of ENS, and to fund continuing development and improvement of the ENS system. Funds that are not reasonably required to achieve this goal may be used to fund other public goods within web3 as ENS governance sees fit.
ENS governance will not allocate funds to a team or individual who does not commit to uphold the same principles outlined in this constitution in their use of the allocated funds.
#### **Examples**
**Permissible**: ENS governance may offer grant funding for a public good unrelated to ENS or Ethereum, so long as doing so does not affect the long-term viability of ENS.
**Not Permissible**: ENS governance must not use the funds to support projects that conflict with the goals of ENS.
### IV. ENS Integrates with the global namespace
In order to facilitate making the most widely usable naming system, ENS aims to integrate with the legacy DNS naming system to the greatest extent possible without sacrificing decentralization of ENS. ENS governance will not enact changes that compromise ENS's ability to do this.
#### **Examples**
**Permissible**: ENS governance should grant control of a top-level domain to its owner in the DNS system on request.
**Not permissible**: ENS governance must not create new top-level domains unless those domains have been granted to ENS by a DNS authority.
### V. Amendments to this constitution by majority vote
Any change may be made to this constitution only by two-thirds majority and at least 1% of all tokens participating.
## The ENS Foundation
### Why have a legal entity?
Having a legal entity that represents the DAO in the "real world" is valuable for a number of reasons:
* It provides limited liability to DAO participants for the actions of the DAO. Without a legal entity, participants may be individually held liable for anything the DAO as a whole does.
* It is capable of complying with taxation requirements - without a legal entity, DAO participants may be held liable for a proportion of the DAO's income, even if they are not able to access these funds.
* It is capable of entering into contracts with other "real world" entities, of holding assets (including IP rights), and so forth.
For a more detailed discussion of this topic, see [this excellent blog post](https://mirror.xyz/0x954888B7a5C6736F4955dF18B556D8328FD02f61/5K9llACK4tzu5WHL68CM3bBsmSleL_XxJ2kRGYnwp7A).
### What is The ENS Foundation?
The ENS Foundation is a Foundation Company Limited By Guarantee, incorporated in the Cayman Islands. Foundation companies are nonprofits; The ENS Foundation has no shareholders and cannot pay out dividends to its directors or members. For more details on how foundations work, see [this article](https://www.careyolsen.com/briefings/overview-cayman-islands-foundation-companies).
The ENS Foundation has three directors: Nick Johnson, Kevin Gaspar, and Alex Van de Sande. Directors are in charge of the day-to-day running of the foundation.
The ENS Foundation has one supervisor. The supervisor is an administrative role whose job is to make sure that the directors are doing their jobs in accordance with Cayman Islands law. The position of supervisor is filled by a Cayman Islands firm, DS Limited.
The ENS Foundation's Articles of Incorporation give significant powers to the ENS DAO (referred to as "The Council" in the Articles). The DAO may vote to:
* Appoint or remove a director, member, or supervisor.
* Prohibit admitting any members in future.
* Instruct the directors to wind up the foundation, and specify what charity or other foundation should receive the foundation's assets.
Though not specified directly in the Articles, the DAO may also instruct the directors to take action on behalf of the Foundation - such as signing a contract, engaging a company for a service the DAO requires, or delegating some of the directors' powers to a DAO working group.
### Foundation Expenses
Running a Foundation is not free, and comes with some real-world costs. An incomplete list of anticipated expenses includes:
* Registered Office & Secretary Services: $10,000 USD p/a
* Supervisory Services: $30,000 USD p/a
* Agent for service of process: $1,200 USD p/a
* Companies Register Fees: $850 USD p/a
The Directors may ask the DAO for reimbursement of these fees when they are incurred so that the Foundation can continue to operate.
### Documents
For transparency, important documents relating to the Foundation can be found below. Meeting minutes, resolutions, accounts, and other documentation will be uploaded here as it is made available to the directors.
:::note
[M & A - Incorp - The ENS Foundation - 26 October 2021.pdf](https://github.com/ensdomains/governance-docs/blob/main/assets/M%26A%20-%20Incorp%20-%20The%20ENS%20Foundation%20-%2026%20October%202021.pdf)
:::
:::note
[Certificate of Incorporation - The ENS Foundation - 26 October 2021.pdf](https://github.com/ensdomains/governance-docs/blob/main/assets/Certificate%20of%20Incorporation%20-%20The%20ENS%20Foundation%20-%2026%20October%202021.pdf)
:::
:::note
[Dir Res - Stage 2 - The ENS Foundation (27.10.21).pdf](https://github.com/ensdomains/governance-docs/blob/main/assets/Dir%20Res%20-%20Stage%202%20-%20The%20ENS%20Foundation%20\(27.10.21\).pdf)
:::
:::note
[Resignation and appointment of a director.pdf](https://github.com/ensdomains/governance-docs/blob/main/assets/Resignation%20and%20appointment%20of%20a%20director.pdf)
:::
:::note
[Brantly resignation.pdf](https://github.com/ensdomains/governance-docs/blob/main/assets/Brantly%20resignation.pdf)
:::
## Welcome to ENS DAO \[The ENS DAO governs the ENS protocol and treasury]
### Context for ENS
* [**ENS landing page**](https://ens.domains): Where you can register and manage ENS names.
* [**ENS Protocol X account**](https://x.com/ensdomains): The official ENS Twitter account.
* [**ENS DAO X account**](https://x.com/ENS_DAO): The official ENS DAO Twitter account.
* [**Support**](https://support.ens.domains): Where the users can get support from the ENS Labs team.
### Context for Governance
* [**Forum**](https://discuss.ens.domains): For discussion on governance proposals and working group operations.
* [**Snapshot**](https://snapshot.org/#/ens.eth): For offchain proposals.
* [**Agora**](https://agora.ensdao.org): For onchain proposals and token delegation.
* [**Tally**](https://www.tally.xyz/gov/ens): For onchain proposals and token delegation.
* [**DeGov**](https://ens.degov.ai): For onchain proposals and token delegation.
## ENS DAO Security Council
The ENS DAO Security Council is a 4-of-8 multi-sig with a limited mandate: to cancel malicious proposals that threaten the DAO, particularly those that would compromise the treasury. It was created to address vulnerabilities stemming from low voter participation relative to treasury size.
### Purpose and Powers
The security council is expected to act only in emergency, in the given following situations or similar cases:
* If a proposal goes against the [ENS Constitution](/dao/constitution)
* If a proposal is approved with malicious intent against the DAO longevity/sustainability
* If such \[a] proposal is approved by any group of voters, but \[they are] directly financially incentivised to vote against the DAO's interests to preserve their own financial stake
* If any approved proposal goes directly against the DAO for the sole benefit of an attacker
The council cannot propose, amend, or otherwise initiate governance actions.
### Time-Limited Authority
The Security Council's cancel authority is time-limited. Two years after deployment (at unix timestamp `1784919179`), any address may call `renounceTimelockRoleByExpiration()` to permanently disable the cancel role, promoting decentralisation over time.
### Relevant Proposals
The veto was first introduced in [Introducing veto.ensdao.eth](https://discuss.ens.domains/t/introducing-veto-ensdao-eth/19088), and approved via social proposal [EP 5.7](/dao/proposals/5.7). Additional discussion occured in [Enable the cancel role on the DAO](https://discuss.ens.domains/t/temp-check-enable-cancel-role-on-the-dao/19090). Member appointments were confirmed in social proposal [EP 5.10](/dao/proposals/5.10), and the Security Council was formally implemented in Executable [EP 5.13](/dao/proposals/5.13).
### Contract Details
[`SecurityCouncil.sol`](https://github.com/blockful-io/security-council-ens) is deployed to [0xb8fa0ce3f91f41c5292d07475b445c35ddf63ee0](https://etherscan.io/address/0xb8fa0ce3f91f41c5292d07475b445c35ddf63ee0) on Ethereum Mainnet. It is owned by the [4-of-8 multi-sig](https://etherscan.io/address/0xaA5cD05f6B62C3af58AE9c4F3F7A2aCC2Cdc2Cc7) specified in [EP 5.10](/dao/proposals/5.10).
import { Avatar } from '../../components/Avatar'
## ENS DAO Stewards
The DAO is governed through a democratic process in which all major matters are decided through a vote open to all holders of governance tokens. Those who wish can also delegate their voting power, entrusting somebody else to keep tabs on the latest DAO matters.
Delegates can be chosen or switched at any time, often without cost, via [Tally](https://www.tally.xyz/gov/ens), [Agora](https://agora.ensdao.org/) or other apps.
For more day-to-day matters, there are Stewards who are elected for a one-year term. The election happens every year on December 10 and lasts for 5 days. Stewards make decisions on governance, hold public meetings, and decide on grants, sponsorships, and other matters. Stewards are divided into different working groups, each reflecting their specific focus.
Read the [full active rules governing the Working Groups](/dao/wg/rules)
### Stewards for 2025 Term
##### Meta-Governance Working Group
| | | |
| ---------------------------------------- | --------------------------------------- | ------------------------------------------ |
| Spence / 5pence.eth | Alex / netto.eth | Cam / daostrat.eth |
##### ENS Ecosystem Working Group
| | | |
| --------------------------------------- | --------------------------------------- | ---------------------------------------- |
| slobo.eth | limes.eth | Donnie / daemon.eth |
##### Public Goods Working Group
| | | |
| ----------------------------------------- | ---------------------------------------- | ------------------------------------------------- |
| coltron.eth | simona.eth | sovereignsignal.eth |
| | | |
### Past Stewards
#### 2024
##### Meta-Governance Working Group
| | | |
| ---------------------------------------- | -------------------------------------- | ------------------------------------------- |
| Spence / 5pence.eth | Alex / avsa.eth | Marcus / estmcmxci.eth |
##### ENS Ecosystem Working Group
| | | |
| --------------------------------------- | --------------------------------------- | ------------------------------------- |
| slobo.eth | limes.eth | 184.eth |
##### Public Goods Working Group
| | | |
| ----------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| coltron.eth | Simona / simona.eth | vegayp.eth |
#### 2023 Q3/Q4
##### Meta-Governance Working Group
| | | |
| -------------------------------------- | ---------------------------------------- | ------------------------------------------- |
| Nick Johnson / nick.eth | Spence / 5pence.eth | Katherine Wu / katherine.eth |
##### ENS Ecosystem Working Group
| | | |
| --------------------------------------- | --------------------------------------- | ------------------------------------- |
| slobo.eth | limes.eth | 184.eth |
##### Public Goods Working Group
| | | |
| ----------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| coltron.eth | Simona / simona.eth | vegayp.eth |
#### 2023 Q1/Q2
##### Meta-Governance Working Group
| | | |
| -------------------------------------- | ---------------------------------------- | ------------------------------------------- |
| nick.eth | simona.eth | Katherine Wu |
##### ENS Ecosystem Working Group
| | | |
| --------------------------------------- | --------------------------------------- | --------------------------------------- |
| slobo.eth | limes.eth | yambo.eth |
##### Public Goods Working Group
| | | |
| -------------------------------------- | ----------------------------------------- | ---------------------------------------- |
| avsa.eth | coltron.eth | vegayp.eth |
#### 2022 Q3/Q4
##### Meta-Governance
| | | |
| ----------------------------------------- | ---------------------------------------- | -------------------------------------- |
| coltron.eth | simona.eth | nick.eth |
##### ENS Ecosystem
| | | |
| ------------------------------------------ | ------------------------------------------- | --------------------------------------- |
| bobjiang.eth | validator.eth | slobo.eth |
##### Community
| | | |
| --------------------------------------- | ----------------------------------------- | ------------------------------------------- |
| limes.eth | coltron.eth | validator.eth |
##### Public Goods
| | | |
| --------------------------------------------- | ---------------------------------------------- | -------------------------------------- |
| anthonyware.eth | ceresstation.eth | avsa.eth |
#### 2022 Q1/Q2
##### Meta-Governance
| | | |
| -------------------------------------- | --------------------------------------------- | --------------------------------------- |
| jmj.eth | simona.eth | james.eth |
| | | |
| nick.eth | leontalbert.eth | |
##### ENS Ecosystem
| | | |
| --------------------------------------- | ----------------------------------------- | ------------------------------------------ |
| ginge.eth | slobo.eth | bobjiang.eth |
| | | |
| nick.eth | jefflau.eth | |
##### Community
| | | |
| ----------------------------------------- | ------------------------------------------- | -------------------------------------------- |
| limes.eth | coltron.eth | spencecoin.eth |
| | | |
| brantly.eth | validator.eth | |
##### Public Goods
| | | |
| ----------------------------------------- | ---------------------------------------------- | -------------------------------------- |
| sumedha.eth | ceresstation.eth | avsa.eth |
| | | |
| matoken.eth | ricmoo.eth | |
## The ENS Token
:::info
ENS Airdropped tokens to anyone who held an ENS name on *October 31st, 2021*.
**THERE ARE NO PLANS FOR ANOTHER AIRDROP**. Please be weary of any notices of
airdrops as these could turn out fraudulent.
:::
All major decisions of the ENS DAO governance rely on the ENS Governance Token, which was distributted to ENS owners in 2021. The token can be found at [token.ensdao.eth](https://etherscan.io/address/token.ensdao.eth) on Ethereum Mainnet and is the only official governance token for ENS DAO.
The $ENS token allocation can be seen in the pie chart below.

### Can I recover tokens accidentally sent to the wrong address?
The answer depends on the address the token was sent to.
* If you accidentally sent the token to [token.ensdao.eth](https://etherscan.io/address/token.ensdao.eth) or [wallet.ensdao.eth](https://etherscan.io/address/wallet.ensdao.eth), then it might be recoverable. Contact the [Meta-governance working group](/dao/stewards/) and explain the situation.
* If the tokens were sent to the null address (0x000...0000) or an address with a typo, then the tokens are unrecoverable and there's nothing that anyone can do.
* If the tokens were sent to an exchange or a third party, then contact that third party for help.
## ENS DAO Working Group Rules
*This document represents the current state of the Working Group Rules as created by [EP0.4](https://snapshot.box/#/s\:ens.eth/proposal/0x899ead1d9b9b98f63f6a60dc0939bef55dbe365e78c6a550f07be969a47f148b), and amended by [EP1.8](https://snapshot.box/#/s\:ens.eth/proposal/0xc7186cf8bebe47600f8d847e76f7971ea97b48bc04eda1e07780aff91fb6410d) and [EP4.8](https://snapshot.box/#/s\:ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266). These should represent the canonical version of the rules and any social proposal to amend it should include a PR to this document.*
:::note
The numbering system of EP's was changed after Working Group rules were established, which is why the above proposals have different numbers than Snapshot displays.
:::
### 1. Formation of Working Groups
1. To create a new working group, a social proposal, as defined by the ENS governance documentation ('Social Proposal'), must be put forward and passed by the DAO.
2. A Social Proposal to create a new working group must demonstrate that the new working group is needed and the work cannot be undertaken within an existing working group.
### 2. Dissolution of Working Groups
1. A working group can be dissolved by passing a Social Proposal requesting the dissolution of a working group or working groups.
2. If an active proposal is put forward to dissolve a working group, all working group funds, including outgoing payments, within that working group, are to be frozen with immediate effect, pending the outcome of that vote.
3. Upon the dissolution of a working group, any and all unspent working group funds from that working group, at the time of dissolution, must be immediately returned to the DAO treasury, without delay.
### 3. Working Group Stewards
1. Each working group shall be managed by three stewards (hereafter a 'Steward' or 'Stewards').
2. Stewards will be elected to serve within working groups for a set period of one calendar year (hereafter known as a 'Term').
3. The Term for Stewards commences at 9am UTC on January 1 each year and ends immediately prior to the commencement of the Term of the following year.
4. Stewards are responsible for overseeing the operation of working groups in accordance with these rules and the ENS DAO constitution.
5. The responsibilities of Stewards include, but are not limited to:
1. Requesting working group funds from the DAO in accordance with these rules;
2. Approving the creation of sub-groups or workstreams within a working group to undertake work and/or carry out specific projects or tasks;
3. Dissolving sub-groups or workstreams within a working group;
4. Using discretion to make working group funds available to sub-groups, workstreams, or contributors within a working group;
5. Using discretion to disburse working group funds to people and/or projects in accordance with the ENS DAO constitution; and
6. Acting as keyholders of working group multi-sigs.
### 4. Steward Eligibility and Nominations
1. Any individual is eligible to nominate themselves to be a Steward of a working group within the DAO ('Eligible Person').
2. To be eligible for the election for the annual Term, Eligible Persons must nominate themselves between 9am UTC on December 6 and 9am UTC on December 9 ('Nomination Window').
3. An Eligible Person may nominate themselves to become a Steward of a working group during the Nomination Window, by meeting the requirements set out in a call for nominations posted in the relevant working group category of the ENS governance forum.
4. An Eligible Person who completes the steps outlined in rule 4.3 above during the Nomination Window and receives 10,000 signed votes to support their nomination will be included in the ballot as a nominee in the election for Stewards that takes place following that Nomination Window ('Nominee').
### 5. Steward Elections
1. Elections for working group Stewards for the upcoming year will take place by a vote of governance token holders using signed messages and will be open for 120 hours, commencing at 9am UTC on December 10 each year ('Election Window').
2. The top-ranked Nominees from the working group vote held during the Election Window will fill any available positions for the role of Steward for those working groups for the upcoming Term, based on the order in which they are ranked in the vote.
3. A Nominee elected to serve as a Steward may not take up the role of Steward for more than two working groups during their Term.
### 6. Delay of Nominations or Elections
1. In the event that nominations or elections for Stewards take place after a Nomination Window or after an Election Window, the nomination process and/or elections shall take place, as otherwise prescribed in rules 4 and 5 above, as soon as is practicable after the missed Nomination Window or missed Election Window.
2. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, outgoing Stewards from the previous Term shall stay in their positions as working group Stewards until immediately prior to 9am UTC the day following the end of the election, which, for the avoidance of doubt, is 120 hours after voting in those elections commenced.
3. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, newly elected Stewards will assume the responsibilities of stewardship within working groups at 9am UTC the day following the end of the election, as defined in rule 6.2 above, for the remainder of that Term.
### 7. Removal and Replacement of Stewards
1. Stewards may be removed at any time by:
1. a Social Proposal passed by the DAO; or
2. a simple indicative majority vote among Stewards of all working groups, with the outcome of that vote communicated in the relevant working group category of the ENS governance forum.
2. Stewards may step down from their position at any time by communicating their intention to step down in the ENS governance forum.
3. In the event that a Steward is removed, steps down, or is unable to continue as a Steward, for whatever reason, prior to the end of a Term, a new election must be held to fill any vacant Steward positions, in accordance with rule 6 above.
### 8. Lead Stewards
1. Each working group must appoint a lead Steward within the first five days of a Term (hereafter a 'Lead Steward' or 'Lead Stewards').
2. Only current elected Stewards of a working group are eligible to serve as Lead Stewards within a given working group.
3. Lead Stewards may be appointed or removed from that role at any time by a simple indicative majority vote among the Stewards of a working group, with the outcome of that vote communicated in the relevant working group category of the ENS governance forum.
4. In the event that a Lead Steward steps down from the position or is removed as a Lead Steward before the end of a Term in accordance with rule 8.3 above, a new Lead Steward must be appointed within five calendar days.
5. A Steward who is appointed to serve as a Lead Steward of a working group will remain in that position, as Lead Steward, from the date of appointment until the end of their elected Term as a Steward or until they are removed as a Lead Steward in accordance with rule 8.3 above or until they are removed as a Steward in accordance with rule 7 above.
6. Lead Stewards are responsible for the operational management and administration of working groups and are expected to provide regular updates to the DAO in the ENS governance forum related to working group progress, achievements, and challenges.
7. The responsibilities of Lead Stewards include, but are not limited to:
1. Acting as a representative of a working group;
2. Managing resource requests from sub-groups, workstreams, and contributors within a working group;
3. Initiating the disbursement of working group funds on an as-needed basis;
4. Providing reports of working group spending in the ENS governance forum; and
5. Maintaining open communications with DAO participants in the ENS governance forum.
### 9. DAO Secretary
1. At the start of each Term, the current Stewards of each working group shall collaborate to appoint an individual who will serve as the secretary of the DAO (hereafter 'Secretary' or 'Secretaries').
2. The Secretary may be appointed or removed from that role at any time by a majority vote of all elected Stewards in a given Term with the outcome of that vote communicated in the ENS governance forum.
3. The Secretary will remain in that position, as Secretary of the DAO, from the date of appointment until the end of a given Term or until the date at which they are removed from that position in accordance with rule 9.2 above.
4. Secretaries are eligible to receive fair compensation for their work as Secretary of the DAO.
5. Compensation for the Secretary of the DAO is to be paid by the Meta-Governance Working Group using funds requested in accordance with rule 10 below.
6. Any individual is eligible to be appointed as the Secretary of the DAO, including past and present working group Stewards.
7. The Secretary is responsible for managing working relationships and communications across working groups as well as performing administrative duties for the DAO.
8. The responsibilities of the Secretary include, but are not limited to:
1. Managing a DAO-wide calendar;
2. Coordinating and attending working group meetings where possible and ensuring meeting summaries are posted in the ENS governance forum;
3. Assisting Stewards with coordination challenges within working groups; and
4. Acting as a multi-sig keyholder for each working group.
### 10. Working Group Funds
1. To request working group funds, Stewards of all working groups will collaborate to submit an active executable proposal, as defined by the ENS governance documentation ('Collective Proposal'), to the DAO during the months of January, April, July, and October each calendar year (each a 'Funding Window').
1. In order for a working group to have a funding request included in a Collective Proposal submitted to the DAO during a Funding Window, the funding request must have passed as a Social Proposal in the same Funding Window.
2. In the case of an emergency, where working group funds are needed by a working group outside of a Funding Window, an executable proposal, as defined by the ENS governance documentation, may be submitted at any time by a Steward of a working group to request funds from the DAO.
2. Working group funds requested and approved in accordance with rule 10.1 above are to be paid out into separate working group multi-sigs controlled by the DAO.
3. Each working group multi-sig must have four keyholders, made up of three current elected Stewards for that working group and the Secretary of the DAO for that Term, with no other keyholders permitted.
4. Working group funds may be disbursed from working group multi-sigs with three-of-four keyholder signing.
5. Stewards of a given working group shall have the discretion to reallocate funds approved in a Collective Proposal where appropriate and where it is not in conflict with any rules of the DAO, DAO bylaws, or the ENS DAO constitution.
### 11. Compensation for Stewards and Lead Stewards
1. Stewards are eligible to receive fair compensation for their work as a Steward or Lead Steward in the DAO.
2. All requests for Steward or Lead Steward compensation must be detailed in a Collective Proposal for working group funds submitted to the DAO in accordance with rule 10.1 above.
3. Stewards may not receive compensation for their role as a Steward or Lead Steward outside of that compensation expressly provided for in a Collective Proposal submitted to the DAO in accordance with rule 10.1 above.
4. The Meta-Governance working group are responsible for defining standards for fair compensation ('Compensation Guidelines').
5. The Compensation Guidelines shall be defined prior to the Nomination Window for each term and can only take effect for the following term.
### 12. Amendments
1. These rules may be amended at any time by passing a Social Proposal.
## \[6.8] \[Executable] Revoke root controller role from legacy ENS multisig
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-6-8-executable-revoke-root-controller-role-from-legacy-ens-multisig/20644) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/83558494563463316177076768398348085020294312678713085260352382286714788322618) |
### Abstract
We have identified that the legacy ENS multisig, which originally controlled ENS before the DAO was created, still has the 'controller' role on the ENS root. This means that a majority of multisig keyholders could create or replace any ENS TLD other than .eth. .eth is locked and cannot be modified by the DAO or anyone else.
In order to correct this oversight, this proposal revokes the legacy multisig's controller role from the root contract.
### Specification
Call `setController` on the ENS `Root` contract at `0xaB528d626EC275E3faD363fF1393A41F581c5897`, passing in the address of the legacy multisig, `0xCF60916b6CB4753f58533808fA610FcbD4098Ec0`.
### Transactions
Address
Value
Function
Argument
Value
0xaB528d626EC275E3faD363fF1393A41F581c5897
0
setController
address
0xCF60916b6CB4753f58533808fA610FcbD4098Ec0
controller
false
## \[EP0.1] \[Social] Proposal: Transfer ENS Treasury and Contract Ownership
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/6307) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0xfe73d1b06675d6bc1cc074f440c347274d13c55b513ea02ec950efe639adbbb0) |
*Note: This was previously numbered EP1.*
### Summary
Transfer ENS treasury and contract ownership from the ENS Multisig to ENS DAO.
### Abstract
With the recent launch of the ENS DAO and $ENS token, it is now time for key governance powers of ENS to be transferred from the ENS root multisig to the ENS DAO.
🔥\_🔥 ([Fire Eyes DAO](https://fireeyes.xyz)) has taken a [central role in the planning and execution](https://mirror.xyz/james.eth/XkOIGh8xu_bF2cQV4QZkKxoN0o1OuNoEb3o-Nzjdo3I) of ENS's decentralization journey and is excited to present this first proposal to the community.
This proposal will take a different form than normal as it proposes making a request to the ENS multisig root keyholders, rather than executing an action on the DAO.
**This proposal looks to execute a transfer of ownership of several aspects of the protocol which are currently controlled by the ENS root multisig:**
1. We propose that control over the existing ENS treasury is transferred to the DAO.
2. We propose that ownership of the ENS Registrar Controller and the pricing oracle is transferred to the DAO.
Ownership of the price oracle gives the DAO the ability to:
1. Set the contract used to get the USD-ETH price.\*
2. Change the price per year of each length of domain name.
Ownership of the registrar controller gives the DAO the ability to:
1. Replace the price oracle contract.
2. Withdraw accumulated funds to the DAO treasury.
3. Set the minimum and maximum period between the first and second transactions of the registration process.
3. We propose that ownership of the ENS Registrar is transferred to the DAO. Ownership of the .eth registrar gives the DAO the ability to:
1. Add and remove controller contracts.
2. Set the resolver contract for .eth
4. We propose that ownership of the 'reverse' namespace, which governs assignment of primary ENS records, be transferred to the DAO. Ownership of the .reverse TLD gives the DAO the ability to:
1. Replace the reverse registrar for Ethereum addresses.
2. Create new types of reverse resolution (For example, bitcoin addresses) and update them.
Importantly, control over the ENS root will remain with the ENS root multisig for now. Control over the root allows for the creation and replacement of ENS top-level domains (TLDs) other than .eth (.eth is locked and cannot be changed by the root). This proposal also does not transfer ownership of the DNSSEC registrar contract, necessary for administering the DNSSEC integration used to allow owners of DNS domains to claim them on ENS.
Powers over the ENS root are not being requested immediately, as they are both powers that can be abused to revoke or reassign non-.eth ENS names, and as such the risk to name owners is significantly higher than the other powers the DAO will exercise. Once the DAO has demonstrated its ability to successfully govern ENS, a future proposal will transfer these powers to the DAO.
Snapshot voting on the above proposals will be conducted individually via approval voting; any proposal above that gets at least 50% approval and a quorum of 1% becomes the official policy of the DAO.
### Specification
The ENS DAO formally petitions the ENS root keyholders (being the owners of the multisig located at multisig.ens.eth) to execute a transaction or transactions taking the following actions:
1. If proposal 1 passes, transfer all ETH and USDC held by multisig.ens.eth to the DAO's timelock contract at wallet.ensdao.eth.
2. If proposal 2 passes, call `transferOwnership` on the contracts at controller.ens.eth and 0xb9d374d0fe3d8341155663fae31b7beae0ae233a (the price oracle), passing in the address of wallet.ensdao.eth.
3. If proposal 3 passes, call `transferOwnership` on the contract at registrar.ens.eth, passing in the address of wallet.ensdao.eth.
4. If proposal 4 passes, call `setSubnodeOwner` on the root, passing in `keccak256('reverse')` and the address of wallet.ensdao.eth.
The ENS DAO agrees to use these funds and powers in accordance with the ENS Constitution.
### Conclusion & Next Steps
This proposal looks to set precedent as the first action taken by ENS delegates & token holders. Upon successful execution, the ENS DAO will hold control over two significant aspects of the protocol, and will be able to dispense funds effectively towards community initiatives.
* Discuss this proposal on the ENS forum and discord.
* Implement a vote on this proposal on Snapshot.
* If passed:
* Transfer existing assets from the ENS Community multisig to the ENS DAO.
* Transfer control over the Registrar Controller to the ENS DAO.
This vote is being conducted via approval voting; select each option you wish to see pass. Those options that have at least 50% support and 1% quorum when voting ends will pass
## \[EP0.2] \[Executable] Retrospective airdrop for accounts that owned another account's primary ENS name
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/6755) |
| **Social Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0xcf77c74696cab1d939936ae8684c0007297bed641f60896ad186354f036d725f) |
| **Onchain Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/90476529665364161211265365238121921179703522228680648046371476645353679539653) |
*Note: This was previously numbered EP2.*
### Summary
Send 213,049 ENS tokens to a new airdrop contract for users who did not receive the 2x multiplier despite owning a name that was used as a primary ENS name.
### Abstract
One of the criteria used for the ENS airdrop was whether the account had a primary ENS name set. Those accounts that did got a 2x multiplier on their airdrop amount. The intention was to use this as a measure of involvement in the ENS ecosystem; those accounts that set primary ENS names are typically using their names in supported applications, while those that don't are less likely to be doing so.
The way this was implemented was to award the multiplier to all accounts that had interacted with the reverse registrar. This had the unintended side effect that if a user owned an ENS name on account A, and configured it to resolve to account B, which used it as its primary name, account A would get tokens, and account B would get the multiplier. As B doesn't own any names, the multiplier has no effect and the end result is that some users got fewer tokens than they would have if they had used the same account for everything.
This proposal aims to correct this, by introducing a new criteria for determining who to award the multiplier to, and creating a new airdrop contract for all accounts that qualify for the new criteria but not the old one.
In plain english terms, the new criteria is that the account must have at some point in time owned a name that was used as the primary ENS name for an account.
More formally, for each account `a`, the account is assigned the multiplier if there exists a name `n` and a time before 2021-11-01 00:00:00 UTC, where all of the following are true:
1. `a` is the registrant of `n`.
2. `n` has a resolver, `r`, set on the ENS registry.
3. `r` has an `addr` record, `a'`, set for `n`, and has emitted an `AddrChanged` event to record this fact.
4. The reverse record for `a'` has a resolver, `r'`, set on the ENS registry.
5. `r'` has a `name` record, `n'`, set for the reverse record of `a`. `r'` is either the default reverse resolver, or has emitted a `NameChanged` event for `n'` and `a'`.
6. `n == n'`.
This logic is implemented by [this series of BigQuery queries](https://gist.github.com/Arachnid/667178e854945abaecb6dfd3b6c0c279/106d9bc156988cf96786c71f6448f13fb11599fc), and shows that 1,969 accounts meet these criteria but did not qualify for the multiplier under the original criteria. The sum of the tokens these accounts would be entitled to comes to \~213,049 ENS tokens. A list of affected accounts and balances is [here](https://gist.github.com/Arachnid/e8b1a18fc19818fb00f51fbb8d90e429).
Further, a number of users have accidentally transferred their ENS tokens to the token contract, totalling 6,246 contracts across 49 transfers. These tokens should be returned to their previous owners. This proposal, if executed, will transfer 219,295 ENS tokens to [a new merkle airdrop contract ](https://github.com/ensdomains/governance/pull/9)allowing affected users to claim them.
### Specification
1. Request that True Names Limited write and deploy a contract that allows claiming of tokens via Merkle Proofs using the same methodology as was used for the airdrop.
2. Request that True Names Limited make changes to the claim.ens.domains site to support claiming this additional airdrop for qualifying accounts.
3. Authorise the contract deployed in (1) to spend 219295650978169915391391 base ENS tokens from the ENS DAO account.
### Code
```javascript
const ethers = require('ethers')
const abi = [
'function approve(address _spender, uint256 _value) public returns (bool success)',
]
const token = new ethers.Contract(
'0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',
abi
)
const airdropAddress = 'TBD'
const tx = await token.populateTransaction.approve(
airdropAddress,
'213049736662531485206636'
)
console.log([token.address])
console.log([0])
console.log([tx.data])
```
## \[EP0.3] \[Social] Amend airdrop proposal to include accidentally returned funds
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/6975) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x9ab53c76cee40d58cb27b244dfa5f9f2763bd8b97b1b4be1dd0f0bf706818fb4) |
*Note: This was previously numbered EP3.*
### Summary
Amend EP2 to include funds accidentally sent back to the $ENS token contract.
### Abstract
A number of users have [accidentally sent](https://discuss.ens.domains/t/proposal-to-correct-ens-transfer-errors-back-to-contract/5989) $ENS tokens back to the token contract. As of December 6, this amounted to some 6,246 tokens in 49 separate transactions.
These funds are held in the same account as is used for new airdrop claims, and on May 4, 2022 when the airdrop expires, the DAO will be able to claim them back to its own account.
[EP2](https://discuss.ens.domains/t/executable-retrospective-airdrop-for-accounts-that-owned-another-accounts-primary-ens-name/6755) sends approximately 200k tokens to users who owned ENS names that were used as primary names but did not already benefit from the 2x multiplier.
This proposal suggests that [EP2](https://discuss.ens.domains/t/executable-retrospective-airdrop-for-accounts-that-owned-another-accounts-primary-ens-name/6755) be amended to include returning the mistakenly sent funds as part of the same airdrop. This minimises overhead, as the DAO will not incur transaction fees or have to set a separate system up, and enables users to get their mistakenly sent funds back promptly.
### Specification
Amend [EP2](https://discuss.ens.domains/t/executable-retrospective-airdrop-for-accounts-that-owned-another-accounts-primary-ens-name/6755) as follows:
> `-This logic is implemented by [this series of BigQuery queries](https://gist.github.com/Arachnid/667178e854945abaecb6dfd3b6c0c279/1182eea3145394181affe4bb799d6b7858f9eb58), and shows that 1,969 accounts meet these criteria but did not qualify for the multiplier under the original criteria. The sum of the tokens these accounts would be entitled to comes to ~213,049 ENS tokens.`
>
> `+This logic is implemented by [this series of BigQuery queries](https://gist.github.com/Arachnid/667178e854945abaecb6dfd3b6c0c279/106d9bc156988cf96786c71f6448f13fb11599fc), and shows that 1,969 accounts meet these criteria but did not qualify for the multiplier under the original criteria. The sum of the tokens these accounts would be entitled to comes to ~213,049 ENS tokens.`
> `-A list of affected accounts and balances is [here](https://gist.github.com/Arachnid/d6495f57ac6a5b17cf28e01b646e99a8).`
>
> `+A list of affected accounts and balances is [here](https://gist.github.com/Arachnid/e8b1a18fc19818fb00f51fbb8d90e429).`
> `-This proposal, if executed, will transfer 213,049 ENS tokens to [a new merkle airdrop contract ](https://github.com/ensdomains/governance/pull/9) allowing affected users to claim them.`
>
> `+Further, a number of users have accidentally transferred their ENS tokens to the token contract, totalling 6,246 contracts across 49 transfers. These tokens should be returned to their previous owners.`
>
> `+This proposal, if executed, will transfer 219,295 ENS tokens to [a new merkle airdrop contract ](https://github.com/ensdomains/governance/pull/9) allowing affected users to claim them.`
> `-3. Authorise the contract deployed in (1) to spend 213049736662531485206636 base ENS tokens from the ENS DAO account.`
>
> `+3. Authorise the contract deployed in (1) to spend 219295650978169915391391 base ENS tokens from the ENS DAO account.`
> `-const tx = await token.populateTransaction.approve(airdropAddress, '213049736662531485206636');`
>
> `+const tx = await token.populateTransaction.approve(airdropAddress, '219295650978169915391391');`
## \[EP0.4] \[Social] Proposal: Creation of Foundational Working Groups and Working Group Rules
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/8156) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x899ead1d9b9b98f63f6a60dc0939bef55dbe365e78c6a550f07be969a47f148b) |
*Note: This was previously numbered EP4.*
### Summary
Create four foundational working groups and establish rules related to the creation, management, and dissolution of working groups within the ENS DAO.
### Abstract
The work-related activities of the ENS DAO will take place within working groups. Each working group will have a specific focus area and mission, aligned with the constitution and needs of the DAO.
This proposal establishes four foundational working groups:
1. Meta-Governance: providing governance oversight and support of the management and operation of the ENS DAO and working groups;
2. ENS Ecosystem: continuing development and improvement of the ENS protocol and ecosystem, with a focus on all technical matters related to ENS;
3. Community: supporting the people and organizations that are users of ENS, with a focus on non-technical matters; and
4. Public Goods: amplifying ENS as a public good and funding public goods within the ENS ecosystem, and more broadly within web3.
This proposal also sets out rules related to the creation and dissolution of working groups and outlines how working groups will be managed within the DAO.
### Motivation
Establishing working groups to manage DAO-related work will allow decisions to be made, and action to be taken, without the need for every initiative or decision of the DAO to be passed as a proposal.
The creation of working groups will streamline the management of the DAO into core areas that will persist, irrespective of changes in activities or contributors. A working group system will promote stability and encourage long-term thinking and planning.
The working group structure will provide new and existing community members clear onboarding pathways for meaningful participation and engagement in the DAO.
### Specification
Create four foundational working groups and establish rules related to the creation, management, and dissolution of working groups within the ENS DAO (‘**DAO**’).
1. **Working Groups**
1. Four foundational working groups will be established within the DAO:
1. Meta-Governance Working Group;
2. ENS Ecosystem Working Group;
3. Community Working Group; and
4. Public Goods Working Group.
2. **Formation of Working Groups**
1. To create a new working group, a social proposal, as defined by the [ENS governance documentation](https://docs.ens.domains/v/governance/process#types-of-proposal) (‘**Social Proposal**’), must be put forward and passed by the DAO.
2. A Social Proposal to create a new working group must demonstrate that the new working group is needed and the work cannot be undertaken within an existing working group.
3. **Dissolution of Working Groups**
1. A working group can be dissolved by passing a Social Proposal requesting the dissolution of a working group or working groups.
2. If an active proposal is put forward to dissolve a working group, all working group funds, including outgoing payments, within that working group, are to be frozen with immediate effect, pending the outcome of the vote.
3. Upon the dissolution of a working group, any and all unspent working group funds from that working group, at the time of dissolution, must be immediately returned to the DAO treasury, without delay.
4. **Working Group Stewards**
1. Each working group shall be managed by five stewards (hereafter a '**Steward**' or '**Stewards**').
2. Stewards will be elected, unless otherwise stated in these rules, to serve within working groups for a set period of time (hereafter known as a '**Term**' or '**Terms**').
3. There are two Terms each calendar year:
1. The first Term commences at 9am UTC on January 1 each year and ends immediately prior to the commencement of the second Term ('**First Term**'); and
2. The second Term commences at 9am UTC on July 1 each year and ends immediately prior to the commencement of the First Term of the following year ('**Second Term**').
4. Stewards are responsible for managing the operations of each working group.
5. The responsibilities of Stewards include, but are not limited to:
1. Managing operational tasks related to the administration of a working group;
2. Maintaining a description that sets forth the focus and intent of the working group;
3. Developing working group goals for the Term and providing a clear road map for achieving those goals, to be published in the ENS governance forum within the first 30 days of a Term;
4. Approving the creation and dissolution of sub-groups or workstreams within a working group to undertake work and/or carry out specific projects or tasks;
5. Requesting working group funds from the DAO; and
6. Approving and making funding available to sub-groups, workstreams, or contributors within a working group.
6. To request working group funds, Stewards of all working groups will collaborate to submit an active executable proposal, as defined by the [ENS governance documentation](https://docs.ens.domains/v/governance/process#types-of-proposal) ('**Collective Proposal**'), to the DAO within the final 15 days (inclusive) of the months of January, March, July, and October each calendar year (each a '**Funding Window**').
1. In order for a working group to have a funding request included in a Collective Proposal submitted to the DAO during a Funding Window, the funding request must have passed as a Social Proposal in the same Funding Window.
2. In the case of an emergency, where working group funds are needed by a working group outside of a Funding Window, an Executable Proposal may be submitted at any time by a Steward of a working group to request funds from the DAO.
5. **Steward Eligibility and Nominations**
1. Any individual is eligible to nominate themselves to be a Steward of a working group within the DAO ('**Eligible Person**' or '**Eligible Persons**').
2. To be eligible to be included in the ballot for First Term elections of a given year, Eligible Persons must nominate themselves between 9am UTC on December 6 and 9am UTC on December 9 ('**First Term Nomination Window**').
3. To be eligible to be included in the ballot for Second Term elections of a given year, Eligible Persons must nominate themselves between 9am UTC on June 6 and 9am UTC on June 9 ('**Second Term Nomination Window**').
4. An Eligible Person may nominate themselves to become a Steward of a working group or working groups during the First Term Nomination Window or the Second Term Nomination Window (each a '**Nomination Window**'), by meeting the requirements set out in a call for nominations posted in the relevant working group category of the ENS governance forum.
5. An Eligible Person who completes the steps outlined in rule 5.4 above during a Nomination Window and receives 10,000 signed votes to support their nomination will be included in the ballot as a nominee in the election for Stewards that takes place following that Nomination Window ('**Nominee**').
6. **Steward Elections**
1. Elections for working group Stewards for the First Term of a given year will take place by a ranked-choice vote of governance token holders using signed messages and will be open for 120 hours, commencing at 9am UTC on December 10 each year ('**First Term Election Window**').
2. Elections for working group Stewards for the Second Term of a given year will take place by a ranked-choice vote of governance token holders using signed messages and will be open for 120 hours, commencing at 9am UTC on June 10 each year (**'Second Term Election Window**').
3. The top-ranked Nominees from each working group vote held during a First Term Election Window or a Second Term Election Window (each an '**Election Window**'), will fill any available positions for the role of Steward for those working groups for the Term immediately following an Election Window, based on the order in which they are ranked in each working group vote.
4. A Nominee elected to serve as a Steward may not take up the role of Steward for more than two working groups during a single Term.
7. **Delay of Nominations or Elections**
1. In the event that nominations or elections for Stewards take place after a Nomination Window or after an Election Window, the nomination process or elections shall take place, as otherwise prescribed in rules 5 and 6 above, as soon as is practicable after the missed Nomination Window or missed Election Window.
2. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, outgoing Stewards from the previous Term shall stay in their positions as working group Stewards until immediately prior to 9am UTC the day following the end of the election, which, for the avoidance of doubt, is 120 hours after voting in those elections commenced.
3. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, newly elected Stewards will assume the responsibilities of stewardship within working groups at 9am UTC the day following the end of the election, as defined in rule 7.2 above, for the remainder of that Term.
8. **Core Team Stewards**
1. For the First Term, commencing January 1 2022 at 9am UTC, each working group will include two Stewards who are core team members of True Names Limited (Singapore) ('**TNL**'), as selected by TNL and not subject to the Steward nomination and election process outlined in rules 5 and 6 above.
2. For the Second Term, commencing July 1 2022 at 9am UTC, each working group will include one Steward who is a core team member of TNL, as selected by TNL and not subject to the Steward nomination and election process outlined in rules 5 and 6 above.
3. For the First Term of the following year, commencing January 1 2023, and for all Terms thereafter, all Stewards must be elected and appointed in accordance with the rules set out in rules 5 and 6 above.
9. **Removal and Replacement of Stewards**
1. Stewards may be removed at any time by:
1. a Social Proposal passed by the DAO; or
2. a simple indicative majority vote among the Stewards of a given working group, with the outcome of the vote communicated in the relevant working group category of the ENS governance forum.
2. Stewards may step down from their position at any time by communicating their intention to step down in the ENS governance forum.
3. In the event that a Steward is removed, steps down, or is unable to continue as a Steward, for whatever reason, prior to the end of a Term, any vacant positions will be filled for the remainder of a Term by the next highest ranked Nominee(s) in a given working group from the most recent working group vote in the most recent election for Stewards.
4. In the event that a Steward steps down or is removed prior to the end of a Term and is a member of the core team of TNL in accordance with rule 8.1 or 8.2 above, the vacant position(s) will be filled by a core team member or team members of TNL, as selected by TNL.
5. Any Steward selected by TNL in accordance with rule 8.1 or 8.2 above, can be removed by TNL at any time prior to the end of a Term, for any reason, and replaced by another core team member for the remainder of that Term.
10. **Compensation for Stewards**
1. Elected Stewards are eligible to receive fair compensation for their work as a Steward.
2. All requests for Steward compensation must be detailed in a Collective Proposal for working group funds submitted to the DAO in accordance with rule 4.6.
3. Stewards may not receive compensation for their role as a Steward outside of that compensation expressly provided for in a Collective Proposal submitted to the DAO in accordance with rule 10.2.
4. Stewards selected by TNL are not eligible to receive compensation from the DAO or working groups for their work as a Steward.
11. **Amendments**
1. These rules may be amended at any time by passing a Social Proposal.
### Next Steps
This proposal will be open for voting on Snapshot for five days. This vote will be a single choice vote. You may vote 'for' or 'against' the proposal, or choose to abstain from the vote.
By voting 'for' this proposal, you are voting in favor of creating four foundational working groups and establishing rules related to the creation, management, and dissolution of working groups within the ENS DAO, as provided in this proposal.
Given the time of year, Steward nominations and elections for the First Term of 2022 will be delayed until the beginning of 2022.
The Nomination Window for the First Term of 2022 will be open between 9am UTC on January 5, 2022 and 9am UTC on January 8, 2022. Any individual is eligible to nominate themselves to be a Steward of a working group or working groups during this Nomination Window. All Eligible Persons who satisfy the requirements set out in rule 5.4 and 5.5 will be included on the ballot for the First Term elections. More details about the nomination process will be available in the call for nominations released prior to the Nomination Window opening.
The Election Window for the First Term of 2022 will be open for 120 hours, commencing at 9am UTC on January 10 2022. Following the election, in accordance with rule 7.3, newly elected Stewards will assume the responsibilities of stewardship within working groups at 9am UTC on January 16, 2022, for the remainder of the First Term.
To stay up to date on developments regarding working groups, please follow the DAO-Bulletin channel in the ENS Discord Server and follow [@ens\_dao](https://twitter.com/ens_dao) on Twitter.
## \[EP1.1] \[Executable] Set the temporary premium start price to $100,000
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/9336) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/65967822514040846992464797266243157509206510058326665394616765053720727454968) |
*Note: This was previously numbered EP5.*
### Summary
Increases the start price for the temporary premium added when names expire from $2,000 to $100,000.
### Abstract
When a name expires, it goes through a 90 day grace period, after which it becomes available for general registration. To prevent it becoming a race to register, a 'temporary premium' is attached, starting at $2000 and diminishing to 0 over 28 days. Done properly this results in a dutch auction for the name.
When the premium was set, $2000 was roughly the 98th percentile of all auction prices for the short name auction, and seemed like a reasonable starting price. Today, we're seeing multiple reports of names, particularly 3 character names, being snapped up by bots the moment they become available at the maximum premium.
Long-term we can improve the mechanism by setting the initial premium based on the base price of the name (so 3 letter names start off more expensive than 5+ letter names), and by introducing a nonlinear pricing curve (for example, having the price diminish by 1% per hour for 28 days). In the short term, however, I'd like to propose setting the initial premium to a much higher value, which we can do with a simple transaction from the DAO account.
Research of current trends shows:
* 2,798 names have been bought during the temporary premium period so far.
* Of these, 340 (12%) were purchased the moment they became available.
* Registrations of names during the temporary premium period have been on the increase since the DAO launched in November.
* 12 names have been purchased at a premium and flipped on OpenSea; the most valuable of these, punk.eth, went for $85,636.
Accordingly, I propose increasing the temporary premium from its current value of $2,000 to a new value of $100,000. This will ensure that the start price exceeds the secondary market resale value of almost all released domains, and corresponds to a rate of decrease of just under $150/hr, meaning that less valuable domains will still have a multi-hour period during which people can purchase them before the premium expires.
In parallel, work should be initiated on a new nonlinear premium model, so that high initial premiums can be combined with a slow decrease towards 0, allowing both high and low value names to be bid on fairly.
### Specification
1. Deploy a new instance of the `LinearPremiumPriceOracle` with the initial premium set to 100,000 USD and the period set to 28 days, with other pricing variables identical to the current oracle.
2. Call `setPriceOracle` on `controller.ens.eth`, passing in the address of the new price oracle contract.
### Code
TBD
## \[EP1.2.1] \[Social] Removal of Brantly Millegan as Director of the ENS Foundation
::authors
| **Status** | Rejected |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11092) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0xa9a2dc5a52ea54b478c4c5fea88540622dff7ad5000f8d146dff482c6e6b6055) |
*Note: This was previously numbered EP6.1.*
### Summary
The removal of Brantly Millegan as Director of The ENS Foundation (the "Foundation Company.").
Adapted from the original [EP6](https://discuss.ens.domains/t/ep6-cancelled-see-ep-6-1-and-6-2) Proposal.
### Abstract
This social proposal puts forth a vote to enact the possible removal of Brantly Millegan as the Director of the Foundation Company.
This action is justifiable under [Clause 15 of the Articles of Association of The ENS Foundation paragraph titled 'Directors'](https://464911102-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVAbPWWNVJRvupIW5EOre%2Fuploads%2Fgit-blob-4b4ba71c3fe2a3146e9b1402d03ecb69d89c0913%2FM%26A%20-%20Incorp%20-%20The%20ENS%20Foundation%20-%2026%20October%202021.pdf?alt=media#page=9) which states that:
> The Council has the power, exercisable by notice to the Foundation Company, to appoint or remove one or more directors of the Foundation Company.
### Motivation
A timeline of events that led to this proposal has been posted by Community WG Stewards in another post [here](https://discuss.ens.domains/t/ens-dao-next-steps-re-brantly/10424/15) and quoted below:
> In May 2016, Brantly Millegan tweeted, "Homosexual acts are evil. Transgenderism doesn't exist. Abortion is murder. Contraception is a perversion. So is masturbation and porn."
>
> On February 5th, 2022, brantly.eth, well-known as a prominent representative of the ENS protocol, [defended these views in a publicly held Twitter space](https://www.dropbox.com/s/ljrp0vjibawuufr/Brantly%20ENS.mp4?dl=0).
>
> Irrespective of one's personal beliefs, we, as ENS DAO Community Stewards, must set the example for inclusivity and must divide our community.
>
> Propagating rhetoric that is viewed as hateful and discriminatory is not conduct conducive to the role as a Community Steward. This conduct will not be tolerated despite one's contributions to the protocol.
Through this Social Proposal, the DAO shall decide whether Brantly Millegan is deemed capable, or otherwise, of continuing his role as the Director of the Foundation Company, and to appoint a suitable replacement if he is deemed incapable.
### Specification
The removal of Brantly Millegan's directorship of the Foundation Company will be defined by a simple "Yes" or "No" vote with the option to abstain.
**Draft Snapshot Vote**
> Should Brantly Millegan be removed from directorship of the Foundation Company? **Choice 1:** Yes **Choice 2:** No **Choice 3:** Abstain
**If Majority "Yes:"** Brantly Millegan is voted to be removed and the results of [**\[EP6.2\] \[Social\] Election of a new Director of the ENS Foundation**](https://discuss.ens.domains/t/ep6-2-social-replacement-of-brantly-millegan-as-director-of-the-ens-foundation/11093) regarding Brantly Millegan's successor shall be effective immediately.
**If Majority "No:"** Brantly Millegan is voted to remain in a directorship position over the Foundation Company, the results of [**\[EP6.2\] \[Social\] Election of a new Director of the ENS Foundation**](https://discuss.ens.domains/t/ep6-2-social-replacement-of-brantly-millegan-as-director-of-the-ens-foundation/11093) shall be null and void.
### Notice to The ENS Foundation
In line with this proposal, a formal notice is served to the ENS Foundation as follows:
*"Pursuant to Article 15 of the Articles of Association, the council, hereby, gives notice to the Foundation Company of a vote to remove Brantly Millegan as a director of the Foundation Company.*
*Whereas, the council undertook a vote, via Snapshot, to remove Brantly Millegan, as a director of the Foundation Company;*
*Whereas, by a majority of the votes cast is to remove Brantly Millegan, as a director of the Foundation Company;*
*Wherefore, Brantly Millegan is hereby removed as a director of The ENS Foundation and shall cease and desist all duties thereto.*
*The result to be formally noted in the council records and shall be promptly communicated to the Foundation Company without further process.*
*This Notice shall have no force or effect, if the vote to remove Brantly Millegan fails to obtain a majority of the votes cast."*
## \[EP1.2.2] \[Social] Election of a new Director of The ENS Foundation
::authors
| **Status** | Passed, avsa.eth selected |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11093) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0xc4bc562d32e59a528dec301261e8d2b3b0c6880c2b782201c2e9f1ff3979d165) |
*Note: This was previously numbered EP6.2.*
### Summary
This proposal is for the election of a new Director of the ENS Foundation.
### Abstract
This social proposal puts forth a vote for the election of a new Director of the ENS foundation.
This is a **contingent proposal** that will only be ratified if [\[EP6.1\] \[Social\] Removal of Brantly Millegan as Director of The ENS Foundation](https://discuss.ens.domains/t/ep-6-1-social-removal-of-brantly-millegan-as-director-of-the-ens-foundation/11092) determines that Brantly Millegan shall be removed from the directorship of the Foundation Company.
**Contingency:** If majority "No" is voted on [\[EP6.1\] \[Social\] Removal of Brantly Millegan as Director of The ENS Foundation](https://discuss.ens.domains/t/ep-6-1-social-removal-of-brantly-millegan-as-director-of-the-ens-foundation/11092), this proposal shall be null and void.
### Motivation
By a vote of the council, Brantly Millegan was removed as a director of the Foundation Company., the DAO shall decide whether Brantly Millegan is deemed capable, or otherwise, of continuing his role as the Director of the Ethereum Foundation, and to appoint a suitable replacement if he is deems incapable.
A timeline of events that led to this proposal has been posted by Community WG Stewards in another post [here](https://discuss.ens.domains/t/ens-dao-next-steps-re-brantly/10424/15) and quoted below:
> In May 2016, Brantly Millegan tweeted that, "Homosexual acts are evil. Transgenderism doesn't exist. Abortion is murder. Contraception is a perversion. So is masturbation and porn."
>
> On February 5th, 2022, brantly.eth, well-known as a prominent representative of the ENS protocol, [defended these views in a publicly held Twitter space](https://www.dropbox.com/s/ljrp0vjibawuufr/Brantly%20ENS.mp4?dl=0).
>
> Irrespective of one's personal beliefs, we, as ENS DAO Community Stewards, must set the example for inclusivity and must not divide our community.
>
> Propagating rhetoric that is viewed as hateful and discriminatory is not conduct conducive to the role as a Community Steward. This conduct will not be tolerated despite one's contributions to the protocol.
### Specification
The appointment of the incoming Director will be held by a [ranked choice](https://en.wikipedia.org/wiki/Ranked_voting) Snapshot vote from a list of pre-determined nominees. Additionally, there shall be an option for voters to select "None of the above" or abstain from this vote.
**Draft Ranked Choice Snapshot Vote**
> Who should be elected as the new Director of the ENS Foundation?
>
> **Choice 1:** [avsa.eth](https://discuss.ens.domains/t/nominations-for-ens-foundation-director-to-replace-brantly-eth/10634/12)
>
> **Choice 2:** [daylon.eth](https://discuss.ens.domains/t/nominations-for-ens-foundation-director-to-replace-brantly-eth/10634/9)
>
> **Choice 3:** [healingvisions.eth](https://discuss.ens.domains/t/nominations-for-ens-foundation-director-to-replace-brantly-eth/10634/3)
>
> **Choice 4:** None of the above.
>
> **Choice 5:** Abstain.
**Note:** \*This list was randomized by @berrios.eth.
The nomination process for this appointment can be found [here](https://discuss.ens.domains/t/nominations-for-ens-foundation-director-to-replace-brantly-eth/10634), and a summary of Director's roles, responsibilities, compensation and liabilities can be found [here](https://discuss.ens.domains/t/role-responsibilities-of-ens-foundation-director/10632).
### Notice to The ENS Foundation
In line with this proposal, a formal notice is served to the ENS Foundation as follows:
*"Pursuant to Article 15 of the Articles of Association, the council, hereby, gives notice to the Foundation Company of the appointment of a director of the Foundation Company, to serve pursuant to the terms of its Articles.*
*Whereas, the council undertook a vote, via Snapshot, to remove Brantly Millegan,*
*Whereas, the majority of votes cast was to remove Brantly MIllegan and formal Notice given to the Foundation Company of such result,*
*Whereas, the council undertook a second vote, via Snapshot, from among nominees of the council, to appoint a new director of the Foundation Company;*
*Wherefore, the person, if any, with the highest number of votes cast is hereby appointed a director of the Foundation Company.*
*The results to be formally noted in the council records and the name of such person, if there be one, shall be promptly communicated to the Foundation Company without further process."*
You may view each candidates [delegate application here ](https://discuss.ens.domains/t/ens-dao-delegate-applications/815/1154)and comments in on nominees for directorship [here](https://discuss.ens.domains/t/comments-on-ens-foundation-nominees/10658).
## \[EP1.3.1] \[Executable] Q1 & Q2 2022 Meta-Governance WG Budget
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11101) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/115615865324623814833258987703837575663427750121726187103053182962864855260310) |
*Note: This was previously numbered EP7.1.*
#### Summary
The goal of the Meta-Governance working group (MG WG) is to manage the administration of the ENS DAO. The MG WG shall focus on the following three areas over the Q1/Q2 2022 Term.
1. Treasury Management
2. Governance process and DAO structures
3. DAO Tooling
The following budget is requested to provide the MG WG with the resources to work on the areas mentioned above over the Q1/Q2 2022 Term.
#### Proposed Budget
**Elected Steward Compensation (2,700 $ENS)**
* Elected steward compensation: 100 $ENS for each 3 elected stewards / month x 6 months = 1,800 $ENS.
* Lead coordinator compensation, to be paid to the steward that is the lead coordinator or other WG members who take on lead coordinator responsibilities, at the discretion of the Stewards: 150 $ENS / month x 6 months = 900 $ENS
##### Subgroups
**Treasury Management ($20k USDC)**
* Management and diversification strategies.
**DAO Governance ($20k USDC)**
* Documentation related to governance processes within the DAO
* Administer experiments related to onboarding, engaging, and valuing contributors within the DAO.
**DAO Tooling ($10K USDC)**
* Develop dashboards to improve transparency and visibility on DAO and ENS metrics.
The MG WG stewards may choose to purchase $ENS with the USDC requested and distribute a mix of USDC and $ENS to contributors as they see fit.
##### Total MG WG Funding Request for Q1/Q2 2022
Steward related compensation: 2,700\
$ENS MG WG funding: $50k USDC
## \[EP2.2.2] \[Executable] Q3 & Q4 2022 Ecosystem WG Budget
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/10195) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/115615865324623814833258987703837575663427750121726187103053182962864855260310) |
*Note: This was previously numbered EP7.2.*
### Summary
The Ecosystem WG is requesting funding to start the Q1/Q2 2022 term. The initial request is made up of three components:
1. Elected steward compensation: $27,500 in USDC/DAI
2. Bounties for the Bug Bounty program: $50,000 in USDC/DAI
3. Ecosystem WG operational budget: $50,000 in USDC/DAI, 6 ETH, and 6,500 $ENS
##### Bug Bounty
The ENS Bounty Program provides bounties for bugs. This program has been running since 2017 and historically has been funded by True Names Limited (TNL). With the creation of the DAO, the DAO is now able to manage and fund the bug bounty. Details of the program can be found [here](https://docs.ens.domains/bug-bounty-program). The $50,000 will be awarded to developers outside of TNL who find vulnerabilities in the ENS protocol. As well as funding for white hat coding in response to system vulnerabilities which arise.
##### Operational Budget
The operational budget supports ecosystem subgroups with the following allocations:
| Subgroup Name | Description | USDC/DAI | ETH | $ENS |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------- | ----- |
| Hackathons | Bounties, judging, and facilitating and managing ENS's hackathon participation. | $10,000 | | |
| Integrations | Bounties for ecosystem integration support | $10,000 | 500 | |
| 3rd Party Projects | Support projects that improve the ENS ecosystem, through proactive and retroactive grants. | $10,000 | 6 | 1,000 |
| Bug Bounty | Administer the bug bounty program | $5,000 | | |
| WG Unallocated Funds | Funds to be allocated to the above subgroups or facilitate the funding of new subgroups as the council of stewards deem necessary | $15,000 | 5,000 | |
| Total | $50,000 USDC/DAI | 6 ETH | 6,500 $ENS | |
##### Elected Steward Compensation
Provide compensation for the stewarding and the coordination efforts of active elected stewards.
| Description | Compensation | Months # | Stewards # | Total |
| ------------------------- | ------------ | ---------------- | ---------- | ------- |
| Base Compensation | $1,000/month | 5.5 | 3 | $16,500 |
| Supplement compensation\* | $2,000/month | 5.5 | N/A | $11,000 |
| Total | | $27,500 USDC/DAI | | |
\*Supplement compensation is allocated to the steward who supports coordination or who has greater involvement in DAO activities above what is expected of a steward. The steward council determines how the supplemental compensation is split between the stewards based on contributions of each steward.
It should be noted that the ecosystem working group has three elected stewards (@slobo.eth, @Ginge.eth, @bobjiang) and two appointed stewards (@nick.eth, @jefflau.eth). The appointed stewards are not compensated via this request.
## \[EP1.3.3] \[Executable] Q1 & Q2 2022 Community WG Budget
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11046) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/115615865324623814833258987703837575663427750121726187103053182962864855260310) |
*Note: This was previously numbered EP7.3.*
### Summary
1. **Community WG Operational Budget:** 115,000 USDC/DAI, 1 ETH, and 650 ENS.
2. **Elected Steward Compensation:** 27,500 in USDC/DAI.
**Total USD Value:** \~$155,050.
### Community WG Budget: Q1 & Q2 Steward Term
#### 1. Operational Budget
This funding is requested to fulfill the needs of the entire Q1/Q2 term.
| Subgroup Name | Description | USDC/DAI | ETH | $ENS |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: | :-----: | :--: |
| Learn Docs | Content related to user documentation, tutorials, and case studies. | 11,000 | 0 | 0 |
| Communications | Provide communications services for the DAO to include a bi-weekly digest, weekly twitter spaces, and other outreach services to drive education and engagement. | 10,000 | 0 | 100 |
| Onboarding | Facilitate and coordinate weekly onboarding calls about ENS and the DAO. Also, focus on refining the DAO onboarding process. | 10,000 | 0 | 0 |
| Discord Support Moderation | Provides 24-hr support coverage in the ENS Discord. | 66,000 | 0 | 0 |
| Translation | Administer translation services for the ENS DAO official documents and website details. | 6,000 | 0 | 0 |
| Communidad Para Hispanohablantes | Increase onboarding for the native Spanish-speaking community. | 2,000 | 0 | 0 |
| IRL Outreach | Community engagement focused on in-person events. | 10,000 | 0 | 0 |
| WG Discretionary Funds | Discretionary funding to be allocated to the above subgroups or facilitate the funding of new subgroups as the council of stewards deem necessary. | 0 | 1 | 550 |
| **Total** | **115,000** | **1** | **650** | |
**Note:** This includes subgroups and supports moderation of the ENS Discord. The Discord moderation is a necessary DAO expense carried by the community working group.
#### 2. Elected Steward Compensation
Provide compensation for the three elected Community Stewards @limes , @spencecoin and @coltron.eth for the entire Q1/Q2 steward term.
| Description | Compensation | Months # | Stewards # | Total USDC |
| ------------------------- | :----------: | :--------: | :--------: | :--------: |
| Base Compensation | $1,000/month | 5.5 | 3 | 16,500 |
| Supplemental Compensation | $2,000/month | 5.5 | - | 11,000 |
| **Total** | | **27,500** | | |
**Note:** *Supplemental compensation shall be distributed to stewards and contributors involved in running operations for the WG. The supplemental compensation will be used in situations where contributors or stewards perform duties beyond what is normally expected. The steward council determines how the supplemental compensation will be split between the stewards based on the contributions of each steward.*
#### Considerations
Multiple parties will approve all funding disbursements using a multi-sig. This budget does not guarantee disbursement, specifically if services rendered to the DAO are incomplete or deemed unsatisfactory. If these situations arise, the working group will review them publicly at the weekly Community Steward Call.
Any funding not used will be re-allocated back to the treasury.
## \[EP1.3.4] \[Executable] Q1 & Q2 2022 Public Goods WG Budget
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11022) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/115615865324623814833258987703837575663427750121726187103053182962864855260310) |
*Note: This was previously numbered EP7.4.*
### Summary
The Ecosystem WG is requesting funding to start the Q1/Q2 2022 term. The initial request is made up of three components:
1. Elected steward compensation: $12,000 in cDAI
2. Bounties for ENS Public Goods Request for Proposals program: $50,000 in cDAI
3. Operational Budget $38,000 in cDAI
**Total for Q1 & Q2: $150,000.00 in cDAI**
The group will be using the price of cDAI in uniswap to calculate the exact amounts requested. We are using cDAI as a accounting unit as a manner to provide a stable value that will still accrue value while not in utilization and resist dollar depreciation. The group can convert them in DAI when sending out payments and grants. The current price of cDAI orbits around 0.021-0.022 per dai and the total budget would be, in today's value, about 6.85M cDAI.
**Elected steward compensation**
The group has 5 elected stewards: Alex (avsa.eth), makoto.eth, sumedha.eth, Scott and Richard Moore (Ricmoo.eth). Two of these steward are appointed by True Names and will not be receiving compensation, and one of the other stewards has elected to forego compensation and therefore we will asking only for a total of 12k USD for the total Steward Compensation. Pay for past months will be sent immediately and the remaining will be streamed until june 30th.
**Bounties for ENS Public Goods Request for Proposals program:**
The bounties will be distributed in prizes of $1,000, $5,000, and $10,000 for projects that execute on basic implementation of goals elected by the stewards. These are set to be given directly to projects and not spent on operations. Any funds remaining at the end of the term will be either given back to the DAO or rolled in the Public Goods stewards budget for the next term.
**Operational Budget**
These will encompass tasks like reimbursements for expenses executed by stewards, payment for projects like a website, social media, or compensation for work done in partner integrations. All payments must be approved by at least 3 other stewards and will be executed in the most transparent manner the stewards can find.
## \[EP1.4] \[Executable] Reimburse True Names for expenses and tax obligations incurred for the DAO
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/10053) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/82659277767818009782194204088226418907972756681918239480374274857360772298879) |
*Note: This was previously numbered EP8.*
### Abstract
Since ENS started allowing registrations using the annual-fee model, revenue from this has accrued to the ENS root multisig, which is controlled by seven individuals drawn from the Ethereum community. In order to shield them from individual tax liability, True Names Limited, the development company responsible for ENS development, historically identified itself as the beneficial owner of these funds, which obliged True Names to pay tax on any income to the multisig.
In past years True Names has covered this tax bill from its own reserves - primarily out of funds that were collected during the Short Name auction - but in 2021 revenue rose to a level that meant that was no longer sustainable. Accordingly, True Names requested funds from the multisig to cover the anticipated tax, and the multisig agreed.
The calculation used to determine the tax owing used the actual income to October 20th, plus a 1/12th buffer to cover the anticipated income between the launch of the DAO and its potential request for control of the funds from the keyholders. This total came to $2,163,921 USDC.
However, this failed to take into account the enormous uptick in interest that the announcement of the DAO produced, and so falls significantly short of True Names' actual tax obligations for FY 2021. This proposal requests that the DAO sends True Names the remainder of the funds required to cover the multisig's income during the period that True Names was the beneficial owner.
Further, True Names has incurred the following expenses on behalf of the DAO in January 2022:
:::note
This screenshot could not be found
:::
We additionally request the DAO reimburse True Names for these expenses in the total of $48,637.
#### Revenue
Revenue to the multisig came exclusively from ENS name registrations and renewals, and can be calculated from onchain data using [this BigQuery query](https://gist.github.com/Arachnid/dfd374886a3e6b0a0eb17b26703d776a), producing the following results:
| Month | ETH | USD |
| --------- | ------------- | --------------- |
| Jan 2021 | 411.6875 | 498484.22 |
| Feb 2021 | 383.5613 | 643985.05 |
| Mar 2021 | 453.5619 | 776834.28 |
| Apr 2021 | 429.0654 | 955345.36 |
| May 2021 | 243.0624 | 740165.91 |
| Jun 2021 | 422.2419 | 993899.95 |
| Jul 2021 | 384.6863 | 811202.23 |
| Aug 2021 | 849.9890 | 2563121.38 |
| Sep 2021 | 728.7825 | 2490699.18 |
| Oct 2021 | 500.3753 | 1863125.83 |
| Nov 2021 | 1699.4660 | 7643673.03 |
| **Total** | **6506.4793** | **19980536.41** |
#### Tax
Singapore's company tax rate is 17%, meaning that the tax owing on $19,980,536 comes to $3,396,691. After deducting the $2,163,921 USDC already sent by the multisig, this leaves a shortfall of $1,232,770.
### Specification
We request that the DAO send $1,281,407 USDC to coldwallet.ens.eth.
## \[EP1.5] \[Executable] Change to Exponential Premium Price Oracle
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11320) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/107166664722174233740232174220463354481004128961821575530758100250899337476509) |
*Note: This was previously numbered EP9.*
### Abstract
In the past we deployed the Linear Premium Oracle as a way to create a distribution mechanism that did not involve gas auctions and bots. This was largely successful and those who wanted a recently expired name could participate in the dutch auction and not have to compete on gas or with bots. Recently with the popularity of ENS increasing, the demand and the price people are willing to pay for these premium names has increased. In response to this TNL quickly drafted a [short-term solution](https://discuss.ens.domains/t/ep5-executable-set-the-temporary-premium-start-price-to-100-000/9336) to raise the premium to 100k, which we felt was the upper limit for what a linear price decay curve could handle.
There are a couple reasons for this:
1. On a linear curve, if the price is too high the price decreases too fast and the UX is bad for a user who wants an exact price (especially at the lower end of the curve)
2. If you extend the time period out, the premium lasts for too long. E.g. If we made it 1 million USD and we wanted a similar price decay speed as 100k, we would need to run it for 10 months, which seems unreasonable.
We can see from the data below, even with the new 100k premium, we have already had a 5-7 domains go for maximum, or close to maximum premium. If a domain sells for the actual premium, it means the dutch auction is not doing its job and so we need to deploy a long-term solution for dealing with premium pricing.
| Row | Label | Event Timestamp | Premium |
| --- | ----- | ----------------------- | ------------------ |
| 1 | bbc | 2022-01-30 17:46:03 UTC | 100230.75321837279 |
| 2 | mets | 2022-02-04 17:16:22 UTC | 100082.49847319399 |
| 3 | fbi | 2022-02-05 06:02:31 UTC | 99894.00632472485 |
| 4 | fly | 2022-02-04 18:49:00 UTC | 99747.22640247621 |
| 5 | ups | 2022-02-05 07:46:24 UTC | 98822.14747808539 |
| 6 | dog | 2022-02-06 16:19:05 UTC | 92950.09208752771 |
| 7 | ubs | 2022-02-01 15:31:35 UTC | 89633.15081063367 |
| 8 | ubi | 2022-02-19 17:06:17 UTC | 72161.56328771653 |
| 9 | punks | 2022-02-16 00:15:44 UTC | 59153.166146336 |
| 10 | omg | 2022-02-24 16:05:57 UTC | 33214.42499419019 |
The long-term solution would be to change the actual curve to something that could start at a very high price, would decrease rapidly at the beginning and slow down at the end so you have better UX for users. And therefore this proposal is to deploy an exponential price curve, that does exactly this. This would allow fairer bidding on both high and low priced names.
### Contract Code
[https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/ExponentialPremiumPriceOracle.sol](https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/ExponentialPremiumPriceOracle.sol)
### Specification
Call `setPriceOracle` on `controller.ens.eth`, passing in the address of the deployed `ExponentialPremiumPriceOracle` (TBD).
## \[EP1.6] \[Executable] A DAO-Governed Identity Server
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/11125) |
| **Social Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x104eb11d42813fadc2b408856e8fa2c10e34dbb4a87abaa2f089ece124263f16) |
| **Onchain Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/82659277767818009782194204088226418907972756681918239480374274857360772298879) |
*Note: This was previously numbered EP10.*
### Abstract
In our research, we found that many services wanted to integrate the Sign-In with Ethereum workflow but did not have the ability to add new passwordless authentication methods to their installations.
We also learned that most services already support OpenID Connect, and were open to adding a new Identity Provider that supported the SIWE workflow. By meeting those services where they are today, we can provide a pragmatic stepping stone towards true decentralization, with an upgrade path to direct authentication.
To ensure adherence to the vision, it's critical that we collaborate with the ENS DAO on hosting and maintenance of this identity server, ensuring the identity server's governance ultimately resides with the community, whom we believe will always put users first. This would be the world's first DAO-hosted, transparent identity server.
### Rationale
The ENS service and community would benefit from increased adoption of Sign-In with Ethereum due to the enablement of organizations to use ENS as a core touchpoint for a user's basic identity and information (via ENS profiles).
Additionally, we believe that a community server could be governed by a credibly neutral party that Ethereum users accept as an intermediary. We think a non-profit or DAO are the right structures to help govern such a server, which is why we would like to collaborate with the ENS DAO on hosting and maintenance.
### Specification and Proposal Request
* **Establish a Subgroup in the Ecosystem Working Group: Community Managed Identity Server**
* **$250,000** allocated from the DAO to the Ecosystem WG to fund this Subgroup.
* **$75,000** from the allocated budget will be in place for community contributions related to the Subgroup, including grants for development, evangelism, and retroactive rewards for SIWE-related efforts.
* **$175,000** from the allocated budget will go towards Spruce's maintenance contract (see below). Paid 25% upon execution, and then an additional 25% every 3 months.
* This Subgroup will support the administration and maintenance of a DAO-run Identity Server for Sign-In with Ethereum. This subgroup will also serve as a support system to help onboard organizations, and evangelize Sign-In with Ethereum to allow users to control their identifiers and use ENS profiles as a base identity.
* An important part of duties this group will include creating training, onboarding, and maintenance materials for managing the server on a specified cloud account.
* Additionally, the group will be responsible for providing updates to the broader community on the health of the server.
* Initial lead: Rocco from Spruce, while continuing to add interested parties to the group for good governance.
* **A 12-month maintenance contract awarded to Spruce for the continuous monitoring, maintaining, and improving of the deployed Identity Server.**
* Spruce will help host a [`siwe-oidc`](https://github.com/spruceid/siwe-oidc) implementation in a lightweight fashion, using a well-known infrastructure provider ultimately administered by the Subgroup.
* Spruce will also be responsible for the deployment, and continuous monitoring, maintenance, and improvements on the server throughout the duration of the contract.
* If the DAO votes to end the contract funding will be returned against the remaining days of the year and we will provide sufficient training for administrators to transfer those duties to a new organization.
* The server is expected to be live within 60 days of this proposal being accepted, assuming that access to the necessary systems and people is provided on a timely basis.
* The 1-year contract begins when this proposal is accepted, and there will not be additional setup fees even if there are increased coordination costs to get the service running.
## \[EP1.7] \[Executable] End the $ENS and EP2 airdrops
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/12047) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/99882233577221676057992280816078245519848378270443751235073826886360950537295) |
*Note: This was previously numbered EP11.*
### Abstract
The $ENS airdrop can be terminated at any time on or after May 4, 2022 by a call from the DAO, transferring remaining tokens to an address it specifies. The EP2 airdrop can be terminated at any time by revoking the token approval given to it by the DAO. This EP proposes to execute both of these actions on or shortly after May 4, 2022.
### Specification
* Call 'sweep' on the ENS token contract, specifying the DAO wallet as target address.
* Call 'approve' on the ENS token contract, specifying the EP2 airdrop contract and an allowance of 0.
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ----- | -------- | -------- | ------------------------------------------ |
| 0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72 | 0 | sweep | dest | 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7 |
| 0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72 | 0 | approve | spender | 0x4A1241C2Cf2fD4a39918BCd738f90Bd7094eC2DC |
| amount | 0 | | | |
## \[EP1.8] \[Social] Working Group Rules
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/12953) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xc7186cf8bebe47600f8d847e76f7971ea97b48bc04eda1e07780aff91fb6410d) |
*Note: This was previously numbered EP12.*
### Abstract
This is a proposal to repeal the working group rules passed in [EP4](https://docs.ens.domains/v/governance/governance-proposals/ep4-social-proposal-creation-of-foundational-working-groups-and-working-group-rules) and replace those rules with working group rules specified in this proposal for the Second Term of 2022 and all Terms thereafter.
The working group rules specified in this proposal add more details about Steward responsibilities and the management of working group funds, as well as introducing the requirement of each working group to appoint a lead steward.
The specification below also introduces a rule to appoint a new DAO Secretary, responsible for managing working relationships and communications across working groups as well as performing administrative duties for the DAO.
### Specification
#### Working Groups Rules
1. Formation of Working Groups
1. To create a new working group, a social proposal, as defined by the ENS governance documentation (‘Social Proposal’), must be put forward and passed by the DAO.
2. A Social Proposal to create a new working group must demonstrate that the new working group is needed and the work cannot be undertaken within an existing working group.
2. Dissolution of Working Groups
1. A working group can be dissolved by passing a Social Proposal requesting the dissolution of a working group or working groups.
2. If an active proposal is put forward to dissolve a working group, all working group funds, including outgoing payments, within that working group, are to be frozen with immediate effect, pending the outcome of that vote.
3. Upon the dissolution of a working group, any and all unspent working group funds from that working group, at the time of dissolution, must be immediately returned to the DAO treasury, without delay.
3. Working Group Stewards
1. Each working group shall be managed by three stewards (hereafter a 'Steward' or 'Stewards').
2. Stewards will be elected to serve within working groups for a set period of time (hereafter known as a 'Term' or 'Terms').
3. There are two Terms each calendar year:
1. The first Term commences at 9am UTC on January 1 each year and ends immediately prior to the commencement of the second Term ('First Term'); and
2. The second Term commences at 9am UTC on July 1 each year and ends immediately prior to the commencement of the First Term of the following year ('Second Term').
4. Stewards are responsible for overseeing the operation of working groups in accordance with these rules and the ENS DAO constitution.
5. The responsibilities of Stewards include, but are not limited to:
1. Requesting working group funds from the DAO in accordance with these rules;
2. Approving the creation of sub-groups or workstreams within a working group to undertake work and/or carry out specific projects or tasks;
3. Dissolving sub-groups or workstreams within a working group;
4. Using discretion to make working group funds available to sub-groups, workstreams, or contributors within a working group;
5. Using discretion to disburse working group funds to people and/or projects in accordance with the ENS DAO constitution; and
6. Acting as keyholders of working group multi-sigs.
4. Steward Eligibility and Nominations
1. Any individual is eligible to nominate themselves to be a Steward of a working group within the DAO ('Eligible Person' or 'Eligible Persons').
2. To be eligible to be included in the ballot for First Term elections of a given year, Eligible Persons must nominate themselves between 9am UTC on December 6 and 9am UTC on December 9 ('First Term Nomination Window').
3. To be eligible to be included in the ballot for Second Term elections of a given year, Eligible Persons must nominate themselves between 9am UTC on June 6 and 9am UTC on June 9 ('Second Term Nomination Window').
4. An Eligible Person may nominate themselves to become a Steward of a working group or working groups during the First Term Nomination Window or the Second Term Nomination Window (each a 'Nomination Window'), by meeting the requirements set out in a call for nominations posted in the relevant working group category of the ENS governance forum.
5. An Eligible Person who completes the steps outlined in rule 4.4 above during a Nomination Window and receives 10,000 signed votes to support their nomination will be included in the ballot as a nominee in the election for Stewards that takes place following that Nomination Window ('Nominee').
5. Steward Elections
1. Elections for working group Stewards for the First Term of a given year will take place by a vote of governance token holders using signed messages and will be open for 120 hours, commencing at 9am UTC on December 10 each year ('First Term Election Window').
2. Elections for working group Stewards for the Second Term of a given year will take place by a vote of governance token holders using signed messages and will be open for 120 hours, commencing at 9am UTC on June 10 each year ('Second Term Election Window').
3. The top-ranked Nominees from each working group vote held during a First Term Election Window or a Second Term Election Window (each an 'Election Window'), will fill any available positions for the role of Steward for those working groups for the Term immediately following an Election Window, based on the order in which they are ranked in each working group vote.
4. A Nominee elected to serve as a Steward may not take up the role of Steward for more than two working groups during a single Term.
6. Delay of Nominations or Elections
1. In the event that nominations or elections for Stewards take place after a Nomination Window or after an Election Window, the nomination process and/or elections shall take place, as otherwise prescribed in rules 4 and 5 above, as soon as is practicable after the missed Nomination Window or missed Election Window.
2. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, outgoing Stewards from the previous Term shall stay in their positions as working group Stewards until immediately prior to 9am UTC the day following the end of the election, which, for the avoidance of doubt, is 120 hours after voting in those elections commenced.
3. In the event that an election takes place outside of an Election Window and after the commencement date of a new Term, newly elected Stewards will assume the responsibilities of stewardship within working groups at 9am UTC the day following the end of the election, as defined in rule 6.2 above, for the remainder of that Term.
7. Removal and Replacement of Stewards
1. Stewards may be removed at any time by:
1. a Social Proposal passed by the DAO; or
2. a simple indicative majority vote among Stewards of all working groups, with the outcome of that vote communicated in the relevant working group category of the ENS governance forum.
2. Stewards may step down from their position at any time by communicating their intention to step down in the ENS governance forum.
3. In the event that a Steward is removed, steps down, or is unable to continue as a Steward, for whatever reason, prior to the end of a Term, a new election must be held to fill any vacant Steward positions, in accordance with rule 6 above.
8. Lead Stewards
1. Each working group must appoint a lead Steward within the first five days of a Term (hereafter a 'Lead Steward' or 'Lead Stewards').
2. Only current elected Stewards of a working group are eligible to serve as Lead Stewards within a given working group.
3. Lead Stewards may be appointed or removed from that role at any time by a simple indicative majority vote among the Stewards of a working group, with the outcome of that vote communicated in the relevant working group category of the ENS governance forum.
4. In the event that a Lead Steward steps down from the position or is removed as a Lead Steward before the end of a Term in accordance with rule 8.3 above, a new Lead Steward must be appointed within five calendar days.
5. A Steward who is appointed to serve as a Lead Steward of a working group will remain in that position, as Lead Steward, from the date of appointment until the end of their elected Term as a Steward or until they are removed as a Lead Steward in accordance with rule 8.3 above or until they are removed as a Steward in accordance with rule 7 above.
6. Lead Stewards are responsible for the operational management and administration of working groups and are expected to provide regular updates to the DAO in the ENS governance forum related to working group progress, achievements, and challenges.
7. The responsibilities of Lead Stewards include, but are not limited to:
1. Acting as a representative of a working group;
2. Managing resource requests from sub-groups, workstreams, and contributors within a working group;
3. Initiating the disbursement of working group funds on an as-needed basis;
4. Providing reports of working group spending in the ENS governance forum; and
5. Maintaining open communications with DAO participants in the ENS governance forum.
9. DAO Secretary
1. At the start of each Term, the current Stewards of each working group shall collaborate to appoint an individual who will serve as the secretary of the DAO (hereafter 'Secretary' or 'Secretaries').
2. The Secretary may be appointed or removed from that role at any time by a majority vote of all elected Stewards in a given Term with the outcome of that vote communicated in the ENS governance forum.
3. The Secretary will remain in that position, as Secretary of the DAO, from the date of appointment until the end of a given Term or until the date at which they are removed from that position in accordance with rule 9.2 above.
4. Secretaries are eligible to receive fair compensation for their work as Secretary of the DAO.
5. Compensation for the Secretary of the DAO is to be paid by the Meta-Governance Working Group using funds requested in accordance with rule 10 below.
6. Any individual is eligible to be appointed as the Secretary of the DAO, including past and present working group Stewards.
7. The Secretary is responsible for managing working relationships and communications across working groups as well as performing administrative duties for the DAO.
8. The responsibilities of the Secretary include, but are not limited to:
1. Managing a DAO-wide calendar;
2. Coordinating and attending working group meetings where possible and ensuring meeting summaries are posted in the ENS governance forum;
3. Assisting Stewards with coordination challenges within working groups; and
4. Acting as a multi-sig keyholder for each working group.
10. Working Group Funds
1. To request working group funds, Stewards of all working groups will collaborate to submit an active executable proposal, as defined by the ENS governance documentation ('Collective Proposal'), to the DAO during the months of January, April, July, and October each calendar year (each a 'Funding Window').
1. In order for a working group to have a funding request included in a Collective Proposal submitted to the DAO during a Funding Window, the funding request must have passed as a Social Proposal in the same Funding Window.
2. In the case of an emergency, where working group funds are needed by a working group outside of a Funding Window, an executable proposal, as defined by the ENS governance documentation, may be submitted at any time by a Steward of a working group to request funds from the DAO.
2. Working group funds requested and approved in accordance with rule 10.1 above are to be paid out into separate working group multi-sigs controlled by the DAO.
3. Each working group multi-sig must have four keyholders, made up of three current elected Stewards for that working group and the Secretary of the DAO for that Term, with no other keyholders permitted.
4. Working group funds may be disbursed from working group multi-sigs with three-of-four keyholder signing.
5. Stewards of a given working group shall have the discretion to reallocate funds approved in a Collective Proposal where appropriate and where it is not in conflict with any rules of the DAO, DAO bylaws, or the ENS DAO constitution.
11. Compensation for Stewards and Lead Stewards
1. Stewards are eligible to receive fair compensation for their work as a Steward or Lead Steward in the DAO.
2. All requests for Steward or Lead Steward compensation must be detailed in a Collective Proposal for working group funds submitted to the DAO in accordance with rule 10.1 above.
3. Stewards may not receive compensation for their role as a Steward or Lead Steward outside of that compensation expressly provided for in a Collective Proposal submitted to the DAO in accordance with rule 10.1 above.
12. Amendments
1. These rules may be amended at any time by passing a Social Proposal.
#### Next Steps
This vote will be a single choice vote. You may vote 'for' or 'against' the proposal, or choose to abstain from the vote.
By voting 'for' this proposal, you are voting in favor of repealing the working group rules passed in EP4 and replacing them with the working group rules provided in the specification of this proposal.
## \[EP1.9] \[Executable] Fund the Protocol Guild pilot with 200,000 $ENS
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/12877) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/8759198094868535520038506706231539487662297008587733129541987545743856603253) |
*Note: This was previously numbered EP13.*
### Abstract
We propose that 200k ENS (\~3.7% of the [unclaimed airdrop](https://twitter.com/ensdomains/status/1522066354387718144)) be allocated in recognition of past and ongoing work of these core contributors.
ENS is one of the most successful projects built on Ethereum, and yet core protocol contributors do not benefit in any way from the success of projects being built on Ethereum. The Protocol Guild provides a vehicle for the ENS community to distribute governance tokens to those individuals who build and maintain the foundational infrastructure that ENS relies on.
ENS sponsorship of the Guild allows members to engage with ENS in a way that is values- and incentive-aligned. Simultaneously, it will allow them to continue the important work of scaling our shared infrastructure and making it as resilient as possible for the applications on top of it.
### Specification
#### Useful links
* [Protocol Guild Docs](https://protocol-guild.readthedocs.io/en/latest/index.html)
* [1 Year Vesting Contract](https://app.0xsplits.xyz/accounts/0xF29Ff96aaEa6C9A1fBa851f74737f3c069d4f1a9/)
* [Split Contract](https://app.0xsplits.xyz/accounts/0x84af3D5824F0390b9510440B6ABB5CC02BB68ea1/)
* [Initial Announcement - Dec 2021](https://stateful.mirror.xyz/mEDvFXGCKdDhR-N320KRtsq60Y2OPk8rHcHBCFVryXY)
* [List of Members](https://protocol-guild.readthedocs.io/en/latest/9-membership.html)
* [Protocol Guild twitter](https://twitter.com/ProtocolGuild)
#### Context
1. As a credibly neutral, maximally uncapturable infrastructure with no block reward, the Ethereum base protocol doesn't offer the same token incentives to contributors as applications or L2s can. However, the protocol still needs to attract and retain talent to continue to evolve. As the broader ecosystem continues to grow, competition for talented individuals will only increase. This isn't to fault individuals for rationally weighting financial incentives, or protocols for leveraging the power of tokens - this is just the reality of the current context. We also acknowledge that financial motivations aren't the only or best motivator for people, it's just one tool in our toolset that is currently underleveraged.
2. Existing public goods funding solutions tend to be either too narrow or broad in scope, fail to exclusively target core protocol contributors, or depend on an intermediating institution, which often leads to organizations, and not individuals, being recipients of funds.
3. The Protocol benefits from contributor continuity. Transferring institutional knowledge between cohorts is more likely to happen successfully the more overlap there is.
Here's a longer exploration of the [project rationale](https://protocol-guild.readthedocs.io/en/latest/1-proposal-rationale.html).
If we believe what we are building is important, then we should structure the incentives to attract more smart people to work on it. After all, "Ethereum is an unprecedented arena for playing cooperative games"; we should try to manifest the novel possibilities made possible by this arena. ([Griffith, 2019](https://medium.com/@virgilgr/ethereum-is-game-changing-technology-literally-d67e01a01cf8))
#### What is the Protocol Guild?
The Protocol Guild aims to address the challenges mentioned above with a simple tool: a weighted split contract that includes vesting. Members will solicit sponsorships in the form of tokens from applications & protocols that build on Ethereum, which gives core contributors exposure to success at the application layer:
* current contributors are rewarded for past work through time-based weighting
* current contributors contribute for longer periods, resulting in less contributor churn
* new contributors are incentivized to join core protocol work, protocol evolution and maintenance is more robust
To date, the membership includes over 110 Ethereum protocol contributors, including researchers, client maintainers, upgrade coordinators, and more, all self-curated (member list [here](https://protocol-guild.readthedocs.io/en/latest/9-membership.html)). This is a broad-based ecosystem effort: members come from 22 different teams and 9 organizations. Only 30% of members are directly employed by the EF. The membership is continuously curated through quarterly updates to the split contract - we expect the membership to grow to 150 over the course of the Pilot.
The Guild contracts will act as an autonomous value routing mechanism, operated independently from any existing institution, purpose-built for incentivizing long-term core protocol work. At no point does PG take custody of funds on behalf of members, it is all handled trustlessly. The diagram below and the [docs](https://protocol-guild.readthedocs.io/en/latest/3-smart-contract.html) have more information.

#### 2022 Pilot
Since starting the project in Nov 2021, we've built norms around member onboarding , refined the splitting and vesting mechanisms, and created extensive documentation on how PG operates.
At this point, we're ready to test the mechanism's efficacy with a 1 year / $10-20mm Pilot. We want to make sure the mechanism operates smoothly before graduating to a full-scale fundraising round for longer vesting periods. The funds for the Pilot would be vested directly to Guild members over one year: see the [Pilot vesting contract here](https://app.0xsplits.xyz/accounts/0xF29Ff96aaEa6C9A1fBa851f74737f3c069d4f1a9/).
#### Proposal
We are proposing that 200k ENS (\~3.7% of the [unclaimed airdrop](https://twitter.com/ensdomains/status/1522066354387718144)) be sent to the [Pilot vesting contract](https://app.0xsplits.xyz/accounts/0xF29Ff96aaEa6C9A1fBa851f74737f3c069d4f1a9/) deployed at 0xF29…f1a9 in recognition of the past and ongoing work of these core contributors.
The tokens would not be liquidated, but would vest for one year to each beneficiary listed on the underlying split. Each recipient would be making an independent decision about how to use their tokens once vested.
The USD value of the 200k ENS is $2.49mm as of the time of this post on May 25 2022. This is roughly in line with what we have already proposed to similarly prominent Ethereum-based protocols. [Lido's 2mm LDO contribution](https://research.lido.fi/t/proposal-to-fund-the-protocol-guild-pilot-via-a-lido-grant/2016) was worth $2.6mm; the [active Uniswap proposal](https://gov.uniswap.org/t/governance-proposal-should-the-uniswap-community-participate-in-the-protocol-guild-pilot/16824) requesting 500k UNI would be worth $2.75mm.
There are a few reasons why supporting the Protocol Guild benefits the ENS community:
* ENS's long-term success is tightly coupled with the continued evolution and maintenance of the Ethereum protocol. These are projects that often have multi-year timelines. Contributing to the Pilot meaningfully increases the incentive to contribute to the core protocol, including:
* [The Merge](https://github.com/ethereum/pm/blob/master/Merge/mainnet-readiness.md): moving from PoW to PoS, increasing security and sustainability
* EVM improvements: new functionality for developers like [EOF](https://notes.ethereum.org/@ipsilon/evm-object-format-overview)
* [Statelessness](https://notes.ethereum.org/@gballet/Sy-a6T5St): sustainable management for state growth
* Supporting L2 scaling: [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844), [EIP-4488](https://eips.ethereum.org/EIPS/eip-4488)
* [Proposer Builder Separation](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance): reducing centralizing incentives for consensus participants
* Continuous client maintenance: improving sync, exploring new database types, researching modular clients
* Coordinating network upgrades: making sure the community helps to shape and is aware of network upgrades
* Having exposure to ENS allows protocol contributors to engage more with ENS governance. Members will be encouraged (but not obligated) to delegate them within the ENS governance framework.
* ENS should be among the protocols maximally aligned with the Public Goods of the largest ecosystem it operates in. Pilot participation maintains and expands the ENS community's existing reputation for funding Public Goods.
* Diverse funding sources from the community further decentralizes protocol governance and prevents influence from pooling with any single entity.
We hope that a successful Pilot will pave the way for future funding collaborations between the ENS community and the Protocol Guild as we scale up the project after the Pilot. To that end, we think it's important to demonstrate impact: learn more about how we intend to evaluate [Pilot outcomes here](https://protocol-guild.readthedocs.io/en/latest/5-initial-pilot.html). We have also adopted an active stance of continuous adjustments to improve PG while we operate the Pilot: improving documentation, resources for members, better transparency, etc.
### Transactions
| Address | Value | Function | Argument | Value |
| ---------------- | ------------------------ | -------- | --------- | -------------------- |
| token.ensdao.eth | 0 | transfer | recipient | theprotocolguild.eth |
| amount | 200000000000000000000000 | | | |
## \[EP2.1] \[Executable] Funding True Names Ltd
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/13391) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/112764562576314516994943312429834673309292069549953740415731020720942627228986) |
*Note: This was previously numbered EP14.*
### Abstract
True Names Ltd ("TNL") developed the Ethereum Name Service ("ENS") protocol, continues to manage the development of the ENS Protocol and solely focuses on this project. Incubated at the Ethereum Foundation in 2017, TNL spun out in 2018 with the charge of designing and deploying THE next generation naming service. TNL is now a growing team of web3 enthusiasts from across the globe working together to support the ENS Ecosystem that now has a passionate community that has registered over 1 million ENS names and uses more than 500 integrations.
In 2021, TNL initiated the creation of the ENS DAO with the goal of 1) furthering the development of the ENS Protocol and 2) funding public goods projects.
In consideration of the work completed thus far this calendar year and the work in the months and years to come, per Article III of the ENS Constitution, True Names Ltd respectfully requests an evergreen grant stream that will allow the organization to continue the development and improvement of the ENS Protocol. For Calendar Year 2022, this request will amount to $4,197,500 USDC which is equivalent to a daily stream of $11,500 USDC. In Q1 of each year, TNL or the ENS Dao may make requests to alter and/or terminate this evergreen grant stream.
### Specification
We request that the ENS DAO approve a daily grant of $11,500 USDC to True Names Ltd, backdated to January 1st, 2022.
This will be accomplished by approving a dedicated token streaming contract at `0xB1377e4f32e6746444970823D5506F98f5A04201` to spend USDC on behalf of the DAO.
## \[EP2.2.1] \[Executable] Q3 & Q4 2022 Meta-Governance WG Budget
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/13756) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x46c7294aca8d70ae8213e8e8c6915697c7be1aab731fbb7e534276f7eb0ef2b9) |
*Note: This was previously numbered EP16.1.*
### Summary
The Meta-Governance Working Group is requesting funding of 632k USD equivalent for the Q3/Q4 of 2022. The budget has three categories. All figures are presented in USD equivalent.

### Multisigs / Subgroups: $371k USD Value
Funding in this category is related to the two Meta-Governance subgroup multi-sigs. These have been reviewed and approved by the Meta-Gov Stewards.
##### Budget

##### Description

### Compensation: $190k USD Value
Funding in this category relates to compensation for DAO stewards and secretary.
##### Budget

##### Description
The Working Group Rules passed in [EP12](https://discuss.ens.domains/t/ep12-social-working-group-rules/12953#specification-3) state compensation is permitted for stewards and secretary as set out in Rules 11.1 and 9.4 respectively.
### Unallocated: $71k USD Value
The funds in this category are reserved for unforeseen grants and unexpected expenses for the term. Stewards will distribute unallocated funds on a discretionary basis.

## \[EP2.2.2] \[Executable] Q3 & Q4 2022 Ecosystem WG Budget
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/13757) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x97265786d808280adc788e6744dd07afd3ff7e2776527d18f4e19abe1bd6c1a5) |
*Note: This was previously numbered EP16.2.*
### Summary
The Ecosystem Working Group is requesting funding of 2.3 million USD equivalent for the second term. The budget has four categories. All figures are presented in USD equivalent.

#### Multisigs / Subgroups: $1.5m
Funding in this category is associated with a multisig wallet that has a clearly defined mandate. These multisigs been approved by current stewards of the ENS Ecosystem working group.
Examples of subgroups receiving funding include bug bounty, support mods, dot-eth websites, .limo infrastructure, hackathons, and ENS ecosystem rounds during gitcoin grants rounds.
**Budget**

**Description**

#### RFP Related: $435k
Funding in this category relates to current and future proposals. Potential examples include on-chain normalization, ENS avatar, and future RFPs. Details on the RFP process can be found in this [thread](https://discuss.ens.domains/t/transitioning-the-dao-to-an-rfp-model/11821).

#### Grants: $262k
Funding in this category supports retro-active grants not covered by predefined multi-sigs in the subgroups category. The majority of this funding is expected to be allocated to the prop-house.

#### Unallocated: $109k
The funds in this category are reserved for unexpected needs of the working group over the term.

## \[EP2.2.3] \[Executable] Q3 & Q4 2022 Public Goods WG Budget
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/13759) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x5c96e490f3e28d8269e8fc7e929491fb8fa5e4bd04d3379f0c4f4bb1a42dc23e) |
*Note: This was previously numbered EP16.3.*
### Summary
The Public Goods Working Group is requesting funding of 430,650 USD equivalent for the second term. The budget has five categories. All figures are presented in USD equivalent.

***July 19, 2022. ETH = 1500 USD and ENS = 11.00 USD.***
#### Multisigs / Subgroups: $431k USD Value
Funding for each category is associated with a multisig wallet that has a clearly defined mandate. These multisigs been approved by current stewards of the ENS Public Goods working group.
##### Budget

##### Description
The breakdown of each Multisig/Subgroup is the following. The PG Pod is the main multisig for the Public Goods Working Group.

#### Grants: $173K USD Value
Funding in this category supports grants that will be distributed through two mechanisms for this term. Rapid Grants will be distributed through the ENS DAO small grants platform, adopting the Nouns Prop.House model. Grants may also be funded for retro-active value provided by web3 Public Goods, with Steward approval.
##### Budget

#### Bounties: $113K USD Value
Funding for projects that accomplish certain goals that will be set out in a list of available bounties. Bounties will relate to initiatives and projects for which there is a need that benefits the broader web3 community.
##### Budget

#### Gitcoin GR15 & GR16: $100K USD Value
Funding in this category relates to matching funds provided for the main Gitcoin Grants Rounds over the next six months, GR15 and GR16. This amount is not related to the funding for the ENS Ecosystem Round, which is funded by the Ecosystem Working Group.
##### Budget

#### Unallocated: $45K USD
The funds in this category are reserved for unforeseen grants and unexpected expenses for the term.
##### Budget

## \[EP2.2.4] \[Social] ENS Endaoment RFP
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep2-2-4-social-rfp-ens-endowment/14069) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x4a1aedbd9d22295f358dc4028b5a3f0a602bb5f1089dabdc2b63bf2bcce45834) |
### Overview
The DAO is seeking a fund manager to manage an endowment fund. This fund will be established from some combination of current treasury and ongoing revenue, and will exist to insulate the DAO from economic fluctuations, ensuring it can continue its core operations regardless of the wider economic outlook.
Funds will be drawn from the DAO's general funds, currently held in ETH and USDC, as well as from ongoing DAO revenue until the fund reaches its target size. Proposals should outline how much of the DAO's current funds the intend to appropriate, as well as what proportion of ongoing revenue will be required, and for how long.
The DAO's accounting basis divides assets into earned and unearned income. Unearned income corresponds to funds paid for registrations and renewals that are future-dated; for example, if a user spends $100 to register a name for 20 years, after a year $5 of that will be counted as earned income and the remainder as unearned income.
Unearned income may be incorporated into the fund, but must be risk-neutral with regard to ETH. Earned income should be risk-netural with regard to USDC.
The DAO's current balances can be viewed [here](https://datastudio.google.com/reporting/8785928a-71d5-4b17-9fea-fe1c937b064f); as of this writing they are:
* 13,069 ETH (\~$20M) in earned income
* $3,817,067 USDC
* 18,184 ETH (\~$20M) in unearned income
### Scope of Work
1. Expand the endowment structure specified in the accepted proposal into an executable form.
2. Work with the ENS Meta-Governance stewards to refine the proposal.
3. Implement the proposal onchain.
4. Administer and adjust the endowment as necessary on an ongoing basis.
### Selection Criteria
The endowment will need to be able to sustain annual withdrawals of at least $4M USDC without a long-term reduction in principal.
Proposals should include, at a minimum:
1. Intended high-level fund allocation of the endowment.
2. Initial and target size for the endowment fund, including the proportion of funds sourced from earned and unearned income.
3. How incoming revenues and income will be assigned to the fund.
4. Specific information on how the fund will be managed, and what steps will be taken to minimise custodial risk.
5. A fee schedule for the fund manager.
6. A detailed description of the reporting structures that will be put in place.
Priority will be given to proposals that:
* Minimise custodial risk by using onchain mechanisms that allow administration of the funds without the fund administrator having custody of the funds.
* Lay out a coherent strategy for how investment returns can be maintained in the short/medium/long term.
* Minimise capital risks relative to the expected returns.
* Define clear mechanisms for assessment and adjustment to changing external and internal conditions in order to continue to meet the endowment's objectives.
* Offer a high rate of return proportional to risk.
* Define a clear reporting structure for frequent and comprehensive reporting of the fund's status to the DAO.
### Timeline
| | |
| --------------------- | ------------------------------ |
| **Submission Period** | September 15 - October 10 2022 |
| **Approval Period** | October 10 - November 7 2022 |
### RFP Manager
The Meta-Governance WG stewards are the RFP managers for this RFP.
Proposals can be submitted via forum DM to the stewards. They will be held in confidence until the end of the submission period, at which point all applicants will be invited to post their proposals publicly for feedback on the forum.
Once a winning proposal is selected by the RFP managers, it will be announced and posted publicly.
### Budget
The endowment is expected to be funded out of a combination of capital and performance fees as proposed by the fund manager.
## \[EP2.2.5] \[Social] Selection of an ENS endowment fund manager
::authors
| **Status** | Passed, Karpatkey selected |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15188) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x1ab7ef84f6e904582d5b5b921944b5b1a8e36dbff1f1248fde87fef02b046816) |
### Abstract
Following the RFP process approved in EP2.2.4, the Meta-Governance Working Group stewards have selected a short list of potential fund managers for the DAO to elect to manage the ENS Endowment.
### Specification
EP2.2.4 set out a process for fund managers to submit proposals to the Meta-Governance Working Group for consideration as fund managers over an ENS Endowment. The Endowment's goal is to ensure the long-term viability of ENS by ensuring it can meet its ongoing financial obligations even in the face of reduced ETH price and registration/renewal revenue.
Eight submissions were made as a result of the RFP process, and the stewards have narrowed this down to three finalists. All three finalists are established actors with track records of fund management, and their proposals reflect an understanding of the low-risk, long-term sustainability approach that an endowment should take.
Rather than select a winner themselves, the Meta-Governance Working Group Stewards believe that the selection of a fund manager should be put to the DAO. This EP implements a Snapshot vote using Ranked Choice voting with the following options:
1. Avantgarde
2. Karpatkey
3. Llama
4. None of the above
Submissions for the vote are listed in alphabetical order.
Following the conclusion of the vote, the Meta-Governance Stewards will work with the winning team to develop an initial treasury allocation strategy, resulting in a separate executable proposal to enact the initial setup of the endowment.
#### Submission Summary
The table below summarizes the final submissions made by each candidate.
| Submission | Initial Size | Target Size | Performance Fee | Admin Fee | Breakeven Return |
| -------------------------------------------------------------------------------------------------- | --------------- | ---------------- | --------------- | ----------------- | ---------------- |
| [Avantgarde](https://discuss.ens.domains/t/endaoment-proposal-avantgarde/14800?u=nick.eth) | 25,000 ETH | $100,000,000 USD | 12.5% | 0.5% | 0.57% |
| [Karpatkey](https://discuss.ens.domains/t/endaoment-proposal-karpatkey-steakhouse-financial/14799) | $52,000,000 USD | $69,000,000 USD | 10% | 0.5% | 0.56% |
| [Llama](https://discuss.ens.domains/t/updated-endaoment-proposal-llama-x-alastor/15183) | 30,000 ETH | $80,000,000 USD | 0% | 1% min. $500k USD | 1% - 1.28% |
Breakeven return is calculated as `admin_fee / (1 - performance_fee)`.
## \[EP3.1.1] \[Social] Q1/Q2 2023 Funding Request: ENS Ecosystem Working Group
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15938) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x5788bf0f52ce82a1d3f7750a80f3001671ded49e4e0239dbbafd154275c78f8b) |
### Abstract
The ENS Ecosystem Working Group requests funding of 935,000 USDC and 254 ETH from the ENS DAO for Q1/Q2 2023.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding people and projects that are ENS-specific or ENS-centric. In line with Article III of the ENS DAO Constitution, the requested funds will be used to support projects and builders contributing to the development and improvement of the ENS protocol and the ENS ecosystem.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| ---------------------- | :-----: | :-: | :--: |
| ENS Ecosystem Multisig | 935,000 | 254 | - |
### Description
**ENS Ecosystem Multisig Balance**
The ENS Ecosystem Working Group is requesting 935,000 USDC, 254 ETH, and 0 $ENS.
The ENS Ecosystem Working Group currently has 879,982 USDC, 110 ETH, and 40,936 $ENS in its multisigs.
If this funding request is approved, the ENS Ecosystem Working Group multisigs will have a total of 1,814,982 USDC, 364 ETH, and 40,936 $ENS.
| | USDC | ETH | ENS |
| --------------------------------- | :-----------: | :-----: | :--------: |
| Carried Forward (from Q3/Q4 2022) | 879,982 | 110 | 40,936 |
| Requested (for Q1/Q2 2023) | 935,000 | 254 | 0 |
| **Total Balance** | **1,814,982** | **364** | **40,936** |
**ENS Ecosystem Multisig Allocations for Q1/Q2 2023 (with funding request approved)**
The table below shows the total allocations for the ENS Ecosystem Working Group multisig, and related multisigs, with funds carried forward from last term (Q3/Q4 2022) along with funds requested in this proposal for this term (Q1/Q2 2023).
| | USDC | ETH | $ENS |
| ----------------- | :-----------: | :-----: | :--------: |
| Hackathons | 235,000 | 20 | - |
| Support | 178,000 | 20 | 1,250 |
| Grants | 220,580 | 30 | - |
| Builders | 250,000 | 39 | 2,000 |
| IRL | 84,256 | 10 | 1,000 |
| Merch | 50,967 | 5 | 500 |
| ENS Fairy | 50,000 | 174 | - |
| ENS Fellowship | 60,000 | - | - |
| Layer 2 | 150,000 | - | - |
| Normalization | 50,000 | - | - |
| ETH.Limo | 85,000 | 10 | - |
| Bug Bounty\*\* | 240,000 | - | - |
| Discretionary | 161,179 | 56 | 36,186\*\* |
| **Total Balance** | **1,814,982** | **364** | **40,936** |
\*\* The USDC in the Bug Bounty and the $ENS held by the ENS Ecosystem Working Group multisig is available if needed and will likely be carried forward into future terms.
**Allocation of Requested Funds**
The 935,000 USDC, 254 ETH, and 0 $ENS of funds requested in this proposal will be allocated to the following initiatives/outcomes.
| | USDC | ETH | $ENS |
| ------------------------- | :---------: | :-----: | :---: |
| Hackathons | 230,000 | 10 | - |
| Support | 90,000 | 5 | - |
| Grants | 105,000 | 30 | - |
| Builders | 100,000 | 15 | - |
| IRL | 45,000 | 5 | - |
| Merch | 40,000 | 5 | - |
| ENS Fairy | 50,000 | 174 | - |
| ENS Fellowship | 60,000 | - | - |
| Layer 2 | 105,000 | - | - |
| Normalization | 40,000 | - | - |
| ETH.Limo | 70,000 | 10 | - |
| **Total Requested Funds** | **935,000** | **254** | **-** |
**Description of Initiatives/Pods**
| Initiative/Pod | Description | Multisig Signer or Lead Singer |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------: |
| Hackathons | Sponsorship costs and prize money for hackathons and conferences | luc.computer |
| Support | Support mods for social platforms, technical and non-technical educational and archival content | validator.eth |
| Grants | Small grants funding for ENS proposals on ensgrants.xyz + evergreen integration bounties | Ecosystem stewards |
| Builders | Support for builders shipping code that improves ENS | Ecosystem stewards |
| IRL | Funding In Real Life events that coincide with the existing Ethereum event schedule + funding IRL community meetups | limes.eth |
| Merch | Subsidizing the cost of creating and shipping physical ENS merchandise including shirts, hats, and pins | Ecosystem stewards |
| ENS Fairy | Funds continued development of ensfairy.xyz + acquisition by validator.eth of names on temporary premium that can be utilized to grow ENS adoption + funding the ENS fairy registration bot to gift .eth names to IRL community members and builders | validator.eth |
| ENS Fellowship | Supports exceptional developers actively creating and contributing to the ENS ecosystem with a 6 month Fellowship | Ecosystem stewards |
| Layer 2 | Development of ENS Layer 2 solutions | Ecosystem stewards |
| Discretionary | Funds in the Ecosystem Working Group multisig that are utilized at the discretion of stewards | Ecosystem stewards |
This proposal was prepared by Slobo.eth, lead steward of the ENS Ecosystem Working Group.
## \[EP3.1.2] \[Social] Q1/Q2 2023 Funding Request: Meta-Governance Working Group
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15940) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0xd7eff781be059513b5cd64d79e709abbbc653944c9a8c621dc051e7b42a405cb) |
### Abstract
The Meta-Governance Working Group requests funding of 364,000 USDC, 125 ETH, and 3,500 $ENS from the ENS DAO for Q1/Q2 2023.
This funding will be used to support the governance processes of the ENS DAO as well as manage and build infrastructure to support the ENS DAO and Working Groups.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| ------------------------ | :-----: | :-: | :---: |
| Meta-Governance Multisig | 364,000 | 125 | 3,500 |
### Description
**Meta-Governance Multisig Balance**
The Meta-Governance Working Group is requesting 364,000 USDC, 125 ETH, and 3,500 $ENS.
The Meta-Governance Working Group currently has 217,510 USDC, 17 ETH, and 8,940 $ENS in its multi-sigs.
If this funding request is approved, the Meta-Governance Working Group multi-sigs will have a total of 581,510 USDC, 142 ETH, and 12,440 $ENS.
| | USDC | ETH | $ENS |
| --------------------------------- | ----------- | ------- | ---------- |
| Carried Forward (from Q3/Q4 2022) | 217,510 | 17 | 8,940 |
| Requested (for Q1/Q2 2023) | 364,000 | 125 | 3,500 |
| **Total Balance** | **581,510** | **142** | **12,440** |
**MetaGovernance Multisig Allocations for Q1/Q2 2023 (with funding request approved)**
The table below shows the total allocations for the MetaGovernance Working Group multi-sig, and related pods, with funds carried forward from last term (Q3/Q4 2022) along with funds requested in this proposal for this term (Q1/Q2 2023).
| | USDC | ETH | $ENS |
| -------------------------------- | ----------- | ------- | ---------- |
| Steward + Secretary Compensation | 184,000 | - | 3,500 |
| Governance | 88,500 | 32 | 1,250 |
| DAO Tooling | 171,000 | 60 | 3,000 |
| DAO Sponsorship | 60,000 | 10 | - |
| Discretionary | 78,010 | 40 | 4,690 |
| **Total Balance** | **581,510** | **142** | **12,440** |
**Allocation of Requested Funds**
The 364,000 USDC, 125 ETH, and 3,500 $ENS of funds requested in this proposal will be allocated to the following initiatives/outcomes.
| | USDC | ETH | $ENS |
| -------------------------------- | ----------- | ------- | --------- |
| Steward + Secretary Compensation | 184,000 | - | 3,500 |
| Governance | 40,000 | 30 | - |
| DAO Tooling | 80,000 | 50 | - |
| DAO Sponsorship | 60,000 | 10 | - |
| Discretionary | - | 35 | - |
| **Total Requested Funds** | **364,000** | **125** | **3,500** |
**Description of Initiatives/Pods**
| Initiative/Pod | Description | Multisig Signers or Lead Signer |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| Steward + Secretary Compensation | Working Group Steward compensation totaling $144k USDC + 3,000 $ENS plus Secretary compensation of $40k USDC | MetaGov stewards |
| Governance | Fee reimbursements and initiatives related to reducing friction in the governance process | MetaGov stewards |
| DAO Tooling | Developing interfaces and dashboards to improve the governance process and increase transparency across the DAO | alisha.eth |
| DAO Sponsorship | Sponsoring DAO-specific events such as DAO NYC, DAO Tokyo, and Aragon's DAO Global Hackathon | MetaGov stewards |
| Discretionary | Funds distributed at the discretion of stewards towards new initiatives + governance experiments | MetaGov stewards |
This proposal was prepared by Katherine Wu, lead steward of the MetaGovernance Working Group.
## \[EP3.1.3] \[Social] Q1/Q2 2023 Funding Request: Public Goods Working Group
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15941) |
| **Votes** | [Snapshot](https://snapshot.org/#/ens.eth/proposal/0x41b3509b88e15677aa15680f48278517f794822fb9a79b9c621def53f1866be7) |
### Abstract
The Public Goods Working Group requests funding of 250,000 USDC and 50 ETH from the ENS DAO for Q1/Q2 2023.
This funding will be used to support projects and builders as provisioned by Article III of the ENS DAO Constitution, which provides for the funding of public goods in web3.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| --------------------- | :-----: | :-: | :--: |
| Public Goods Multisig | 250,000 | 50 | - |
### Description
**Public Goods Multisig Balance**
The Public Goods Working Group is requesting 250,000 USDC, 50 ETH, and 0 $ENS.
The Public Goods Working Group currently has 146,548 USDC, 75 ETH, and 200 $ENS in its multisigs.
If this funding request is approved, the Public Goods Working Group multisigs will have a total of 396,548 USDC, 125 ETH, and 200 $ENS.
| | USDC | ETH | $ENS |
| --------------------------------- | ----------- | ------- | ------- |
| Carried Forward (from Q3/Q4 2022) | 146,548 | 75 | 200 |
| Requested (for Q1/Q2 2023) | 250,000 | 50 | 0 |
| **Total Balance** | **396,548** | **125** | **200** |
**Public Goods Multisig Allocations for Q1/Q2 2023 (with funding request approved)**
The table below shows the total allocations for the Public Goods Working Group multisig, and related pods, with funds carried forward from last term (Q3/Q4 2022) along with funds requested in this proposal for this term (Q1/Q2 2023).
| | USDC | ETH | $ENS |
| ----------------- | ----------- | ------- | ------- |
| Small Grants | - | 50 | - |
| Gitcoin Grants | 100,000 | - | - |
| Rapid Grants | 50,000 | 10 | - |
| Large Grants | 200,000 | 50 | - |
| Discretionary | 46,548 | 15 | 200 |
| **Total Balance** | **396,548** | **125** | **200** |
**Allocation of Requested Funds**
The 250,000 USDC and 50 ETH will be allocated to the following initiatives/outcomes.
| | USDC | ETH | $ENS |
| ------------------------- | ----------- | ------ | ----- |
| Small Grants | - | 40 | - |
| Gitcoin Grants | 50,000 | - | - |
| Rapid Grants | 50,000 | 10 | - |
| Large Grants | 150,000 | - | - |
| Discretionary | - | - | - |
| **Total Requested Funds** | **250,000** | **50** | **-** |
**Description of Initiatives/Pods**
| Initiative/Pod | Description | Multisig Signer |
| -------------- | --------------------------------------------------------------------------------------------------- | --------------------- |
| Small Grants | ETH for the top Public Goods proposals submitted to ensgrants.xyz | Public Goods stewards |
| Gitcoin Grants | Support for Open Source and Ethereum Infrastructure rounds by Gitcoin through their grants protocol | Public Goods stewards |
| Rapid Grants | Grants up to $10k each for web3 public goods | Public Goods stewards |
| Large Grants | Grants up to $100k each for web3 public goods | Public Goods stewards |
| Discretionary | Funds distributed at the discretion of stewards towards new initiatives + public goods experiments | Public Goods stewards |
This proposal was prepared by Coltron.eth, lead steward of the Public Goods Working Group.
## \[EP3.2] \[Executable] April 2023 Working Group Funding
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/16123) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/105292919185331921858643224173178583901390266903267892669205105842869373522526) |
### Abstract
This proposal executes all three Working Group funding requests for Q1/Q2 2023 as passed in EP 3.1.1, EP 3.1.2, and EP 3.1.3. For more detail, view the [ENS Governance docs](https://docs.ens.domains/v/governance/governance-proposals/term-3) or view the links below.
### Motivation
[**EP 3.1.1 — ENS Ecosystem Working Group**](https://docs.ens.domains/v/governance/governance-proposals/term-3/ep3.1.1-social-q1-q2-2023-funding-request-ens-ecosystem-working-group)
The ENS Ecosystem Working Group requests funding of 935,000 USDC and 254 ETH from the ENS DAO for Q1/Q2 2023.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding people and projects that are ENS-specific or ENS-centric. In line with Article III of the ENS DAO Constitution, the requested funds will be used to support projects and builders contributing to the development and improvement of the ENS protocol and the ENS ecosystem.
[**EP 3.1.2 — MetaGovernance Working Group**](https://docs.ens.domains/v/governance/governance-proposals/term-3/ep3.1.2-social-q1-q2-2023-funding-request-meta-governance-working-group)
The Meta-Governance Working Group requests funding of 364,000 USDC, 125 ETH, and 3,500 $ENS from the ENS DAO for Q1/Q2 2023.
This MetaGovernance Working Group will use this funding to support the governance processes of the ENS DAO as well as manage and build infrastructure to support the ENS DAO and Working Groups.
[**EP 3.1.3 — Public Goods Working Group**](https://docs.ens.domains/v/governance/governance-proposals/term-3/ep3.1.3-social-q1-q2-2023-funding-request-public-goods-working-group)
The Public Goods Working Group requests funding of 250,000 USDC and 50 ETH from the ENS DAO for Q1/Q2 2023.
The Public Goods Working Group will be use this funding to support projects and builders as provisioned by Article III of the ENS DAO Constitution, which provides for the funding of public goods in web3.
### Specification
1. Transfer 935,000 USDC and 254 ETH to ens-ecosystem.pod.xyz
2. Transfer 364,000 USDC, 125 ETH, and 3,500 $ENS to ens-metagov.pod.xyz
3. Transfer 250,000 USDC and 50 ETH to ens-publicgoods.pod.xyz
**Addresses:**
* 0x2686A8919Df194aA7673244549E68D42C1685d03 - ens-ecosystem.pod.xyz
* 0x91c32893216dE3eA0a55ABb9851f581d4503d39b - ens-metagov.pod.xyz
* 0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d - ens-publicgoods.pod.xyz
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ------- | -------- | -------- | ----------------------- |
| ens-ecosystem.pod.xyz | 254 ETH | | | |
| ens-metagov.pod.xyz | 125 ETH | | | |
| ens-publicgoods.pod.xyz | 50 ETH | | | |
| 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | | transfer | to | ens-ecosystem.pod.xyz |
| | | | value | 935000000000 |
| 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | | transfer | to | ens-metagov.pod.xyz |
| | | | value | 364000000000 |
| 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | | transfer | to | ens-publicgoods.pod.xyz |
| | | | value | 250000000000 |
| 0xc18360217d8f7ab5e7c516566761ea12ce7f9d72 | | transfer | to | ens-metagov.pod.xyz |
| | | | value | 3500000000000000000000 |
## \[EP3.3] \[Executable] Sell ETH to USDC
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15906) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/45461903078948131870051132081249892009497709518413744958551889217805827301425) |
### Abstract
This proposal executes a swap of 10,000 ETH into USDC, to ensure ENS DAO has enough to cover operating expenses for 18 - 24 months.
### Motivation
The DAO currently keeps almost 100% of its spendable treasury in ETH. While ENS generates protocol revenue in ETH, having so much exposure to a single volatile asset places the DAO in a vulnerable position.
This is a proposal to convert 10,000 ETH into USDC through a Cowswap swap.
10,000 ETH is approximately 25% of the total amount of ETH held by the ENS DAO (wallet.ensdao.eth) and register controller (controller.ens.eth) as of January 18, 2023.
It is hoped that this sale will generate in excess of $13m in USDC. The goal is to ensure that the DAO has enough USDC to cover operations for the next 18 - 24 months.
### Specification
1. Call `withdraw()` on controller.ens.eth (0x283af0b28c62c092c9727f1ee09c02ca627eb7f5)
2. Call `deposit()` on WETH9 (0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), sending 10,000 ETH
3. Call `approve(, 10000 ETH)` on WETH9 (0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)
4. Call `requestSwapExactTokensForTokens(10000 ETH, , , wallet.ensdao.eth, , )` on milkman (0x11C76AD590ABDFFCD980afEC9ad951B160F02797)
Price checker data is configured to check the swap against the Uniswap v3 pool and limit to 2% slippage. It is generated using the below code:
```javascript
import { ethers } from 'https://cdn.ethers.io/lib/ethers-5.2.esm.min.js'
function getCheckerData(slippage, path, fees) {
return ethers.utils.defaultAbiCoder.encode(
['uint256', 'bytes'],
[
slippage,
ethers.utils.defaultAbiCoder.encode(
['address[]', 'uint24[]'],
[path, fees]
),
]
)
}
const checkerData = getCheckerData(
200,
[
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
],
[5]
)
console.log('checkerData:', checkerData)
```
**Addresses:**
* 0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7 - wallet.ensdao.eth
* 0x283af0b28c62c092c9727f1ee09c02ca627eb7f5 - controller.ens.eth
* 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - WETH9
* 0x11C76AD590ABDFFCD980afEC9ad951B160F02797 - milkman
* 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 - USDC
* 0x2F965935f93718bB66d53a37a97080785657f0AC - Uniswap v3 slippage checker
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | --------- | ------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5 | - | withdraw | | |
| 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 | 10000 ETH | deposit | | |
| 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 | - | approve | guy | 0x11C76AD590ABDFFCD980afEC9ad951B160F02797 |
| | | | wad | 10000000000000000000000 |
| 0x11C76AD590ABDFFCD980afEC9ad951B160F02797 | - | requestSwapExactTokensForTokens | amountIn | 10000000000000000000000 |
| | | | fromToken | 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 |
| | | | toToken | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
| | | | to | 0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7 |
| | | | priceChecker | 0x2F965935f93718bB66d53a37a97080785657f0AC |
| | | | priceCheckerData | 0x00000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005 |
## \[EP 3.4] \[Executable] Fund the Endowment (first tranche)
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/15952) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/90786656233306599444783442367171420493182391933134906270328139870999449830964) |
### Abstract
First tranche to fund the Endowment with 16,000 ETH sent from [ENS DAO](https://etherscan.io/address/0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7) to the [ENS Endowment](https://etherscan.io/address/0x4F2083f5fBede34C2714aFfb3105539775f7FE64) and an additional 150 ETH sent to the [Meta-Gov Pod](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) to account for karpatkey and Steakhouse monthly fees.
### Motivation
[Approximately one year ago](https://discuss.ens.domains/t/an-ens-endaoment/11756), the ENS DAO initiated a process to ensure the sustainability of ENS as a self-funded public good for the long term. The [RFP process](https://discuss.ens.domains/t/ep2-2-4-social-rfp-ens-endowment/14069) (EP2.2.4), on which [karpatkey, together with Steakhouse, made a proposal](https://discuss.ens.domains/t/updated-endaoment-proposal-karpatkey-steakhouse-financial/14799), resulted in the [selection of karpatkey](https://discuss.ens.domains/t/social-ep2-2-5-selection-of-an-ens-endowment-fund-manager/15188) (EP2.2.5).
For reference, the proposal submitted by karpatkey was for an initial size of $52,000,000 USD (converted to 32,000 ETH for operational purposes as the Endowment will be founded in ETH and to account for the reduction of the pool according to [EP3.3](https://discuss.ens.domains/t/ep3-3-executable-sell-eth-into-usdc/15906)). The proposal included performance fees of 10% above the investment's reference currency, with $ for $-related investments and ETH for ETH-related investments, as well as an annual fee of 0.5% based on the size of the endowment, payable entirely in ETH on a monthly basis.
Karpatkey engaged in discussions with the ENS community to seek feedback on strategies and the ramp-up process, both [here](https://discuss.ens.domains/t/social-endowment-initial-conditions-required-steps/15684) and [here](https://discuss.ens.domains/t/endowment-initiation/15952). Feedback was received regarding concerns about the required time to establish trust and the need to limit executive votes for funding. Karpatkey believes that a balanced approach, such as funding 50% on day one and the remaining 50% after six months, would be a suitable tradeoff for all parties. To address questions and concerns raised, a [FAQ](https://discuss.ens.domains/t/endowment-frequently-asked-questions-faq/16228) was provided.
In the meantime, karpatkey made progress on the setup of [the Endowment safe](https://etherscan.io/address/0x4F2083f5fBede34C2714aFfb3105539775f7FE64), which has been seeded to display target positions. The necessary [managing permissions](https://docs.google.com/document/d/11xrliJIveXO6C6twYOrnGJ5QUW0Apr1LCcDY8hOfpuo/edit) have been defined and audits from [Ackee](https://github.com/gnosis/zodiac-modifier-roles/blob/main/packages/evm/docs/ZodiacModifierRolesJanuary2023abch.pdf) and [Sub 7](https://github.com/gnosis/zodiac-modifier-roles/blob/main/packages/evm/docs/ZodiacModifierRolesJanuary2023sub7.pdf) have been completed. On its part, Steakhouse has started work on providing open source [accounting and financial services](https://docs.google.com/document/d/1xS4nXx1G0QCjFS-VdG5yVmVoMa5t1q9_dFZ9N4wGSJ8/edit?usp=sharing), as well as a [monitoring Dune dashboard](https://dune.com/steakhouse/ens-steakhouse), both of which are work in progress.
If the Endowment is funded through this first tranche, karpatkey will allocate the funds as follows:
| # | Protocol | Assets | Strategy | Share per Strat | Allocated Funds | Share of Portfolio | Proj. APR | Proj. Rev | Pool TVL (MM) |
| - | --------------------- | -------------------------------- | ------------- | --------------- | --------------- | ------------------ | --------- | -------------- | ------------------- |
| 1 | Compound v2 | DAI | USD - neutral | 50% | $5,506,971 | 20.61% | 2.21% | $121,704 | $560 |
| 2 | Compound v2 | USDC | USD - neutral | 50% | $5,506,971 | 20.61% | 2.16% | $118,951 | $637 |
| 3 | Aura Finance | wstETH - WETH | ETH - neutral | 40% | $6,282,423 | 23.51% | 10.38% | $652,116 | $208 |
| 4 | Curve | stETH - ETH | ETH - neutral | 40% | $6,282,423 | 23.51% | 5.38% | $337,994 | $1,653 |
| 5 | Stakewise/ Uniswap v3 | sETH2 - ETH Range: 1.000 - 1.006 | ETH - neutral | 20% | $3,141,212 | 11.76% | 12.77% | $401,133 | $65 |
| | **Total** | | | | **$26,720,000** | **100.00%** | **6.11%** | **$1,631,897** | |
### Specification
1. Transfer 16,000 ETH to the Endowment (0x4F2083f5fBede34C2714aFfb3105539775f7FE64)
2. Transfer 150 ETH to ens-metagov.pod.xyz (0x91c32893216dE3eA0a55ABb9851f581d4503d39b) to cover Endowment fees for Q1/Q2
Addresses:
* 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7 - ENS DAO
* 0x4F2083f5fBede34C2714aFfb3105539775f7FE64 - endowment
* 0x91c32893216dE3eA0a55ABb9851f581d4503d39b - ens-metagov.pod.xyz
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ---------- | -------- | -------- | ----- |
| 0x4F2083f5fBede34C2714aFfb3105539775f7FE64 | 16,000 ETH | | | |
| 0x91c32893216dE3eA0a55ABb9851f581d4503d39b | 150 ETH | | | |
## \[EP3.5] \[Executable] Activate new .eth Controller and Reverse Registrar
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/16776) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/42973781582803845389836855775840822719678533376883030929209752909248937768242) |
### Abstract
With the new Name Wrapper, we will add a new .eth controller that allows registering wrapped names directly as well as registering with multiple records and adding a reverse record in 1 transaction. This will reduce the transactions required from 4 to 2 (for adding records + reverse). This will be added as a controller to the NameWrapper, and the NameWrapper will be added as the new controller of the existing .eth Base Registrar.
We will also replace the current reverse registrar with a new reverse registrar which allows the new controller to set the reverse on registration, as well as adds support for the owner of contract to retrospectively claim their reverse node.
### Specification
New instances of the Name Wrapper, Reverse Registrar, and .eth registrar controller have been deployed to mainnet at these addresses:
* NameWrapper: `0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401`
* ReverseRegistrar: `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`
* ETHRegistrarController: `0x253553366Da8546fC250F225fe3d25d0C782303b`
* PublicResolver: `0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63`
They have been configured, and ownership has been transferred to the DAO.The new Public Resolver is set as the default resolver on the reverse registrar.
This executable proposal will execute the following calls to complete the contract upgrades:
1. Call `registrar.addController(newNameWrapperAddress)`
2. Call `ens.setSubnodeOwner(namehash('reverse'), labelhash('addr'), newReverseRegistrarAddress)`
3. Call `setInterface` on the resolver for .eth with the interface IDs and contract addresses of the new .eth registrar controller and namewrapper. This is used as part of the discovery mechanism by the ENS manager app and others in order to locate the new contracts.
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ----- | --------------- | ----------- | ------------------------------------------------------------------ |
| 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85 | | addController | controller | 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401 |
| 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e | | setSubnodeOwner | node | 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34 |
| | | | labelhash | 0xe5e14487b78f85faa6e1808e89246cf57dd34831548ff2e6097380d98db2504a |
| | | | owner | 0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb |
| 0x30200e0cb040f38e474e53ef437c95a1be723b2b | | setInterface | node | 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae |
| | | | interfaceId | 0x019a38fe |
| | | | implementer | 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401 |
| 0x30200e0cb040f38e474e53ef437c95a1be723b2b | | setInterface | node | 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae |
| | | | interfaceId | 0x612e8c09 |
| | | | implementer | 0x253553366Da8546fC250F225fe3d25d0C782303b |
## \[EP3.6] \[Social] Election of new ENS Foundation director
::authors
| **Status** | Passed (elected: Alex Van de Sande) |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/17008) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x3c6b192eb2e990d74125d82ef886a1ec9e7373f4f768ed5b4adc23a03c26d649) |
### Abstract
This is a vote to elect a new director of the ENS Foundation.
### Motivation
Brantly Millegan has [communicated](https://discuss.ens.domains/t/resignation-from-the-ens-foundation-effective-upon-the-election-of-a-replacement/16676) that he would like to resign as a director of the ENS Foundation. Brantly's resignation will take effect following the appointment of a new director by the DAO.
The DAO may appoint a new director of the ENS Foundation pursuant to Article 15 of the Articles of Association of the ENS Foundation.
### Specification
The DAO will vote to appoint one new director of the ENS Foundation.
Two candidates are seeking election after successfully completing the requirements outlined in the ['Call for Nominees' post](https://discuss.ens.domains/t/call-for-nominees-ens-foundation-director/16858) on the ENS Governance forum.
The candidates seeking election are:
1. Sean Murray
2. Alex Van de Sande
The candidate with the highest number of votes above quorum will be appointed as a director of the ENS Foundation following the completion of mandatory KYC checks.
#### Voting
This vote is a single choice vote. You may vote for one of the following options:
1. Sean Murray
2. Alex Van de Sande
3. None of the above
4. Abstain
By voting for a named candidate, you are voting in favor of appointing that candidate as a director of the ENS Foundation.
### Candidates
#### Sean Murray
**Twitter**: [@financeguy74](https://twitter.com/financeguy74) \
**Are you 18 years of age or older?** Yes \
**Are you a U.S citizen or permanent resident?** Yes \
**Do you live in the U.S or one of its territories?** Yes
**Why should you be appointed as a director of the ENS Foundation?** \
I am capable of fulfilling the required duties but also beyond that I would use it as a platform to increase mainstream ENS adoption.
**How would you handle a request from the SEC for information about the ENS Foundation and/or the $ENS token?** \
This is an incomplete question because it does not specify who "you" is. If an SEC inquiry is addressed only to the Foundation itself, the correct answer is that the Foundation retain counsel and that counsel manage the inquiry. Should the definition of "you" be more broad, then any rational person should find my conditions stated below rational, reasonable, and necessary. They should be put in place regardless of who is chosen.
**Is there any other information you would like delegates to know about you or your nomination?** \
Yes, if by chance I am selected, my acceptance of the role is conditional on:
* The DAO authorizing the Foundation to set up D\&O insurance;
* The DAO authorizing the Foundation to compensate directors.
#### Alex Van de Sande
**Twitter**: [@avsa](https://twitter.com/avsa) \
**Are you 18 years of age or older?** Yes \
**Are you a U.S citizen or permanent resident?** No \
**Do you live in the U.S or one of its territories?** No
**Why should you be appointed as a director of the ENS Foundation?** \
I won't lie: I believe this role is purely ceremonial and believe that as long as everything is working as intended, Directors should do nothing but rubberstamp what the DAO approves. But as a symbol, I do think it's important for the Directors not to be all from ENS Labs, nor for them to be in any jurisdiction that is not welcome to Crypto - and at this moment, the US is such jurisdiction.
So that's it, that's the whole of my pitch: I do not work for ENS labs, I do not respond to them, nor do I am subject to US jurisdiction. I also have been in this space for the last 10 years and you can expect me to be around in the next 10 years.
**How would you handle a request from the SEC for information about the ENS Foundation and/or the $ENS token?** \
I am not not subject to American laws, but that doesn't mean I intend to break any of them, as I still intend to keep the privilege of landing in US soil. I still believe the US to be a reasonable thriving democracy that is just right now a bit on the wrong side of the pendulum. I also believe that the ENS airdrop was a great precedent on how to do token distribution to the community: no "investor" ever received it in the airdrop, because there were no investors in ENS before the airdrop. All that received them were either involved in the community or the development.
If I ever received a request from the SEC of any other legal institutions from anywhere I would take the reasonable route: talk to my lawyer, open it with as much as possible with the community and, in an extreme case in which I believed I the requests would hurt ENS and I couldn't be open to talk about it, I would resign from the foundation.
**Is there any other information you would like delegates to know about you or your nomination?** \
I am not Dutch either, despite a lot of people seemingly believing it so.
## \[EP3.7] \[Social] Approval of ENS Name Normalization Standard (ENSIP-15)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/16957) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xed7bbde7c1136cbb5b9090a0abd48438c97a020b9e8a1e8f6257a46d068aa2e0) |
### Abstract
This is a vote to approve [ENSIP-15: Normalization Standard.](https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard)
### Motivation
#### EP3.7 Motivation
* Normalization isn't enforced on-chain.
* There is no code for the DAO to execute.
* Approval for ENSIP-15 should be confirmed through a social vote.
#### ENSIP-15 Motivation
* Since [ENSIP-1](https://github.com/ensdomains/governance-docs/blob/8e2e6c98198dd31fd2e982987e286fd6ce540319/governance-proposals/ensip-1-ens.md) (originally [EIP-137](https://eips.ethereum.org/EIPS/eip-137)) was finalized in 2016, Unicode has [evolved](https://unicode.org/history/publicationdates.html) from version 8.0.0 to 15.0.0 and incorporated many new characters, including complex emoji sequences.
* ENSIP-1 does not state the version of Unicode.
* ENSIP-1 implies but does not state an explicit flavor of IDNA processing.
* [UTS-46](https://unicode.org/reports/tr46/) is insufficient to normalize emoji sequences. Correct emoji processing is only possible with [UTS-51](https://www.unicode.org/reports/tr51/).
* Validation tests are needed to ensure implementation compliance.
* The success of ENS has encouraged spoofing via the following techniques:
1. Insertion of zero-width characters.
2. Using names which normalize differently between algorithms.
3. Using names which appear differently between applications and devices.
4. Substitution of confusable (look-alike) characters.
5. Mixing incompatible scripts.
### Specification
* Replace [ENSIP-1 § Name Syntax](https://docs.ens.domains/ens-improvement-proposals/ensip-1-ens#name-syntax) "UTS-46 algorithm" with link to [ENSIP-15](https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard).
* Agree to normalize names according to ENSIP-15 for a safer end-user experience.
* Examples:
1. 
2. 
3. 
* Libraries implementing ENSIP-15:
1. Javascript — [adraffy/ens-normalize](https://github.com/adraffy/ens-normalize.js)
2. Javascript — [ensdomains/eth-ens-namehash](https://github.com/ensdomains/eth-ens-namehash)
3. Python — [namehash/ens-normalize-python](https://github.com/namehash/ens-normalize-python)
* Web Frameworks using ENSIP-15:
1. Javascript — [ethers/ethers.io](https://github.com/ethers-io/ethers.js/)
2. Javascript — [web3/web3.js](https://github.com/web3/web3.js)
3. Javascript — [wagmi-dev/viem](https://github.com/wagmi-dev/viem)
* Names visible to the end-user should be [**beautified**](https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard#annex-beautification) for a more consistent appearance.
* Example: These labels are the same:\
[](https://camo.githubusercontent.com/1b7b4f3d0baa83d62415760a4622955e6de1f8f102a8ea5070e21ae0d44ab9ea/68747470733a2f2f692e696d6775722e636f6d2f703772785572452e706e67)
### Voting
This vote is a single choice vote. You may vote for one of the following options:
* **For**
* **Against**
* **Abstain**
By voting **For** this proposal, you are voting in favor of approving [ENSIP-15](https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard).
## \[EP4.1] \[Executable] Approve further actions and strategies for the Endowment
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/17406) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/55447465396737793905646186593156244424717001140618132725073945884287085787959) |
### Abstract
This proposal introduces additional actions and strategies to the [ENS Endowment](https://discuss.ens.domains/t/ep3-4-executable-fund-the-endowment-first-tranche/16277?u=alisha.eth), which enhance the Endowment's performance, adaptability, and diversification.
### Motivation
Permissions granted to Karpatkey to manage the Endowment are not static, and require regular updates to effectively respond to evolving market conditions and to capitalize on emerging opportunities.
Any changes to the permissions related to Endowment funds ([endowment.ensdao.eth](https://etherscan.io/address/0x4F2083f5fBede34C2714aFfb3105539775f7FE64)) must be executed by the DAO. To streamline the process for delegates, Karpatkey has bundled all non-urgent changes in this proposal.
#### Endowment Update
The latest weekly report shows that the Endowment's ncAUM (non-custodial Assets Under Management) amount is $30.1M, with a capital utilisation of 99.95% and an APR (Annual Percentage Rate) of 2.78%.
Weekly updates on the Endowment can be found in the ENS governance forum [here](https://discuss.ens.domains/t/endowment-weekly-reports/16665?u=alisha.eth). Monthly updates can be found in the ENS governance forum [here](https://discuss.ens.domains/t/ens-financial-reporting-by-steakhouse/16601?u=alisha.eth).
### Specification
Permissions that will be added in this proposal are:
1. Deposit USDC on Compound v3;
2. Deposit DAI on AAVE v3;
3. Deposit USDC on AAVE v3;
4. Deposit DAI on Maker's DSR module;
5. Deposit wstETH - ETH on Balancer;
6. Stake ETH - stETH on Convex;
7. Deposit and stake rETH - WETH on Balancer;
8. Stake rETH - WETH on Aura;
9. Deposit and stake Compound USDC DAI on Curve;
10. Stake Compound USDC DAI on Convex;
11. Deposit and stake Balancer Boosted Aave V3 USD on Balancer;
12. Stake Balancer Boosted Aave V3 USD on Aura;
13. Add swap route CVX - WETH on Curve;
14. Migrate wstETH-WETH position to a new gauge on Aura,
15. Add swap route processor for SushiSwap's concentrated liquidity (v3) pools, and
16. Add swapping options on Cow Swap
The majority of the actions mentioned above were initially presented in the proposal that resulted in the selection of Karpatkey as the Endowment Manager. However, it is important to note that there is one exception, namely action #4 - Deposit DAI on Maker's DSR module. This particular opportunity has emerged as an appealing addition subsequent to the original proposal, presenting a new avenue that was not available at the time of its submission. More details about the new actions are posted below as a comment to this post.
Moving forward, this initial list of actions will be subject to updates based on future market conditions, ensuring the Endowment remains responsive and adaptable.
#### Additional information
We propose an updated version of the "Preset permissions - ENS Endowment" [document](https://docs.google.com/document/d/1ccSDe25I9ojvlbPGT5acqD71LOY9U8xkjBYWJgjJtgI/edit?usp=sharing) that shows all the permissions granted to Karpatkey, including the ones that are being requested now.
The payload to update the preset that needs to be executed by the ENS DAO upon a successful on-chain vote is posted below as a comment to this post along with some additional considerations.
## \[EP4.10] \[Social] Transfer ENS Root Key Ownership to the ENS DAO
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/18338) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x8e3c8812bd52d1760eb2bbf8dc603d68860741f80d489dc051017e863151a242) |
### Abstract
The ENS DAO has established itself as the key governance entity for the Ethereum Name Service (ENS) and has demonstrated capability and responsibility in ownership of several aspects of the protocol. We now propose the further decentralization of the ENS governance structure by transferring ownership of the ENS root key from the current multisig system (multisig.ens.eth) to the ENS DAO (wallet.ensdao.eth).
### Background
#### ENS Root Key
The ENS root node is currently owned by a multisig contract. The root key can control the allocation and replacement of all TLDs except for .eth. Keyholders are well-respected individuals in the Ethereum community and, with the exception of Nick Johnson, founder of ENS, are unaffiliated with ENS. While the .eth registrar contract control has been locked and cannot be affected by the root keyholders, they still hold significant powers over the structure and functioning of the ENS Protocol.
#### ENS DAO Current Powers
The ENS DAO holds ownership of the .eth registrar and has control over functionalities like the NameWrapper. The DAO does not have control over the core ENS root name, which retains the capability to create new TLDs, adjust controls for existing ones, and upgrade the contracts responsible for reverse resolution.
### Proposal
1. **Transfer of Root Key Ownership**: We propose the transfer of ownership of the ENS root key from the current multisig holders to the ENS DAO. This will consolidate governance powers and further the vision of decentralized control over the ENS Protocol.
2. **TLD Management**: While .eth is permanently set and unchangeable, the DAO will inherit the power to create and manage other top-level domains (TLD). The DAO will also have the ability to lock any TLD permanently if deemed necessary.
3. **Reverse Resolutions and L2s**: The DAO will have the capacity to update reverse resolutions. Additionally, with the Labs team's support, the DAO will explore and potentially implement primary domain names on Layer 2 solutions (L2s).
### Specification
1. Current ENS root keyholders are requested to execute a transaction transferring root key ownership to the ENS DAO's designated contract.
2. The ENS DAO commits to managing the new powers and funds in line with the [ENS DAO Constitution](/dao/constitution), ensuring transparent governance and decision-making.
3. The DAO will develop policies to govern TLD management, (oracle) pricing updates, and other key decisions.
### Coda (Conclusion)
With this proposal, we aim to further decentralize the control and governance of the ENS Protocol, placing more trust and power in the hands of the ENS community via the DAO. Community discussion will ensue on the [Governance Forum](https://discuss.ens.domains). The ballot will begin on [Snapshot](https://snapshot.org/#/ens.eth) and, should it be passed, the current ENS root keyholders will initiate a transfer of the ENS root key to the ENS DAO where it will be managed according to the precepts outlined herein.
## \[EP4.2] \[Executable] Fund the Endowment (second tranche)
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/17743) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/10686228418271748393758532071249002330319730525037728746406757788787068261444) |
### Abstract
This proposal outlines the allocation of the second tranche, comprising 16,000 ETH, from the [ENS DAO](https://etherscan.io/address/0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7) to the [ENS Endowment](https://etherscan.io/address/0x4F2083f5fBede34C2714aFfb3105539775f7FE64). Additionally, it introduces minor adjustments to the existing permissions preset for maintenance purposes.
### Motivation
In March 2023, the ENS Endowment was formally established following the [joint proposal](https://discuss.ens.domains/t/updated-endaoment-proposal-karpatkey-steakhouse-financial/14799) by karpatkey and @steakhouse, after the successful execution of [E.P 3.4 - Fund the Endowment (first tranche)](https://www.tally.xyz/gov/ens/proposal/90786656233306599444783442367171420493182391933134906270328139870999449830964). The community had expressed a preference for a phased funding approach, leading to the decision to allocate the funds in two equal tranches over a six-month interval. As we reach this pivotal milestone, this proposal seeks community approval for the second tranche.
#### Endowment Update
Based on the most recent monthly report detailing the Endowment's performance for August 2023, the Endowment has achieved:
* $28.03 M of ncAUM (non-custodial assets under management)
* 100% of capital utilisation
* An APY (annual percentage yield) of 4.1%
* Monthly farming results of $93,841
A comprehensive review [post](https://discuss.ens.domains/t/karpatkey-h1-2023-review-for-the-ens-endowment/17682) detailing our collaborative efforts with the ENS DAO has been recently shared on the forum. We encourage community members to consult this post for insights into our achievements and ongoing initiatives.
##### Cumulative Revenues
In the 182 days since the Endowment was established, 173 ETH have been accrued through ETH-neutral strategies and $136,764 in stablecoin revenues via USD-neutral strategies. Operational reports were initially shared on a [weekly basis](https://discuss.ens.domains/t/endowment-weekly-reports/16665) and later transitioned to [monthly updates](https://discuss.ens.domains/t/endowment-monthly-reports/17614), all of which were made available on the forum for community review.
The Endowment's phased initiation should also be taken into account when interpreting these results. Full capital utilisation was only achieved 49 days after the Endowment's inception, following the completion of the earned ETH-to-stablecoin tranche swaps. This staggered approach had a discernible impact on the reported financial metrics.
Taking into consideration the revenue generated during the most recent four months—after reaching 100% capital utilisation—the projected annual revenues at the current Endowment's size stand at 367 ETH from ETH-neutral strategies and an equivalent of $351,654 in stablecoins from USD-neutral strategies. This results in a projected Annual Percentage Rate (APR) of approximately 3.4%.
### Specification
#### Fund Transfer
Transfer 16,000 ETH to the Endowment (0x4F2083f5fBede34C2714aFfb3105539775f7FE64).
#### Permissions preset adjustments
In line with our commitment to streamline governance and reduce the frequency of voting events for the community, we propose targeted adjustments to the existing permissions preset within this proposal. Specifically, we are requesting three key changes:
* **Whitelisting the updated wstETH-WETH Pool and Gauge**: As part of our ongoing optimization, we propose to whitelist the updated wstETH-WETH pool on [Balancer](https://app.balancer.fi/#/ethereum/pool/0x93d199263632a4ef4bb438f1feb99e57b4b5f0bd0000000000000000000005c2) and its corresponding gauge on [Aura](https://app.aura.finance/#/1/pool/153).
* **Revoking Permissions for Aura's bb-a-usd Pool**: In light of the recent [vulnerability](https://forum.balancer.fi/t/vulnerability-found-in-some-pools/5102) disclosed by Balancer on August 24, 2023, we recommend revoking all permissions associated with potentially compromised pools. It's important to note that the Endowment had no exposure to these compromised pools at the time the vulnerability was made public.
* **Whitelisting the **\_**delegatecall**\_\*\* function on Cow Swap\*\*: A minor bug was found in the existing preset configuration. Specifically, the *signOrder* function within Cow Swap's order signer contract is designed to be executed solely via a delegate call, a capability not currently supported by the preset. This oversight not only hindered functionality but also revealed a flaw in the SDK preset testing framework. The issue has been swiftly addressed and rectified in a recent [commit](https://github.com/gnosis/zodiac-modifier-roles-v1/commit/c22b1fa8c10b1e3cfb2c1fceef24498c25f3ea2d) to the codebase.
As is customary, we are presenting an updated version of the ["Preset permissions - ENS Endowment'' document](https://docs.google.com/document/d/1vhws_fnbIws8EUItK14V2TVIecHdJLxKzN8Za4d5L0M/edit). This document comprehensively lists all permissions granted to karpatkey, with newly requested permissions highlighted in green and any revocations marked in red.
We are also sharing the [payload](https://gist.github.com/santinomics/bb6b345ff977e7451ff0506e253ebc4c/044f46247ab57f8c65bf608b83eacefa128671f7) to apply the proposed changes for your review. We strongly encourage community members with the required technical expertise to scrutinise the content and share their invaluable feedback.
### Transactions
All transactions can be found in the following [payload](https://gist.github.com/santinomics/bb6b345ff977e7451ff0506e253ebc4c/044f46247ab57f8c65bf608b83eacefa128671f7).
## \[EP4.3] \[Executable] Refund Invalid .eth Names
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/16824) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/87741894125754523615596264728611635516467361279764827076788536604061840625452) |
### Abstract
This proposal initiates a transfer of 117 ETH to the Meta-Governance Working Group to facilitate the refunding of .eth names invalidated by ENSIP-15, the latest ENS name normalization standard.
### Specification
ENSIP-15 introduced a new ENS name normalization standard, resulting in the invalidation of a set of .eth names. In order to address the impact on owners of these invalidated names, refund amounts have been determined based on the following factors:
1. Remaining registration fee or renewal fee
2. Gas fees paid to register the name
3. Any premium protocol fee paid to acquire the names
These factors together have been used to calculate the refund amounts. A total of 2,973 unique addresses will be refunded a total of approximately 115 ETH.
Note: The data is from June 18, 2023 when ENSIP-15 passed. The [distributions](https://docs.google.com/spreadsheets/d/1JoLq8obUwFu_xGaXRMslAyX6nwR3njXqIc7I9sizTLU/edit?usp=sharing) and [code](https://github.com/ensdomains/normalise-refund) are both open source.
To facilitate the transfer of refunds to the affected addresses, this proposal suggests transferring the necessary ETH amount, including gas fees, to the Meta-Governance multisig. The multisig will then execute the refunds on behalf of the ENS DAO and return any leftover gas funds, if applicable.
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ------- | -------- | -------- | ----- |
| 0x91c32893216dE3eA0a55ABb9851f581d4503d39b | 117 ETH | | | |
## \[4.4.1] \[Social] Funding Request: ENS Ecosystem Working Group
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/4-4-1-social-funding-request-ens-ecosystem-working-group/17995) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x12a2abca291496c7e990d099240b4c995099dc0fb85767e04f22b9496e953799) |
### Abstract
The ENS Ecosystem Working Group requests funding of 409,000 USDC to support operations until the March 2024 funding window. This is the only funding request of this term.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding builders and projects that are ENS-specific or ENS-centric.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| --------------------------- | :-----: | :-: | :--: |
| ENS Ecosystem Main Multisig | 409,000 | -- | -- |
### Description
#### ENS Ecosystem Multisig Balances - As of October 18, 2023
The ENS Ecosystem Working Group multisigs:
| Multisigs | USDC | ETH |
| :---------------------------------------------------------------------------------------- | ---: | --: |
| [Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 215k | 157 |
| [Builder Grants](https://etherscan.io/address/0x6a016548310076285668e2378df70bd545396b5a) | 157k | 38 |
| [Grants](https://etherscan.io/address/0xba0c461b22d918fb1f52fef556310230d177d1f2) | 141k | 3 |
| [IRL](https://etherscan.io/address/0x536013c57daf01d78e8a70cad1b1abada9411819) | 21k | 9 |
| [Hackathon](https://etherscan.io/address/0x9b9c249be04dd433c7e8fbbf5e61e6741b89966d) | 68k | 19 |
| [Support](https://etherscan.io/address/0x69a79128462853833e22bba1a43bcdac4725761b) | 74k | 19 |
| [Bug Bounty](https://etherscan.io/address/0xb3a37c813d3d365a03dd1dd3e68cc11af019cdd6) | 14k | 0 |
| [Merch](https://etherscan.io/address/0x0d06a817584ac378849f03df6f11a9ad67dd786d) | 39k | 4 |
| [Newsletter](https://etherscan.io/address/0x13aEe52C1C688d3554a15556c5353cb0c3696ea2) | 14k | 0 |
| Total\*\* | 741k | 249 |
\*\*Amounts do not foot due to rounding (739k vs. 741)
#### Reserved for Initiatives
Ecosystem reserves amounts to make sure we can cover initiatives that are important. Reserving is not the same as spending it. For example, we are reserving 250k for the bug bounty program. The actual spend will depend on what, if any, bugs are discovered.
| Initiatives | USDC | ETH |
| :------------- | ---: | --: |
| Grants | 300k | 115 |
| Bug Bounty | 250k | 0 |
| Hackathon | 150k | 50 |
| Audit Support | 100k | 0 |
| IRL | 75k | 0 |
| Newsletter | 25k | 0 |
| Reserved Total | 900k | 165 |
**Reconciliation**
| Initiatives | USDC | ETH |
| :-------------- | -----: | ----: |
| Current Balance | 741k | 249 |
| Reserved | (900k) | (165) |
| Buffer | (250k) | (50) |
| Total | (409k) | 34 |
As result, Ecosystem WG is requesting 409,000 in USDC and zero ETH. This request ensures that there are sufficient resources to meet the expected future needs of the working group.
##### Grants Breakdown
| Item | USDC | ETH |
| ------------- | -------: | ------: |
| eth.limo\*\* | 85k | 10 |
| ensgrants.xyz | 0.0 | 55 |
| Fellowship | 60k | 0 |
| Discretionary | 155k | 50 |
| **Total** | **300k** | **115** |
\*\* Expected to be paid in Q1 2024.
#### Initiatives Description
| Initiative | Description |
| -------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Grants | Grants support ens small grants funding, builders such as [eth.limo](https://eth.limo/), [unruggable](https://www.unruggablelabs.com/), library support, and other builder centric bounties |
| Bug Bounty | Supports the official bug bounty [program](https://docs.ens.domains/bug-bounty-program) of ENS -- soon to be managed by [immunifi](https://immunefi.com/) |
| Hackathons | Sponsorship costs and prize money for hackathons and conferences |
| Support | Support mods for social platforms, technical and non-technical educational and archival content |
| IRL | Funding In Real Life events that coincide with the existing Ethereum event schedule |
| Merch | Subsidizing the cost of creating and shipping physical ENS merchandise including shirts, hats, and pins |
| ENS Fellowship | Supports exceptional developers actively creating and contributing to the ENS ecosystem with a 6 month Fellowship |
This proposal was prepared by slobo.eth, lead steward of the ENS Ecosystem Working Group.
## \[4.4.2] \[Social] Funding Request: ENS Meta-Goverance Working Group
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/17994) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x5c0d103911aaaa64ee33fc35aa30bffd7c1ca04ac2df85fb274414732c45a6f9) |
### Abstract
The ENS Meta-Governance Working Group requests funding of the below to **support operations until the March 2024 funding window**. This means the Working Group will not be requesting funds in the January 2024 Funding Window.
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| -------------------------- | :-------: | :-: | :----: |
| ENS Meta-Gov Main Multisig | 376,000\t | 40 | 52,300 |
***
### Description
#### Current Metagov Wallet Balances
(Values expected as of October 20th, 2023 - Use hyperlinked wallet names to see current balances)
| Address | ETH | USDC | $ENS |
| ---------------------------------------------------------------------------------------------------- | ----- | ------- | ----- |
| [ens-metagov.pod.xyz](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) | 1.2\* | 162,653 | 1,990 |
| [ens-governance.pod.xyz](https://etherscan.io/address/0x4f4cAdb8AF8F1d463240c2b93952D8a16688a818) | 32 | 83,500 | 1,250 |
| [ens-daotooling.pod.xyz](https://etherscan.io/address/0x8f730f4aC5fd234df9993E0E317f07e44fb869C1) | 0 | 85,993 | |
| [ens-endowmentfees.pod.xyz](https://etherscan.io/address/0x83DD97A584C4aD50015f7aA6B48bf4970A056d8f) | 86.69 | | |
\*As of 10/18 this wallet also temporarily holds the 117 ETH being distributed via [ \[EP4.3\] \[Executable\] Refund .eth names affected by normalization updates](https://discuss.ens.domains/t/ep4-3-executable-refund-eth-names-affected-by-normalization-updates/17622)
***
### Expenditures
Meta-Gov sets aside funds to ensure coverage for critical mission initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives. We anticipate that Final Expenditures will not surpass the Expected Expenses allocated for the term.
#### Expected Expenses through March 2024
| | USDC | ETH | $ENS |
| -------------------------------- | ----------- | ------ | ---------- |
| Steward + Secretary Compensation | 276,000 | - | |
| Governance | 50,000 | - | 52,300 |
| DAO Tooling | 50,000 | 30 | - |
| DAO Sponsorship | - | 10 | - |
| Discretionary | - | - | - |
| **Total Balance** | **376,000** | **40** | **52,300** |
#### Description of Initiatives/Pods
**Steward + Secretary Compensation**: Working Group Steward and Secretary compensation totalling $276,000 USDC.
**Governance**: Fee reimbursements and initiatives related to reducing friction in the governance process. This can also include $ENS distributed in order to lower barriers to the governance proposal process.
**DAO Tooling**: Developing interfaces and dashboards to improve the governance process and increase transparency across the DAO.
**DAO Sponsorship**: Sponsoring DAO-specific events such as DAO NYC, DAO Tokyo, or others that fit the criteria.
**Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments.
***
This proposal was prepared by katherine.eth, lead steward of the ENS Meta-Governance Working Group.
## \[4.4.3] \[Social] Funding Request: Public Goods Working Group
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/17996) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x0a7bec3cd182dadbd043e77cf7a610a6e33c5228fabe407cb89c632b578b83a9) |
### Abstract
The ENS Public Goods Working Group requests funding of the below to **support operations until the March 2024 funding window**. The Working Group intends to refrain from requesting funds in the upcoming January 2024 Funding Window.
The Public Goods Working Group is responsible for supporting projects and builders as provisioned by Article III of the ENS DAO Constitution, which provides direction for the DAO to fund public goods that benefit the broader Ethereum and Web3 Ecosystems.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Public Goods Multisig to fulfil anticipated budgetary needs through March 2024.
| | USDC | ETH | $ENS |
| ------------------------- | :-----: | :-: | :--: |
| Amount Requested from DAO | 218,204 | 35 | 0 |
***
### Description
#### Current Public Goods Wallet Balance
(Values expected as of October 20th, 2023 - Use hyperlinked wallet names to see current balances.)
| Address | USDC | ETH | $ENS |
| --------------------------------------------------------------------- | ------- | --- | ----- |
| [ens-publicgoods.pod.xyz](0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d) | 184,796 | 25 | 1,352 |
***
### Expenditures
#### Expected Expenses through March 2024
| | USDC | ETH | $ENS |
| ---------------------------- | ----------- | ------ | --------- |
| Large Grants | 300,000 | - | - |
| Small Grants | - | 45 | - |
| Events & Hackathons | 50,000 | - | - |
| Discretionary | 53,000 | 15 | - |
| **Total Projected Expenses** | **403,000** | **60** | **1,352** |
#### Description of Initiatives/Pods
##### Large Grants
Grants up to 50k USDC with applications accepted on a rolling basis throughout the term. Large Grants are resuming in Q4 2023 and should be allocated through Q1 2024.
##### Small Grants
Multiple micro-grants voted on by the community. Small Grants is resuming this term with modifications to the voting format. Three rounds, totalling 15 ETH each, are expected to occur until March 2023.
##### Events and Hackathons
The working group will provide support to Public Goods events and hackathons. Following discussions around hackathon opportunities, we want to ensure we have availing funding if requests arise.
##### Discretionary
The funds in this category are reserved for unforeseen grants and unexpected expenses for the term. Spending in this category is at the discretion of the working group stewards and may include grants not listed but in alignment with the purpose of this working group.
***
This proposal was prepared by coltron.eth, lead steward of the ENS Public Goods Working Group.
## \[EP4.5] \[Executable] Endowment permissions to karpatkey - Update 3
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/18036) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/15706104363492914432572227540113855373051896881975394006732444538096386655538) |
### Abstract
This proposal introduces new actions and strategies to the Endowment with the aim of enhancing diversification and adapting to current market conditions. Notable additions include ETH-neutral strategies involving Liquid Staking Protocols and established Money Markets.
### Motivation
Following the successful approval of [E.P. 4.2](https://www.tally.xyz/gov/ens/proposal/10686228418271748393758532071249002330319730525037728746406757788787068261444), the second tranche of the Endowment was funded with 16,000 ETH. Community feedback during the E.P. 4.2 voting window indicated a desire to reduce exposure to Lido due to concerns about centralization risks in the network. While diversifying ETH-neutral holdings was already underway, the need for further diversification and divestment from Lido became clear during [community discussions](https://discuss.ens.domains/t/4-2-executable-fund-the-endowment-second-tranche/17743) and the last [Meta-gov call](https://discuss.ens.domains/t/metagov-working-group-weekly-meeting-11am-et-tuesday/15981/43#h-2-endowment-discussion-karpatkey-steakhouse-10) before the vote's closure. Consequently, karpatkey and @steakhouse proposed a 20% cap on Lido's maximum allocation within the ETH-neutral portfolio, set to be achieved by month-end. This proposal's goal is to introduce new strategies for deploying the remaining 80% of the funds as well as other minor maintenance actions.
### Specification
Permissions to be added in this proposal:
1. Deposit ETH on Compound v3;
2. Deposit ETH or WETH on AAVE v3;
3. Deposit ETH or WETH on Spark Protocol;
4. Stake (and unstake) ETH on Stader;
5. Stake (and unstake) ETH on Ankr;
6. Removal of CowSwap permissions;
7. Removal of SushiSwap permissions;
8. Addition of an alternative getReward() for Aura pools;
9. Swaps:
1. rETH \<> WETH on Balancer;
2. rETH \<> WETH on Uniswap v3;
3. ankrETH \<> wstETH on Balancer;
4. ETHx \<> WETH on Balancer;
5. ankrETH \<> ETH on Curve;
6. ETHx \<> WETH on Pancake Swap
#### Auditing Process
We are releasing an updated version of the ["Preset Permissions - ENS Endowment"](https://docs.google.com/document/d/1Ker_TkBJV0xmQ9Li9HB-vtdlpx1vEeVEQwpIH6WoK0o/edit?usp=sharing) document, highlighting all permissions granted to karpatkey, with proposed additions marked in green and revocations in red. We encourage community members with technical expertise to review and provide feedback on the preset update [payload](https://gist.github.com/santinomics/5b43dee4839d74e2c593ac9e7c7d1d3d).
In the auditing realm, significant progress has been made, with a [new version](https://zodiac-roles-1h9v0miw9-gnosis-guild.vercel.app/gor%3A0x74F819Fa1D95B57a15ECDEf9ce5c779C1bD6cc8A/roles/test-role/diff/4Iq1jdNbLbCBKmLAKciGaDQANiHStkCqFvJJ5KWQc) of the Zodiac Roles Modifier app developed by Gnosis Guild. When fully operational, this app will allow users to input a payload and check the before-and-after status of permissions presets, enhancing the auditing process.
Furthermore, we're actively engaged in collaborative efforts with potential partners to create a user-friendly audit report, enhancing openness for all stakeholders involved in the process. In our commitment to transparency, we're taking an additional step by offering a [self-audit report](https://github.com/karpatkey/gists/blob/main/Self%20Audit_%20%5BENS%5D%20-%20PUR%20%233%20-%20New%20ETH-Neutral%20Strategies.md). This report sheds light on our internal procedures for assessing proposed permissions and changes, providing further insight into our practices.
## \[EP4.6] \[Executable] October 2023 Working Group Funding
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/18064) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/97815480450036429026998617227498389389237567897899533433380564585906006968770) |
This proposal executes all three Working Group funding requests for the October 2023 funding window as passed in EP 4.4.1, EP 4.4.2, and EP 4.4.3. For more detail, view the ENS Governance docs at [https://basics.ensdao.org](https://basics.ensdao.org) 1 [Draft Discourse link](https://discuss.ens.domains/t/ep-4-6-executable-october-2023-working-group-funding/18064)
### Abstract
### [EP 4.4.1 — ENS Ecosystem Working Group](https://discuss.ens.domains/t/4-4-1-social-funding-request-ens-ecosystem-working-group/17995)
The ENS Ecosystem Working Group requests funding of **409,000 USDC** from the ENS DAO treasury.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding people and projects that are ENS-specific or ENS-centric. In line with Article III of the ENS DAO Constitution, the requested funds will be used to support projects and builders contributing to the development and improvement of the ENS protocol and the ENS ecosystem.
### [EP 4.4.2 — MetaGovernance Working Group](https://discuss.ens.domains/t/4-4-2-social-funding-request-ens-meta-goverance-working-group/17994)
The Meta-Governance Working Group requests funding of **376,000 USDC, 40 ETH, and 52,300 $ENS** from the ENS DAO treasury.
This MetaGovernance Working Group will use this funding to support the governance processes of the ENS DAO as well as manage and build infrastructure to support the ENS DAO and Working Groups.
### [EP 4.4.3 — Public Goods Working Group](https://discuss.ens.domains/t/4-4-3-social-funding-request-ens-public-goods-working-group/17996?u=5pence.eth)
The ENS Public Goods Working Group requests funding of **218,204 USDC, and 35 ETH** from the ENS DAO treasury.
The Public Goods Working Group will be use this funding to support projects and builders as provisioned by Article III of the ENS DAO Constitution, which provides for the funding of public goods in web3.
### Specification
The following transfers are to be made:
* Transfer 409,000 USDC to ens-ecosystem.pod.xyz
* Transfer 376,000 USDC, 40 ETH, and 52,300 $ENS to ens-metagov.pod.xyz
* Transfer 218,204 USDC and 35 ETH to ens-publicgoods.pod.xyz
Addresses for confirmation:
* 0x2686A8919Df194aA7673244549E68D42C1685d03 for ens-ecosystem.pod.xyz
* 0x91c32893216dE3eA0a55ABb9851f581d4503d39b for ens-metagov.pod.xyz
* 0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d for ens-publicgoods.pod.xyz
## \[EP4.7] \[Social] Create Service Provider Streams
::authors
| **Status** | Passed, Budget of $3.6M |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/18091) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x5748982aed143f51333befbc6cc490116648b85a2b0212fdfaf3ab848932c7ae) |
### Abstract
The intent of this proposal is to add new Streams for service providers and propose a structure on how to elect them.
### Motivation
The ENS DAO constitution mandates:
*"Any income generated by the ENS treasury should primarily ensure the long-term viability of ENS and fund the ongoing development and enhancement of the ENS system. Surplus funds may be allocated to other public goods within the web3 space as determined by ENS governance."*
The Endowment has been pivotal in securing the longevity of ENS. This proposal aims to utilize new funds to establish funding streams for service providers dedicated to the continuous evolution and enhancement of the ENS system.
#### **Procedure for Implementation**
Service providers interested in participating must submit their candidacy on the ENS Forum by December 1st, demonstrating their expertise and providing a plan for enhancing the ENS system. Detailed instructions will be issued following the approval of this proposal.
Candidates must stipulate their service fees in increments of US$200,000 per annum, committing to a minimum service period of 12 months. Project budgets should not exceed US$1 million annually.
A new snapshot for approval voting will be set up. Projects must obtain a minimum of 1 million ENS in approvals to proceed.
Eligible projects will be ranked by vote count. A greedy algorithm will then be applied to select the highest-voted projects, provided the cumulative budget does not exceed the preset limit.
Funding for streams will be guaranteed for a minimum of 18 months to prevent service disruptions. However, a reassessment vote will be conducted after 12 months. Although the one-year term is non-binding, and streams may be discontinued at any time by the service provider or the DAO, proper notice will be given in advance.
All outputs financed by the DAO must be released under an Open Source License permitting derivative works.
##### **Criteria for Project Qualification**
Projects may include, but are not limited to:
* Development of alternative open-source front-ends for diverse audiences or platforms.
* Maintenance of developer tools, such as SDKs, to facilitate ENS integration into various applications.
* Implementation of a referral program, complete with necessary contracts and outreach for successful execution.
* Proposals for enhancements to ENS base layer contracts for a more refined experience or to facilitate cost-effective batch transactions.
* Creation and support of improved tools for ENS names' interoperability with decentralized storage solutions.
* Development of novel off-chain trading experiences for names or innovative NFT trading experiments to broaden ENS's appeal.
* Exploration of untapped platforms or entirely new applications for ENS.
### Voting
The vote is a ranked choice voting on the ideal budget: rank your preferred budget or if you'd rather not approve the project at all, rank NO as the highest ranked choice.
## \[EP4.8] \[Social] Amend working groups rules to extend to a full year
::authors
| **Status** | Passed |
| ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) |
### Abstract
The intent of this proposal is to modify the working group guidelines to enhance the DAO's ability to attract and retain talent.
### Motivation
By increasing the term length, we aim to enable potential stewards to allocate more time to the DAO and to establish a transparent and predictable compensation structure for the delegates and token community.
#### Proposed changes
##### Regarding term changes
These amendments are designed to extend the stewardship term, allowing candidates to commit more substantially to the DAO and benefit from a more stable financial prospect.
There are numerous small textual changes that change the two terms into a single one.
**Current:**
> 3.2. Stewards will be elected to serve within working groups for a set period of time (hereafter known as a 'Term' or 'Terms').
>
> 3.3. There are two Terms each calendar year:
>
> 1. The first Term commences at 9am UTC on January 1 each year and ends immediately prior to the commencement of the second Term ('First Term'); and
> 2. The second Term commences at 9am UTC on July 1 each year and ends immediately prior to the commencement of the First Term of the following year ('Second Term').
**Proposed:**
> 3.2. Stewards will be elected to serve within working groups for a set period of one calendar year (hereafter known as a 'Term').
>
> 3.3. The Term for Stewards commences at 9am UTC on January 1 each year and ends immediately prior to the commencement of the Term of the following year.
Some minor changes also occur in sections 4 and 5 just to the same effect. [See the full diff below](https://github.com/ensdomains/governance-docs/pull/44/files).
##### Regarding changes to fair compensation guidelines
The aim here is to bolster the transparency surrounding compensation practices, benefiting voters and delegates and enhancing the DAO's capacity to attract and maintain skilled contributors. These are proposed amendments to section 11 (compensation for stewards)
**Proposed Addition:**
> 10.4. The Meta-Governance working group are responsible for defining standards for fair compensation ('Compensation Guidelines').
>
> 10.5. The Compensation Guidelines shall be defined prior to the Nomination Window for each term and can only take effect for the following term. Summary
The proposed changes intend to make Steward compensation more predictable and transparent, which serves the dual purpose of attracting more talent to the space as well as being fully transparent towards the electors.
### Voting
The vote is an approval voting meaning you need to vote to approve or reject each individual change. Changes will only take effect if the vote for approval on each section is higher than the rejection
## \[EP4.9] \[Social] Select providers for EP4.7 streams
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/18309) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x6ba81cd2997288cc49ae1b95921ec8f107e8ffb9733321d53d488e2b30710b86) |
### Abstract
Following the approval of [EP4.7](/dao/proposals/4.7) by the DAO, prospective service providers have submitted applications to be considered by the DAO for funding. This proposal collects successful applications for a vote by the DAO.
### Specification
EP4.7 provides for a budget of $3,600,000 USDC to be provided annually to qualifying service providers. All successful applications are summarized below in [random order](https://twitter.com/nicksdjohnson/status/1731660224031793376).
The purpose of this vote is to select service providers to receive streaming funding from the DAO. Per the [draft rules](https://github.com/alexvansande/governance-docs/blob/Streams-rules/service-provider-rules.md), selection of winning proposals uses the following process:
1. **Order Proposals**
* Arrange all proposals in descending order based on the number of votes received.
2. **Evaluate Proposals Sequentially**
* **Vote Threshold Check**
* If a proposal has received fewer than 1 million votes, stop the evaluation process immediately.
* **Comparison with 'None of the Above'**
* If a proposal has fewer votes than the 'None of the Above' option, stop the evaluation process.
* **Budget Check**
* If a proposal's requested budget exceeds the remaining budget, skip it and move to the next proposal.
* **Selection**
* If a proposal passes the above checks, add it to the set of selected proposals. Deduct its requested budget from the remaining budget.
#### Post-Selection Procedure
* If at least one service provider is chosen, the Meta-Governance working group will post an executable vote to implement the funding streams by January 10 at the latest.
### Instructions
**Vote FOR** on any service providers whom you believe that are capable of continuous evolution and enhancement of the ENS system and for which you believe offer a good cost benefit. **Do NOT vote** to any provider you do not believe to be capable of such, for which you believe the proposed projects are out of scope or for which you believe the ask is too high for the proposals. *Only vote "None of the Above" if you want to express your disapproval with the whole system and would rather **not have ANY** of the projects be selected.*
### Candidates
#### NameSys.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#namesysethhttpsdiscussensdomainstservice-provider-stream-nomination-thread181426-1) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/6) **Requested Budget**: $200,000 p.a.
#### handle.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#handleethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814237-2) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/37) **Requested Budget**: $100,000 p.a.
#### NameHash Labs
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#namehash-labshttpsdiscussensdomainstservice-provider-stream-nomination-thread1814239-3) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/39) **Requested Budget**: $600,000 p.a.
#### Unruggable
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#unruggablehttpsdiscussensdomainstservice-provider-stream-nomination-thread181425-4) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/5) **Requested Budget**: $400,000 p.a.
#### generalmagic.eth & pairwise.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#generalmagiceth-pairwiseethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814231-5) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/31) **Requested Budget**: $300,000 p.a.
#### servais.eth / web3xplorer.com
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#servaiseth-web3xplorercomhttpsdiscussensdomainstservice-provider-stream-nomination-thread181429-6) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/9) **Requested Budget**: $100,000 p.a.
#### AlphaWallet
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#alphawallethttpsdiscussensdomainstservice-provider-stream-nomination-thread1814217-7) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/17) **Requested Budget**: $100,000 p.a.
#### ENS Like Protocol
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#ens-like-protocolhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814230-8) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/30) **Requested Budget**: $100,000 p.a.
#### Namespace
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#namespacehttpsdiscussensdomainstservice-provider-stream-nomination-thread1814220unicketh-9) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/20?u=nick.eth) **Requested Budget**: $200,000 p.a.
#### Gnosis Guild
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#gnosis-guildhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814233-10) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/33) **Requested Budget**: $600,000 p.a.
#### GravityDAO
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#gravitydaohttpsdiscussensdomainstservice-provider-stream-nomination-thread1814226-11) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/26) **Requested Budget**: $100,000 p.a.
#### ENS Vision Forge
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#ens-vision-forgehttpsdiscussensdomainstservice-provider-stream-nomination-thread1814219-12) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/19) **Requested Budget**: $500,000 p.a.
#### Blockful
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#blockfulhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814238-13) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/38) **Requested Budget**: $300,000 p.a.
#### Web3Domains.com
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#web3domainscomhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814227-14) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/27) **Requested Budget**: $500,000 p.a.
#### dAppling
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#dapplinghttpsdiscussensdomainstservice-provider-stream-nomination-thread1814222-15) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/22) **Requested Budget**: $400,000 p.a.
#### ESF Tools
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#esf-toolshttpsdiscussensdomainstservice-provider-stream-nomination-thread1814216-16) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/16) **Requested Budget**: $200,000 p.a.
#### StableLab
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#stablelabhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814223-17) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/23) **Requested Budget**: $300,000 p.a.
#### The Interceptor
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#the-interceptorhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814210-18) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/10) **Requested Budget**: $500,000 p.a.
#### Tally
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#tallyhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814232-19) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/32) **Requested Budget**: $300,000 p.a.
#### ENS Anti-Abuse Tools
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#ens-anti-abuse-toolshttpsdiscussensdomainstservice-provider-stream-nomination-thread1814221-20) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/21) **Requested Budget**: $100,000 p.a.
#### Wildcard Labs
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#wildcard-labshttpsdiscussensdomainstservice-provider-stream-nomination-thread1814225-21) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/25) **Requested Budget**: $200,000 p.a.
#### eth.limo
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#ethlimohttpsdiscussensdomainstservice-provider-stream-nomination-thread181423-22) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/3) **Requested Budget**: $500,000 p.a.
#### wayback-machine.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#wayback-machineethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814229-23) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/29) **Requested Budget**: $200,000 p.a.
#### Referrals powered by generalmagic.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#referrals-powered-by-generalmagicethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814234-24) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/34) **Requested Budget**: $200,000 p.a.
#### unicorn.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#unicornethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814236-25) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/36) **Requested Budget**: $200,000 p.a.
#### Ethereum Follow Protocol
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#ethereum-follow-protocolhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814218-26) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/18) **Requested Budget**: $500,000 p.a.
#### resolverworks.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#resolverworksethhttpsdiscussensdomainstservice-provider-stream-nomination-thread1814224-27) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/24) **Requested Budget**: $700,000 p.a.
#### 1w3.eth
[Summary](https://discuss.ens.domains/t/ep4-7-candidates-short-description/18382#h-1w3ethhttpsdiscussensdomainstservice-provider-stream-nomination-thread181428-28) | [Full Proposal](https://discuss.ens.domains/t/service-provider-stream-nomination-thread/18142/8) **Requested Budget**: $500,000 p.a.
## \[EP5.1] \[Executable] Upgrade DNSSEC support
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep5-1-executable-upgrade-dnssec-support/18535) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/4208408830555077285685632645423534041634535116286721240943655761928631543220) |
### Abstract
The ENS labs team has been working on a new version of the DNSSEC oracle and the DNS registrar that, combined with wildcard resolution (ENSIP 10) and CCIP-Read, allow for 'gasless DNSSEC' - enabling the use of DNS names inside ENS with no onchain transactions required. This proposal replaces the existing DNSSEC registrar with the new one.
Existing DNS names will continue to function as before, and names can still be imported using the 'legacy' method. The new registrar also allows configuring a name by setting a TXT record on \_ens.name.tld, containing the address of a special resolver contract to use, followed by any resolver-specific data. Resolvers designed for the purpose can be configured to parse this extra data, making configuration entirely offchain a possibility.
Alongside the new registrar and oracle contracts, a simple resolver is provided that reads the Ethereum address to resolve a name to from the extra data.
Post-execution, ENS Labs will run a process to upgrade all current DNS TLDs to use the new registrar. TLDs will only function with the new registrar once this (permissionless) transaction is sent for the TLD.
### Specification
Call `setController` on the Root contract at `root.ens.eth`, passing in the address of the new DNS registrar (`0xb32cb5677a7c971689228ec835800432b339ba2b`).
### Transactions
| Address | Value | Function | Argument | Value |
| ------------------------------------------ | ----- | ------------- | -------- | ------------------------------------------ |
| 0xaB528d626EC275E3faD363fF1393A41F581c5897 | 0 ETH | setController | | 0xB32cB5677a7C971689228EC835800432B339bA2B |
| | | | | true |
## \[EP5.10] \[Social] Confirming the ENS DAO Security Council Members
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-enable-cancel-role-on-the-dao/19090) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xa0b1bfadf6853b5b0d59d3c4d73c434fc6389339887d05de805361372eb17c3a) |
### Abstract
Following the successful passing of the [EP5.7](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54), this proposal aims to confirm the 8 individuals who will form the Security Council with the permissions defined in [EP5.7](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54). The Security Council will be responsible for protecting the organization from potential governance attacks by having the ability to cancel malicious proposals using the [SecurityCouncil](https://github.com/blockful-io/security-council-ens/blob/main/README.md) smart contract.
### Specification
A discussion was held in the ENS forum titled **[\[Temp Check\] Enable CANCEL role on the DAO](https://discuss.ens.domains/t/temp-check-enable-cancel-role-on-the-dao/19090)**.
Following that discussion, The [EP5.7](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54) proposal, which can be [found here](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54), detailed the need for a Security Council to mitigate the risk of governance attacks on the ENS DAO. The proposal passed with overwhelming support from the community, receiving 1.4 million votes and 100% approval.
As outlined in the [EP5.7](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54) proposal, the [SecurityCouncil](https://github.com/blockful-io/security-council-ens/blob/main/README.md) smart contract will be deployed, and the Security Council multisig will be granted the PROPOSER\_ROLE in the timelock. This will allow the Security Council to cancel malicious proposals, without granting the ability to initiate proposals, vote on proposals, or perform any other actions. The contract also features an expiration mechanism that automatically revokes the council's veto power after 2 years, promoting decentralization.
#### Proposed Security Council Members
The proposed Security Council will consist of the following 8 individuals in a 4/8 multisig configuration:
1. [nick.eth](https://www.tally.xyz/gov/ens/delegate/nick.eth)
2. [griff.eth](https://www.tally.xyz/gov/ens/delegate/0x839395e20bbb182fa440d08f850e6c7a8f6f0780)
3. [avsa.eth](https://www.tally.xyz/gov/ens/delegate/avsa.eth)
4. [lefteris.eth](https://www.tally.xyz/gov/ens/delegate/lefteris.eth)
5. [katherineykwu.eth](https://www.tally.xyz/gov/ens/delegate/katherineykwu.eth)
6. [fireeyes.eth](https://www.tally.xyz/gov/ens/delegate/fireeyesdao.eth)
7. [brantly.eth](https://www.tally.xyz/gov/ens/delegate/brantly.eth)
8. [alextnetto.eth](https://www.tally.xyz/gov/ens/delegate/alextnetto.eth)
The text of [EP5.7](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54) specified that the 5 delegates included on the veto contract would be included in the security council. To fill the remaining 3 places on the council, consideration was given to, delegation power, past activity in governance, economic skin on the game, and jurisdictional diversity (for legal reasons).
#### Voting
This social proposal seeks to confirm the complete list of 8 individuals as the Security Council members. **The vote will be a simple For/Against/Abstain vote on the entire list.** If the proposal is successful, a separate executable proposal will be put forward to deploy the SecurityCouncil smart contract and grant the necessary roles.
For this vote, the 8 proposed members of the Security Council will vote "**Abstain**" to help meet quorum requirements while preserving their impartiality.
#### Next Steps
Upon confirmation of the Security Council members through this social proposal, the following steps will be taken:
1. The SecurityCouncil contract will be manually deployed to Mainnet.
2. A multsig will be manually created with the 8 members as signers.
3. The multisig will accept ownership of the SecurityCouncil contract.
4. The executable proposal will grant the PROPOSER\_ROLE to the SecurityCouncil contract address using the grantRole function in the timelock.
Once the executable proposal is passed and the contract is deployed with the necessary roles granted, the Security Council will be able to cancel malicious proposals to protect the ENS DAO.
After the specified expiration period (2 years), anyone can revoke the PROPOSER\_ROLE from the Security Council, ensuring this is a time-limited mechanism that defaults back to a more decentralized posture.
### Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
1. **Quorum**: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "Yes" and "Abstain" votes combined. "No" votes do not count towards quorum.
2. **Approval**: Once the quorum is reached, the proposal requires a simple majority (>50%) of "Yes" votes among the "Yes" and "No" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP5.11] \[Executable] Fund the Meta-Governance Working Group (Term 5)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep5-11-executable-proposal-fund-the-meta-governance-working-group-term-5/19358) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/76312276134880424811339391717815330375652916610982980144903695563372140531115) |
### Abstract
Meta-Governance is seeking funding to support DAO-wide operations, including Working Groups, treasury management, and governance initiatives. This request aligns with Rule 10.1.1 of the [Working Group Rules](https://docs.ens.domains/dao/wg/rules) and amendments introduced in [EP 4.8](https://docs.ens.domains/dao/proposals/4.8). This proposal will execute the funding specification according to [EP 5.9](https://snapshot.org/#/ens.eth/proposal/0x66d355555c24ed0d2fed0aee89e4fe009e2925c84144c4edc707d33e7c19e554), as amended by [EP 5.8](https://snapshot.org/#/ens.eth/proposal/0x1f328fd1fda5f3cabfdace3e521403def7ad41b0b0582e27334c135cd23c511d).
### Motivation
#### [EP 5.9 — Funding Request: ENS Meta-Governance Working Group Term 5 ](https://discuss.ens.domains/t/4-4-2-social-funding-request-ens-meta-goverance-working-group/17994)
The Meta-Governance Working Group requests funding of **374,000 USDC and 150,000 ENS** from the ENS DAO treasury ([wallet.ensdao.eth](https://etherscan.io/address/0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7)). This funding will be used to support the governance processes of the ENS DAO and to manage and build infrastructure that supports the ENS DAO, its treasury, and its Working Groups.
### Specification
The following transfers are to be made:
* Transfer 374,000 USDC to [main.mg.wg.ens.eth](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b).
* Transfer 150,000 ENS to [main.mg.wg.ens.eth](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b).
Addresses for confirmation:
* 0x91c32893216de3ea0a55abb9851f581d4503d39b for main.mg.wg.ens.eth
## \[EP 5.12] \[Executable] Roles Modifier V2 Migration & Updates to Endowment Permissions
::authors
| **Status** | Passed |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-12-roles-modifier-v2-migration-updates-to-endowment-permissions/19173) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/107992041043258996427224563090014372885335179099580585497266204203463156791290) |
### Abstract
This proposal aims to roll out an updated version of the Zodiac Roles Modifier module. The new version improves usability and transparency of treasury management operations. Upon approval, the Roles Modifier v2 module will be activated.
Furthermore, this proposal requests authorization from the DAO to revise the permissions policy. A notable change includes enabling swapping actions on CoW Swap while the other permissions primarily focus on eliminating obsolete actions and protocols, and refining parameters within the existing permissions.
## Roles v2 Migration
### Motivation
As [previously stated](https://discuss.ens.domains/t/endowment-initiation/15952#a-list-of-zodiac-roles-modifier-permissions-for-the-manager-role-9), the Zodiac Roles Modifier facilitates karpatkey’s proxy management of the Endowment by ensuring that only pre-approved transactions, defined by the permissions policy voted on by the DAO, can be executed. In collaboration with karpatkey, the Gnosis Guild team has significantly upgraded the Zodiac Roles Modifier module and the Zodiac Roles app. These enhancements have resulted in a more powerful and robust on-chain permissions infrastructure with the following improvements:
* **Introduction of Allowances**: Implementation of spending limits within permissions.
* **Enhanced Call Data Scoping Toolset**: This toolset considerably broadens the range of functions that can have permissions set, increasing flexibility.
* **Advanced Logical Conditions**: Allows for the creation of complex permissions structures to accommodate sophisticated operational needs.
* **Compatibility with** [**DeFi Kit**](https://kit.karpatkey.com/): This feature integrates with karpatkey’s permissions policy building module, facilitating the straightforward crafting of protocol actions.
* **Improved Visualisation and User Interface**: the new [Zodiac Roles app UI 1](https://roles.gnosisguild.org/) not only displays permissions clearly but also provides a user-friendly interface to compare changes in each policy update, enhancing transparency and simplifying audits.
For more detailed information, please refer to the following resources:
* **Documentation**: [The Zodiac Roles Modifier](https://docs.roles.gnosisguild.org/)\\
* **Articles**: [Evolving Smart Accounts with Onchain Permissions](https://gnosisguild.mirror.xyz/oQcy_c62huwNkFS0cMIxXwQzrfG0ESQax8EBc_tWwwk), [Permissions as code](https://engineering.gnosisguild.org/posts/permissions-as-code)
### Contract audits
The Zodiac Roles Modifier v2 contract has been rigorously audited by G0 Group, the internal auditing team of Gnosis DAO, and by [Omniscia](https://omniscia.io/). The detailed audit reports are available for review [here 1](https://github.com/gnosisguild/zodiac-modifier-roles/tree/main/packages/evm/docs).
## Changes to Permissions policy
This proposal outlines the following modifications to the permissions policy:
1. **Token Arrays for Swapping**:
* Considering the tokens involved in the existing permissions, we have updated the token arrays to ensure they can be seamlessly swapped across the various whitelisted protocols and aggregators.
* **Token IN Allowlist**: \\\[CRV, DAI, USDT, BAL, AURA, CVX, ETHx, COMP, rETH, SWISE, wstETH, LDO, WETH, ankrETH, USDC, stETH].
* **Token OUT Allowlist**: \\\[DAI, USDT, USDC, rETH, wstETH, WETH, stETH].
* 4. The above arrays are to be utilised for swapping on CoW Swap, with equivalent lists replicated for Uniswap v3 and Balancer.
2. **Introduction of CoW Swap** ([diff 4](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0x23da9ade38e4477b23770ded512fd37b12381fab)):
* Addition of a **CoW Swap Order signer** to enable gas-minimised and MEV-protected swaps. This includes an extensive set of aggregated exchange routes, improving the efficiency and effectiveness of required swaps.
* Tokens will be swapped on CoW Swap according to the token IN/OUT allowlists mentioned above.
3. **Deprecations and Removals**:
* **Uniswap v2 Swaps** ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#left-0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45-0x472b43f3)): Removed due to insufficient liquidity in V2 pools.
* **Stakewise v2**: Deprecated functions related to deposit ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#left-0xc874b064f465bdd6411d45734b56fac750cda29a)) and claim ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#left-0xa3f21010e8b9a3930996c8849df38f9ca3647c20)) functions in light of the recent launch of Stakewise v3. Consequently, permitted actions related to Stakewise v2’s sETH2-ETH Uniswap pool are also removed ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#left-0xc36442b4a4522e871399cd717abdd847ab11fe88)).
* **Compound v2** ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#left-0x39aa39c021dfbae8fac545936693ac917d5e7563)): Discontinued all actions targeting v2 contracts and v2 cTokens (cUSDC and cDAI) due to the ongoing transition of the protocol to its v3.
* **Revocation of Existing/Obsolete Allowances:** All existing and outdated allowances previously set by the Endowment are revoked (set to zero). The ability to call the corresponding approve functions is included in the newly proposed policy. Accordingly, the payload contains a bundle of transactions to revoke these allowances.
4. **Updates**:
* **Uniswap v3** ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45-0x04e45aaf)) **and Balancer** ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0xba12222222228d8ba445958a75a0704d566bf2c8)): Adjusted to allow the mentioned token IN/OUT allowlists.
* **Curve Pools**: Addition of stETH-ng (factory) pool ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/rMNui3Yp9LlBScVLFjY9cWkk4QGYoIVkkYxURs16ys?annotations=false#right-0x21e27a5e5513d6e65c4f830167390997aa84843a)) and removal of cUSDC + cDAI pool ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/rMNui3Yp9LlBScVLFjY9cWkk4QGYoIVkkYxURs16ys?annotations=false#left-0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56); Compound v2 tokens).
* **Curve ZAP Deposit Contract** ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/rMNui3Yp9LlBScVLFjY9cWkk4QGYoIVkkYxURs16ys?annotations=false#right-0x56c526b0159a258887e0d79ec3a80dfb940d0cd7)): Introduced to allow depositing and staking of LP tokens in a single step.
* **Convex Staking** ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0x6b27d7bc63f1999d14ff9ba900069ee516669ee8)): Added the CVX/stETH Rewards contract.
* **Lido Withdrawals** ([diff](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0x889edc2edab5f40e902b864ad4d7ade8e412f9b1)): Enhanced to include new withdrawal methods using permits for both wstETH and stETH; methods include `requestWithdrawalsWstETHWithPermit` and `requestWithdrawalsWithPermit`.
* **Spark Rewards Claim** ([diff 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false#right-0x4370d3b6c9588e02ce9d22e684387859c7ff5b34)): Added functionality to claim wstETH rewards in Spark.
## Audit Considerations
We highly value the community’s involvement in reviewing and providing feedback on this proposal. We encourage members with the necessary technical expertise to examine the content carefully (including this [payload 1](https://gist.github.com/santinomics/773117b729152f31a121045f4ba26b5b)) and share their insights with us. For effective testing of the permissions policy configuration, we have utilised a [Testing Avatar Safe 1](https://app.safe.global/balances?safe=eth:0xC01318baB7ee1f5ba734172bF7718b5DC6Ec90E1). This safe mirrors the current state of the [permissions policy v4 1](https://docs.google.com/document/d/1Ker_TkBJV0xmQ9Li9HB-vtdlpx1vEeVEQwpIH6WoK0o) granted by the Endowment to the Manager SAFE operated by karpatkey. The enhancements in the Zodiac Roles app interface now allow for a clear visualisation of all existing permissions, accessible [here 2](https://roles.gnosisguild.org/eth:0xbd1099dfd3c11b65fb4bb19a350da2f5b61efb0d/roles/ENS-MANAGER-V1). The updated interface also simplifies the process of identifying [changes](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/C0zUV4NtNErufEpbpNc2S55F2oiAGw8aKE2jYwWjLg?annotations=false) by displaying the current permissions policy on the left side and the newly proposed policy on the right side. To further aid in the adoption and understanding of these tools for audit purposes, we have detailed the proposed changes in [version 5 documentation](https://docs.google.com/document/d/1KU4a7s-AxAAAPJxd8vexn7kCl8hsr3-c7VIDfEPHbKc/edit), following our standard Policy Update Request (PUR) format.
## Additional Considerations
### Roles Modifier v1 and Enabling of v2
The existing Roles Modifier v1 module will remain active to ensure a smooth transition and prevent any unexpected disruptions in operational execution. Ownership of the deployed [Roles Modifier v2 module 1](https://etherscan.io/address/0x703806E61847984346d2D7DDd853049627e50A40), equipped with the new proposed permissions policy, has been [transferred 1](https://etherscan.io/tx/0x78c69c7ad0c5f430d97ec5c3bac5cb649d831a756b3d4c5b09b45152427ae8f4) to the Endowment’s Avatar Safe. These permissions are displayed [here 4](https://roles.gnosisguild.org/eth:0x703806e61847984346d2d7ddd853049627e50a40/roles/MANAGER) and match those shown on the comparison interface [here 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/rMNui3Yp9LlBScVLFjY9cWkk4QGYoIVkkYxURs16ys?annotations=false). The payload will only activate this module, marking the first phase of the migration process. A subsequent policy update proposal will seek to disable the v1 module.
### Policy Visualisation in Terms of DeFi Kit Actions
The “show annotations” button, located at the top-right [here 1](https://roles.gnosisguild.org/eth:0xBd1099dFD3c11b65FB4BB19A350da2f5B61Efb0d/roles/ENS-MANAGER-V1/diff/rMNui3Yp9LlBScVLFjY9cWkk4QGYoIVkkYxURs16ys?annotations=false), provides a visualisation of the proposed permissions policy expressed through the DeFi Kit Protocol Actions. This feature offers a more abstract and simplified description of the policy, enhancing understanding and accessibility.
## \[EP 5.13] \[Executable] Security Council
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep5-13-executable-security-council/19412) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/42329103797433777309488042029679811802172320979541414683300183273376839219133) |
### Abstract
The primary mission of ENS DAO is to govern the protocol and allocate resources from the treasury in line with the DAO's constitution and broader objectives. However, due to changing economic dynamics, the DAO is increasingly vulnerable to attacks aimed at draining its treasury.
To safeguard the DAO's integrity and longevity, a Security Council with the authority to cancel malicious proposals is needed. To avoid perpetuating centralized power, the Security Council's authority will have a built-in expiration date. After two years, anyone will be able to call a [function](https://github.com/blockful-io/security-council-ens/blob/main/src/SecurityCouncil.sol#L59) that revokes the council's power to veto proposals, ensuring a time-limited mechanism to counter malicious attacks while promoting more delegation and governance distribution.

### Motivation
As ENS continues to grow, its treasury in ETH is always growing. Simultaneously, the percentage of tokens actively delegated is on the decline.
This imbalance creates a risk where an attacker could acquire enough $ENS to gain control of the DAO at a cost lower than the treasury's total value. This has been a growing concern since March 2023.
Past attacks on DAOs have exploited similar vulnerabilities, with some [being thwarted](https://x.com/AragonProject/status/1656028382939815937) by components with veto power. Currently, the ENS governance process involves a proposal passing through the governor, relying on delegated voting power for approval. If approved, the governor queues the proposal in a timelock contract, delaying execution by two days. While the governor can cancel proposals, it follows the same pathway as a malicious proposal, introducing potential risks.
The short-term solution was delegating 3.8M $ENS to a contract that can only vote "Against"; more details about this can be found in [Nick's forum post](https://discuss.ens.domains/t/introducing-veto-ensdao-eth/19088). The attack is still profitable and, depending on market conditions can be up to a 3x ROI, like in Dec 2023. We need a **mid-term solution** to cancel the attack, which is this proposal. An article about this research done by the Blockful team will be published [here](https://blockful.io/blog/ens-security-council) after the proposal is executed and there is no attack risk.
### Specification
To enhance security, the [SecurityCouncil contract](https://github.com/blockful-io/security-council-ens/blob/main/src/SecurityCouncil.sol) will be deployed, receiving the PROPOSER\_ROLE in the timelock, granting it the ability to cancel proposals (callable only by the [Security Council multisig](https://etherscan.io/address/0xaa5cd05f6b62c3af58ae9c4f3f7a2acc2cdc2cc7)) without the power to initiate or modify other DAO actions. **The scope of this proposal is to assign the PROPOSER\_ROLE to the SecurityCouncil contract ([Etherscan](https://etherscan.io/address/0xb8fa0ce3f91f41c5292d07475b445c35ddf63ee0#code))**.
To ensure decentralization, the contract will also feature a time-based expiration mechanism that allows anyone to revoke the PROPOSER\_ROLE after two years. This window provides time to strengthen delegation and address current vulnerabilities, facilitating the DAO's transition to a more secure governance scenario.
### Security considerations
Assigning the PROPOSER\_ROLE to a multisig within the timelock contract is overly broad for our requirements as it allows the address to create operations in the timelock. If the multisig signers are compromised, they could potentially propose and execute malicious changes. Therefore our approach is deploying a new contract similar to the current veto.ensdao.eth contract, which can only do one action: to CANCEL a transaction in the timelock, triggered only by the security council multisig.
The risk is mitigated but one scenario remains: if the whole multisig is compromised then a malicious entity could kick other signers and effectively stop the DAO from executing proposals by canceling all transactions, including any that would remove this contract from the PROPOSER\_ROLE. Anyways, after 2 years, [anyone can remove the PROPOSER\_ROLE from the contract](https://github.com/blockful-io/security-council-ens/blob/main/src/SecurityCouncil.sol#L59).
### Council Operations
It is in the best interest of everyone to make clear the expectations and responsibilities ENS DAO put on those members, backed by the reputation, other roles and gains those might have in the organization.
The security council is expected to act only in emergency, in the given following situations or similar cases:
* If a proposal goes against the ENS constitution
* If a proposal is approved with malicious intent against the DAO longevity/sustainability
* If such proposal is approved by any group of voters, but directly financially incentivised to vote against the DAOs interests to preserve their own financial stake.
* If any approved proposal goes directly against the DAO for the sole benefit of an attacker.
### Relevant links
* SecurityCouncil contract ([GitHub](https://github.com/blockful-io/security-council-ens/blob/main/src/SecurityCouncil.sol), [Etherscan](https://etherscan.io/address/0xb8fa0ce3f91f41c5292d07475b445c35ddf63ee0#code))
* Security Council multisig ([Safe](https://app.safe.global/home?safe=eth:0xaA5cD05f6B62C3af58AE9c4F3F7A2aCC2Cdc2Cc7), [Etherscan](https://etherscan.io/address/0xaA5cD05f6B62C3af58AE9c4F3F7A2aCC2Cdc2Cc7))
* Snapshot proposals:
* [\[EP5.7\]\[Social\] Security Council](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54)
* [\[EP5.10\]\[Social\] Confirming the ENS DAO Security Council Members](https://snapshot.org/#/ens.eth/proposal/0xa0b1bfadf6853b5b0d59d3c4d73c434fc6389339887d05de805361372eb17c3a)
* [Forum discussion](https://discuss.ens.domains/t/temp-check-enable-cancel-role-on-the-dao/19090/19)
## \[EP 5.14] \[Executable] Endowment permissions to karpatkey - Update #4
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-14-executable-endowment-permissions-to-karpatkey-update-4/19503) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/62537345451524095629071359388092434511638926463658570104856324869910407296726) |
## Abstract
This proposal aims to introduce new permissions for deploying Endowment funds, focusing on improved diversification and alignment with the evolving market landscape and liquidity. We are also introducing an independent audit report together with the Permissions Update; this will be the standard practice for Permissions Updates going forward.
## Motivation
Effective treasury management strategies must be adapted to market conditions and protocol updates; for existing Permissions, there might be migrations and introductions of new pools; for new Permissions, protocols and pools that were previously considered immature and unsuitable for the Endowment’s risk appetite may become viable options as they become more time- and battle-tested. This proposal seeks to request new permissions from the ENS DAO for karpatkey, enabling the introduction of new yield-generation strategies for the Endowment.
The new permissions have also been audited by [ThirdGuard](https://thirdguard.com/), an independent 3rd-party, to ensure the suggested changes have been thoroughly reviewed by a technically-competent, independent party.
## Specification
### New permissions implemented in this payload
1. Deposit osETH on Aave v3;
2. Stake (and unstake) ETH on Stakewise v3;
1. Through the [Genesis Vault](https://app.stakewise.io/vault/mainnet/0xac0f906e433d58fa868f936e8a43230473652885).
3. Mint (and burn) osETH on Stakewise v3;
1. Through the Genesis Vault
4. WETH/osETH pool on Balancer;
5. WETH/osETH pool on Aura Finance;
6. Swaps:
1. WETH \<> osETH on Balancer
2. USDC \<> osETH on Uniswap v3
3. USDC \<> WETH \<> osETH on CoW Swap
4. RPL \<> WETH on Uniswap v3
5. RPL \<> WETH on CoW Swap
7. Unsign order on Cow Protocol so that a pending order that has been submitted but not executed can be cancelled.
### Additional implementation details
1. The enableModule(address module) function is called to enable the modules, pointing it to the [Avatar address](https://app.safe.global/home?safe=eth:0x4F2083f5fBede34C2714aFfb3105539775f7FE64) (the Endowment).
2. The payload to be executed upon the successful approval of this proposal can be found [here](https://gist.github.com/JeronimoHoulin/55f50e86d1dc874e4e685d5e9b496a67). The proposed permissions policy can be visualised in the aforementioned [link](https://roles.gnosisguild.org/eth:0x703806E61847984346d2D7DDd853049627e50A40/roles/MANAGER/diff/C5Twf3khKv2Ny8PvzoARgHFKFFK8vIiNR7nDkrIM?annotations=false) for ease of review.
3. We have tested the payload to make sure all interactions mentioned on this proposal work as expected through our [Test Safe](https://app.safe.global/transactions/history?safe=eth:0xC01318baB7ee1f5ba734172bF7718b5DC6Ec90E1).
4. With the introduction of the [new Roles App Permissions Visualisation tool](https://roles.gnosisguild.org/eth:0x703806E61847984346d2D7DDd853049627e50A40/roles/MANAGER?annotations=false), manually updating the “Preset Permissions - ENS Endowment” [document](https://docs.google.com/document/d/1KU4a7s-AxAAAPJxd8vexn7kCl8hsr3-c7VIDfEPHbKc/edit?usp=sharing) is no longer necessary. The new tool provides an up-to-date and accurate method for exploring the current permissions granted to karpatkey by the ENS DAO.
## Auditing process
### Introduction of an independent audit report
We have received feedback in the previous proposal that independent, 3rd party code review would be helpful for the ENS community and delegates to make a more informed decision and to reduce delegate fatigue.
In our commitment to transparency and effort towards DAO efficiency, karpatkey decided to engage with independent, third-party firms / individuals for every contract upgrade starting with this proposal. [ThirdGuard](https://thirdguard.com/) has been engaged for this proposal's code review; ThirdGuard is a provider of on-chain risk monitoring solutions, and has been working with the Zodiac Roles Modifier since its inception (and its precursor, Scope Guard). Given their past experiences across Zodiac Roles Modifier, Solidity, and DeFi risk management, ThirdGuard was deemed to be a suitable candidate to fulfil the role of policy reviewer. Their approach to auditing the permissions can be found [here](https://www.loom.com/share/0b3cbcd6907a4455ab45ead4887c7f9a?sid=9bd0a2c7-d932-45c0-acad-8516201c56ea).
**The ThirdGuard audit for the permissions in this payload can be found [here](https://github.com/ThirdGuard/roles-policy-audits/blob/main/ENS/ens-policy-audit-v2-21st-Aug-2024.pdf).**
Audit report summary is as follows:
* No material findings were found.
* Policy changes requested were considered bona fide actions needed by the Manager to carry out their DeFi operations.
* 1 Informational Finding and 1 Warning were logged, and acknowledged by karpatkey. These findings do not post an immediate risk but are relevant to security best practices.
## \[EP 5.15] \[Social] Adding ProposalBond to ENS Governor to make proposing more accessible
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-social-adding-proposalbond-to-ens-governor-to-make-proposing-more-accessible/19539?u=estmcmxci) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xca27ce450e2a404b51d7ec7979639561dc5d8302949b3a29e4dfef2a8993f018) |
### Abstract
The proposal threshold for propose new executable ENS proposals is high, and rightly so. ENS is one of the most popular DAOs and community in the Web3 community and keeping the quality bar of proposals to the highest standard is very important. However, ENS also has the treasury and the desire to expand the community and make proposing easier and more accessible to enable more builders to come and build in ENS.
[Agora](https://agora.xyz/) proposes adding the functionality of the ProposalBond to the ENS DAO Governor that would allow a proposer to propose with a lower threshold, and then the community could vote \[For, Against, Against with penalty, Abstain]. If the weight of `Against with penalty + Against > For`, then the proposer does not get their bond back and the proposal does not pass.
To clarify further: a bond is withheld only if a proposal is rejected (the sum of rejections are bigger than the approvals) AND if the "Against with penalty" is bigger than "Against".
This way we align incentives to create good proposals.
### Specification
A discussion in the DAO Meta-Gov working group titled: [Seeking Feedback: ENS Governor Upgrade to make proposing more accessible](https://discuss.ens.domains/t/seeking-feedback-ens-governor-upgrade-to-make-proposing-more-accessible/19296), Agora proposed the following PR on the ENS Governor: [Proposal Bond Pull Request](https://github.com/voteagora/ens-governance-contracts/pull/1) which outlines the code needed to make this change happen.
Since the time of that PR and during the follow up discussions, the community has asked for the following additions:
* Ensure that the ProposalBond work proposed by Agora works with the new Veto rules and security council. This covers the case of a proposal being vetoed from within the timelock therefore making sure we have the code to handle that case. The default case here being that the bond would not be returned.
* Work with OpenZeppelin to see if we can bring this functionality into OZ Governance Core
* Collaborate with ScopeLift to bring in a few sensible defaults to the voting delay period which is currently set to only one block. This leaves the DAO open to attack and the MetaGov working group is agreed on a 24 hour delay to ensure the DAO time to protect itself if needed.
Agora is committed to building public goods and is already working closely with OpenZeppelin to bring innovations of Agora's Governor into OZ Governance Core.
Given that the proposal threshold of this new functionality will be the most important piece, there is a general consensus in the discussion group that `1,000 ENS` is the right initial value. This parameter can later be set governance and moved up and down as we see fit.
### Voting
We are putting this to a simple, for/again/abstain vote
### Next Steps
Should the vote pass, Agora will be responsible for:
* closing out the implementation
* working with ScopeLift to review the code and add in the Voting Delay logic
* securing and organizing the audits
* making any changes raised by the auditors
* getting the code ready for a governor upgrade
#### Auditing
Given the potential impact of the change, we are going to work with the ENS MetaGov stewards to do 2 audits on this code: one chosen by Agora, and the other chosen by the stewards.
Agora recommends using [OpenZeppelin](https://www.openzeppelin.com/security-audits), a reputable and top quality auditor in the governance space.
Agora recommends that the MetaGov stewards pick from: [CodeArena](https://code4rena.com/), [Trail of Bits](https://www.trailofbits.com/services/software-assurance/blockchain/), [Spearbit](https://spearbit.com/) or [Trust Security](https://www.trust-security.xyz/services). Each of these are quality auditing firms with a proven track record of working with governance contracts.
Both of these audits will be funded by ENS, and code changes will be implemented by Agora as part of their service contract with ENS, at no additional charge.
Results and changes will be posted for everyone to see
### Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
**Quorum**: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "Yes" and "Abstain" votes combined. "No" votes do not count towards quorum.
**Approval**: Once the quorum is reached, the proposal requires a simple majority (>50%) of "Yes" votes among the "Yes" and "No" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP 5.16] \[Executable] Reimbursement of ENS Labs’ legal fees in eth.link litigation
::authors
| **Status** | Passed |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-16-executable-reimbursement-of-ens-labs-legal-fees-in-eth-link-litigation/19613) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/33657496545373741813637578444724485346468737982573562831880427564621945332995) |
### Summary
This executable proposal seeks to implement the reimbursement payment to ENS Labs for the legal fees incurred while pursuing litigation to protect the eth.link domain. The reimbursement was approved in the previously passed social proposal [EP 5.3](./5.3).
### Background
The lawsuit that ENS filed in federal district court in Arizona to maintain ownership and control over eth.link has been resolved, and on 26 August 2024, the Court officially closed this case.
ENS Labs has maintained full ownership and control over the eth.link domain and, therefore, ENS Labs has achieved the initial objective they had when first filing the complaint and obtaining injunctive relief. To reach this outcome, ENS Labs has spent in total 1,218,669.76 USD. This legal action was necessary to defend the ENS ecosystem and maintain control of the eth.link domain, a critical infrastructure component since 2017.
#### Links
* [EP 5.3 Snapshot Vote](https://snapshot.org/#/ens.eth/proposal/0x456ccb438eed5d189cbe51e5e36a88d2bb4dc0c61f12f6d9e310a7ba4798d5fc)
* [Forum Discussion on EP 5.3](https://discuss.ens.domains/t/ep5-2-social-determine-ens-labs-next-steps-in-eth-link-litigation/18756)
### Specification
This executable proposal will initiate a transfer of 1,218,669.76 USDC from the ENS DAO treasury to ENS Labs. This amount represents the final total of all legal expenses related to the eth.link litigation.
#### Transaction Details
* **From:** ENS DAO Treasury (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7)
* **To:** USDC Token Contract (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
* **Recipient:** ENS Labs (0x690F0581eCecCf8389c223170778cD9D029606F2)
* **Amount:** 1,218,669.76 USDC (1218669760000 considering USDC's 6 decimal places)
* **Purpose:** Reimbursement for legal fees in eth.link litigation
This transaction calls the `transfer` function of the USDC contract, transferring 1,218,669.76 USDC to ENS Labs' address.
### Rationale
The ENS community, through the passage of EP 5.3, has demonstrated its support for reimbursing ENS Labs for the legal expenses incurred in protecting the eth.link domain. This reimbursement acknowledges the efforts made by ENS Labs to safeguard a critical asset of the ENS ecosystem. It ensures that the financial burden of this legal action does not fall solely on ENS Labs, particularly given that their actions were taken to benefit the entire ENS community.
***
*Note - When the original snapshot for the social vote was posted it was numbered as 5.2, but it should have been 5.3. It has been renumbered in the official ENS documentation. Some links point to forum discussions and Snapshots that show the original duplicitive label of 5.2*
## \[5.17.1] \[Social] Funding Request: ENS Meta-Governance Working Group Term 5 (Oct. Window)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-17-1-social-funding-request-ens-meta-governance-working-group-term-5-oct-window/19677) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x0f906ef744da4aace051305dff824fe7b000814f23af36f037f0dd23a1a94f98) |
### Abstract
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](/dao/proposals/1.8)) and further required by [this snapshot proposal in Nov. 2023 modifying steward rules](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Metagov Multisig to fulfill anticipated budgetary needs through the next formal funding window in April 2025.
| | USDC | ETH | $ENS |
| -------------------------- | ---- | --- | ---- |
| ENS Meta-Gov Main Multisig | 254k | 0 | 0 |
This amount will cover all expected expenses outlined below while leaving a 100k prudent reserve to ensure continuity if future funding is delayed.
### Description
**Current Metagov Wallet Balances**
| | USDC | ETH | $ENS |
| -------------------------- | ---- | ---- | ---- |
| ENS Meta-Gov Main Multisig | 286k | 83.7 | 51 |
\*Up to date balance information can be found at [https://enswallets.xyz](https://enswallets.xyz)
### Expenditures
Meta-Gov sets aside funds to ensure coverage for mission-critical initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives.
#### Expected Expenses through April 2025
| | USDC | ETH | $ENS |
| ---------------------------------- | ---- | --- | ---- |
| Steward + Secretary Compensation ¹ | 294k | - | - |
| Governance | - | - | - |
| Contract Audits | 155k | - | - |
| DAO Tooling | 150k | - | - |
| Discretionary | 40k | - | - |
| Total Balance | 639k | - | - |
#### Governance Distributions
The governance distribution strategy for Term 6 will be announced and posted as a temp check in the forum. This strategy will then be codified by a DAO vote.
#### Description of Initiatives/Pods
**Steward + Secretary Compensation**: Working Group Steward and Secretary compensation as required by [revised steward working group rules](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) and [totaling $294,000 USDC to cover the costs for all 9 stewards and supporting roles for a 6 month period](https://discuss.ens.domains/t/ens-dao-steward-compensation/18063).
¹This is the expected compensation amount based on existing compensation. The Meta-governance working group is required by [EP 4.8](https://docs.ens.domains/dao/proposals/4.8) to announce compensation ahead of the next term's steward nominations. **The current Term 5 stewards will also be proposing Term 6 compensation numbers to the DAO to ensure consensus. This proposal will take place before the Term 6 nominations to comply with \[EP 4.8].**
**Governance**: Fee reimbursements and initiatives related to reducing friction in the governance process. This can also include $ENS distributed in order to lower barriers to the governance proposal process. The $ENS distributions to stewards and service providers falls into this category.
**Contract Audits**: Meta-governance maintains a balance to be used for contract audits. These audits are performed independently on contracts that are to be included in executable proposals if those contracts impact or affect any ENS protocol or ENS DAO contracts or processes. Examples would be any proposed changes to the ENS DAO governor contract or protocol related contracts such as the registrar.
This line item is larger than normal because Meta-governance is anticipating potential audits for both governor upgrades and contracts from Service Providers that are contributing to the ENS v2 work.
**DAO Tooling**: Developing interfaces and dashboards to improve the governance process and increase transparency across the DAO. An example of DAO tooling spend is our current engagement with Agora as they help build out an enhanced DAO proposal flow to streamline the proposal process.
**Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments. In this cycle, we've consolidated the former DAO Sponsorship category into this discretionary category.
### Conclusion
This funding request will allow the ENS Meta-Governance Working Group to continue its essential work in providing governance oversight, supporting the management and operation of working groups, and ensuring effective treasury management for the DAO. The requested funds will enable us to maintain our ongoing initiatives and develop new tools to enhance the governance process. We are grateful for the community's ongoing support and engagement, which is crucial to the success of the ENS DAO. The Meta-Governance Working Group remains committed to serving the ENS community and driving the long-term growth and sustainability of the ecosystem.
## \[5.17.2] \[Social] Funding Request: ENS Ecosystem Working Group
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-17-2-social-funding-request-ens-ecosystem-working-group/19678) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xfe303865510b5ef7fabee2bcbd5081afa01f276195f57e1561ff27c477459984) |
### Abstract
The ENS Ecosystem Working Group requests funding of 836,000 USDC to support operations through April 2025. This is the only funding request of Term 5.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding builders and projects that are ENS-specific or ENS-centric.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| ------------------------------------------------------------------------------------------------------ | :-----: | :-: | :--: |
| [ENS Ecosystem Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 836,000 | -- | -- |
### Description
#### ENS Ecosystem Multisig Balances - As of October 4, 2023
The ENS Ecosystem Working Group multisigs:
| Multisigs | USDC | ETH |
| :--------------------------------------------------------------------------------------- | -------: | -------: |
| [Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 82k | 81.7 |
| [IRL](https://etherscan.io/address/0x536013c57daf01d78e8a70cad1b1abada9411819) | 21k | - |
| [Hackathon](https://etherscan.io/address/0x9b9c249be04dd433c7e8fbbf5e61e6741b89966d) | 22k | 9.8 |
| [Newsletter](https://etherscan.io/address/0x13aEe52C1C688d3554a15556c5353cb0c3696ea2) | 4k | - |
| **Total** | **129k** | **91.5** |
#### Reserved for Initiatives
Ecosystem reserves amounts to make sure we can cover initiatives that are important. Reserving is not the same as spending it. For example, we are reserving 100k for the bug bounty program. The actual spend will depend on what, if any, bugs are discovered.
| Initiatives | USDC | ETH |
| :-------------- | -------: | -----: |
| Hackathon | 300k | - |
| Grants | 200k | 10 |
| Library Support | 100k | - |
| Bug Bounty | 100k | - |
| Audit Support | 100k | - |
| IRL | 50k | - |
| Support | 15k | - |
| Reserved Total | **865k** | **10** |
**Reconciliation**
| Initiatives | USDC | ETH |
| :-------------- | ---------: | -----: |
| Current Balance | 129k | 91.5 |
| Reserved | (865k) | (10) |
| Buffer | (100k) | (81.5) |
| Total | **(836k)** | **-** |
Ecosystem WG is requesting 836,000 in USDC and zero ETH. This request ensures that there are sufficient resources to meet the expected future needs of the ecosystem working group. Buffer is an additional reserve to cover unforeseen expenses or opportunities.
#### Initiatives Description
| Initiative | Description |
| --------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hackathons | For our main partner, ETHGlobal, payments are made in December for the following calendar year. We anticipate participating in at least 7 events. |
| Grants | Grants consist of [builder grants](https://discuss.ens.domains/t/term-5-grants-summary/18921), [Gitcoin rounds](https://discuss.ens.domains/t/gg20-ens-identity-round-conclusion/19301), and [ENS subgraph](https://discuss.ens.domains/t/ens-subgraph-migration-to-the-decentralised-version/19183/4) subsidization. |
| Bug Bounty | Supports the official bug bounty program of ENS administered by [immunefi](https://immunefi.com/bug-bounty/ens/information/). |
| Library Support | Support open-source libraries that ENS depends on, either directly or through a program such as [drips](https://blog.ens.domains/post/supporting-software-dependencies-with-drips). |
| Audit Support | Provide funding for auditing smart contracts that have significant prominence in the ecosystem or are expected to see widespread use. |
| IRL | Funding relates to events that coincide with conferences, such as ethCC & Devcon. |
| Support | Support mods for social platforms, technical and non-technical educational content and the [newsletter](https://discuss.ens.domains/t/ens-dao-newsletter-70-09-24-24/19621). |
#### Historical Spending
For historical spending consult the spending reports for [Q1](https://discuss.ens.domains/t/term-5-working-group-spending-summary-2024-q1/19146) & [Q2](https://discuss.ens.domains/t/term-5-working-group-spending-summary-2024-q2/19449), which are released within 30 days after the end of each quarter.
***
*This proposal was prepared by [slobo.eth](https://x.com/AlexSlobodnik), Lead Steward of the Ecosystem Working Group.*
## \[5.17.3] \[Social] Funding Request: ENS Public Goods Working Group
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-17-3-social-funding-request-ens-public-goods-working-group/19679) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xafb1325f49057dd20fabf2908531da93565172525309a0a3a914daa7f773b0c6) |
### Abstract
The ENS Public Goods Working Group requests funding to support operations until the next funding window in April 2025.
The Public Goods working group funds projects and builders improving the Web3 ecosystem. This funding stream is authorized in Article III of the ENS DAO Constitution. The funding supports initiatives related to open-source software, tooling, research and any practical implementations that broadly benefit a wide range of users of Ethereum and Web3.
The funds requested extends current need through to next term to ensure that next season’s stewards have some available funding before the next funding window available.
The total request in this proposal is 226k USDC to be transferred from the DAO wallet to the Public Goods Working Group.
### Specification
This specification is the amount requested from the DAO treasury to the Public Goods Multisig to fulfill anticipated budgetary needs through the next formal funding window in April 2025.


Of these funds, 256k is allocated to large grants builders and initiaves through to the end of 2024. This leaves approximately 89k USD and 29.5 Ether unallocated and available to be rolled into the next term.

**Note #1:** To ensure grantees have consistency, the funds requested for this category carry the program to Q3 which is an exception from the other spending categories which plan only through April 2025.
**Note #2:** The PG Working group budget request is in USDC only; our balance of ETH will rollover to next term, but it will be left to future stewards discretion to swap it, keep it or return it to the treasury.

Subtracting the 89k available to rollover from 2024, the unmet need is 226k USDC which is the sum total to be included as the specification of this funding request.
### Spending Categories Explained
#### Builder Grants
This new category consolidates the existing Large and Small grants under one category and program title. The Public Good working group has been working with a provider to create a unified platform which will be announced during frENSday in Bangkok on 11/11/2024. To ensure grantees have consistency, the funds requested for this category carry the program through to Q3 which is an exception from the other spending categories which plan through to April 2025.
* **Small Grants**\
Multiple micro-grants will be distributed to builders via the Builder Grants platform to be launched. We have added the amount expected to spend in the next 5 months with the same amounts distributed in the last rounds.
* **Large Grants**\
Grants up to 50k USDC with applications accepted on a rolling basis throughout the term. Large Grants will continue in Q4. The working group will continue to focus on strengthening impact measurements accomplished by grantees during the previous Large Grants cycle.
#### PG Perpetual Bounty
Launched during ETHLondon in March 2024, this is a perpetual pool of funds that is available to builders who are developing projects which align with the principles of public goods in the web3 space.
This funding pool is available at any time, but also marketed specifically towards builders who are not eligible for ENS-related bounties during hackthons, but deserve support for their public goods mission.
#### Events and Hackathons
The working group provides support to Public Goods events and hackathons. These funds cover expenses related to event sponsorship, bounties, judging and other participatory support roles during events.
**The current earmarked events are:**
* ETHGlobal Bangkok
* Devcon
* ETHDenver 2025
\*This list is not set as several events are still in planning stages for Q1 of 2025. The PG stewards continuously assess opportunities for expanding the public goods conversation and collaborations.
#### Discretionary
The funds in this category are reserved for additional grant opportunities and expenses that arise during the term. Spending in this category is at the discretion of the working group stewards.
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ens-dao-steward-compensation-structure-term-6/19739) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x88de13f2f088390262d1d5e7db9ddff5a74d0b878fedf590a0448c32692078ba) |
## \[EP 5.18] \[Social] ENS DAO Steward Compensation Structure - Term 6
::authors
### Background
The ENS DAO Working Group Rules place the responsibility for steward compensation on the Metagov working group.
**Working Group Rules:**
[\[EP0.4\] \[Social\] Proposal: Creation of Foundational Working Groups and Working Group Rules](https://docs.ens.domains/v/governance/governance-proposals/term-0/ep4-social-proposal-creation-of-foundational-working-groups-and-working-group-rules)
[\[EP12\]\[Social\] Working Group Rules ](https://discuss.ens.domains/t/ep12-social-working-group-rules/12953)
With the passing of [this social proposal](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) in Term 4, these two rules were added:
> **10.4.** The Meta-Governance working group are responsible for defining standards for fair compensation ('Compensation Guidelines').
> **10.5.** The Compensation Guidelines shall be defined prior to the Nomination Window for each term and can only take effect for the following term.
### Summary
In accordance with rule 10.5, This post outlines the proposed compensation structure for ENS DAO stewards during Term 6. The structure builds upon previous compensation models but includes several important changes. Notably, this compensation proposal will be put to a DAO vote for approval.
### Proposed Compensation Structure
#### USDC Compensation
The total USDC compensation is the same as Term 5. The base compensation structure remains similar to previous terms, with some adjustments:
| Role | Quantity | Per Steward Per Month | Per Steward Per Term | Total per Term |
| ------------ | -------- | --------------------- | -------------------- | -------------- |
| Steward | 6 | $4,000 | $24,000 | $288,000 |
| Lead Steward | 3 | $5,500 | $33,000 | $198,000 |
| Secretary | 1 | $5,500 | $33,000 | $66,000 |
| Scribe | 1 | $3,000 | $18,000 | $36,000 |
| **Total** | | | | **$588,000** |
([previous structure linked here for reference](https://discuss.ens.domains/t/ens-dao-steward-compensation/18063))
Key changes:
* The discretionary amount has been removed.
* The $3,000 previously allocated to each WG for discretionary compensation has been split evenly among the stewards of that working group.
* Regular stewards will now receive $4,000 USDC per month (up from $3,000).
* Lead stewards will now receive $5,500 USDC per month (up from $4,500).
#### $ENS Token Distribution
We are introducing a new structure for $ENS governance distribution to stewards:
1. Each steward will receive $ENS tokens equal in value to their total USDC compensation for the year.
2. The $ENS tokens will be distributed on July 1st, via 2-year linear vesting contracts.
3. The $ENS token price used to calculate the number of tokens each steward receives will be derived from the average daily price of the token between January 1st and July 1st of the term.
4. The vesting period will start from the beginning of the term (January 1st), meaning 6 months of vesting will have already occurred at the time of distribution.
Example calculation:
* A regular steward receiving $48,000 USDC for the year would also receive $48,000 worth of $ENS tokens.
* If the average $ENS price is $12 when calculated on July 1st, the steward would receive 4,000 $ENS tokens in a 2-year linear vesting contract.
* At the time of distribution (July 1st), 25% of the tokens (1,000 $ENS) would have already vested.
This structure ensures that stewards' token compensation aligns with their USDC compensation and incentivizes long-term commitment to the DAO.
#### Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
1. **Quorum**: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "Yes" and "Abstain" votes combined. "No" votes do not count towards quorum.
2. **Approval**: Once the quorum is reached, the proposal requires a simple majority (>50%) of "Yes" votes among the "Yes" and "No" votes to pass. "Abstain" votes do not count towards the approval calculation.
If approved, this structure will be implemented for Term 6. If not approved, the Metagovernance Working Group will reassess and propose an alternative structure based on feedback received.
## \[EP 5.19] \[Social] Governance Distribution Pilot Program
::authors
| **Status** | Passed, approved 30K $ENS distribution program |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-19-social-governance-distribution-pilot-program/19759) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xfa54ff2b55f0495c96ec2d8645241bcff48ca6afe1f4925fb51f29c4667252df) |
### Objective:
This proposal establishes a pilot program to distribute ENS governance to eligible DAO contributors who have been selected by the DAO to receive a grant, bounty, or other payment for services. The program would also serve as a pilot, and if successful, could become a long-term initiative, aiming to cover all DAO USDC and ETH recipients, while setting a policy for future governance distribution.
The intent is to engage contributors in governance. We believe governance distribution increases access to DAO governance, enhances the utility of the token, decreases the amount of tokens purely used in markets, increases delegation and the safety of the DAO, and helps align developers and other contributors who bring value to the DAO.
### Context:
* **Previous Distributions**:
* [90k ENS tokens to stewards](https://discuss.ens.domains/t/5-8-social-ens-steward-vesting-proposal/19059)
* [80k ENS tokens to service providers and security council members](https://discuss.ens.domains/t/distribution-of-80k-ens-tokens-to-service-providers-and-security-council-members/19541)
* **Proposed Distribution**:
* This vote is to determine if the program is approved and to select its budget within a range between 0 and 90k ENS.
### Matching Program:
The distributions are calculated using a progressive ratio, meaning that the more you receive in dollar value from the DAO, the more you will receive in absolute values in ENS, but less relatively to the amount, following a quadratic formula. The process is as follows:
1. **Calculate all eligible transfers**: First, we list all transfers from the various DAO wallets into external wallets from January to September 2024. Data is collected from the [ENS Ledger app](https://ens-ledger.app).
2. **Exclude ineligible transactions**: Transactions to Stewards, ENS Labs, Service Providers, and other transactions that are considered refunds or payments for goods are not counted.
3. **Calculate the square root of the total value received**: The total weights are calculated to determine the percentage of the budget each recipient will receive. That calculation and further details can be seen in [this spreadsheet](https://docs.google.com/spreadsheets/d/1hnrBSPy5efi2W0b4hd4y2BnAmRIfI0M5y4NgYGjEPms/edit?usp=sharing).
4. **Decide the program's total budget**: The total budget will be determined by this vote.
### Voting Method:
The vote will use a ranked choice voting system with options of 0, 30k, 60k, and 90k ENS.
An Instant Run-Off will be calculated, and if the budget option of 0 wins, or if the total votes are less than 1 million, then the proposal will be considered rejected.
### Distribution Table:
The table below is from the [ENS ledger](https://ens-ledger.app), excluding Stewards, Service Providers, ENS Labs, refunds, and internal wallets. ETHGlobal Hackers are bounties given by ETHGlobal to hackathon winners. The final number of hackers is still being calculated, but here it is presented as a maximum of 100. If the final number is less than this, then more ENS will be distributed to other recipients, and if it is greater, it will be capped at 100. This proposal covers transactions from January 2024 to September 2024, and the final table may be subject to change upon legal or technical review.
| | $ Received jan-sep 2024 | 30k ENS | % | 60k ENS | % | 90k ENS | % |
| ---------------------------------------- | ----------------------- | ------- | ---- | ------- | ---- | ------- | ---- |
| ETHGlobal | $ 190,000.00 | 1,441 | 13% | 2,883 | 26% | 4,324 | 39% |
| Karpatkey | $ 187,149.13 | 1,430 | 13% | 2,861 | 26% | 4,291 | 39% |
| @UGWST\_COM | $ 75,000.00 | 906 | 21% | 1,811 | 41% | 2,717 | 62% |
| Rotki | $ 53,973.38 | 768 | 24% | 1,536 | 48% | 2,305 | 73% |
| wslyvh.eth | $ 50,004.00 | 739 | 25% | 1,479 | 50% | 2,218 | 75% |
| gashawk.eth | $ 40,000.00 | 661 | 28% | 1,323 | 56% | 1,984 | 84% |
| buidlguidl.eth | $ 35,000.00 | 619 | 30% | 1,237 | 60% | 1,856 | 90% |
| borderlessafrica.eth | $ 30,000.00 | 573 | 32% | 1,145 | 65% | 1,718 | 97% |
| daemon.eth | $ 27,000.00 | 543 | 34% | 1,087 | 68% | 1,630 | 103% |
| Revoke.Cash | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| Onthis | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| ipns.eth | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| Fluidkey | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| Blockscout | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| beaconchain.eth | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| 1w3.eth | $ 25,000.00 | 523 | 36% | 1,046 | 71% | 1,568 | 107% |
| Firefly | $ 20,000.00 | 468 | 40% | 935 | 79% | 1,403 | 119% |
| EIP-7212 | $ 20,000.00 | 468 | 40% | 935 | 79% | 1,403 | 119% |
| Urbe Campus | $ 19,680.00 | 464 | 40% | 928 | 80% | 1,392 | 120% |
| ethdaily.eth | $ 14,797.60 | 402 | 46% | 804 | 92% | 1,207 | 139% |
| Discord Support | $ 13,000.00 | 377 | 49% | 754 | 99% | 1,131 | 148% |
| Dappnode | $ 12,500.00 | 370 | 50% | 739 | 101% | 1,109 | 151% |
| generalmagic.eth | $ 11,563.43 | 356 | 52% | 711 | 105% | 1,067 | 157% |
| Immunefi | $ 10,200.00 | 334 | 56% | 668 | 111% | 1,002 | 167% |
| Pugson | $ 10,000.00 | 331 | 56% | 661 | 112% | 992 | 169% |
| Juicebox | $ 10,000.00 | 331 | 56% | 661 | 112% | 992 | 169% |
| frolic.eth | $ 10,000.00 | 331 | 56% | 661 | 112% | 992 | 169% |
| ETHDenver | $ 10,000.00 | 331 | 56% | 661 | 112% | 992 | 169% |
| Drips | $ 10,000.00 | 331 | 56% | 661 | 112% | 992 | 169% |
| Lemma | $ 9,998.67 | 331 | 56% | 661 | 112% | 992 | 169% |
| Tally | $ 8,999.54 | 314 | 59% | 627 | 119% | 941 | 178% |
| pairwise.eth | $ 8,402.18 | 303 | 61% | 606 | 123% | 909 | 184% |
| @navad | $ 7,500.00 | 286 | 65% | 573 | 130% | 859 | 195% |
| apoorv.eth | $ 7,021.88 | 277 | 67% | 554 | 134% | 831 | 201% |
| leticiaferraz.eth | $ 6,949.32 | 276 | 67% | 551 | 135% | 827 | 202% |
| @Sagamore | $ 6,000.00 | 256 | 73% | 512 | 145% | 768 | 218% |
| Socket | $ 5,000.00 | 234 | 79% | 468 | 159% | 701 | 238% |
| Latin Hackathon | $ 5,000.00 | 234 | 79% | 468 | 159% | 701 | 238% |
| eth-mexico.eth | $ 5,000.00 | 234 | 79% | 468 | 159% | 701 | 238% |
| aynieducativo.eth | $ 5,000.00 | 234 | 79% | 468 | 159% | 701 | 238% |
| @adhd | $ 5,000.00 | 234 | 79% | 468 | 159% | 701 | 238% |
| ENS Fairy | $ 4,781.34 | 229 | 81% | 457 | 163% | 686 | 244% |
| glodollar.eth | $ 3,762.22 | 203 | 92% | 406 | 183% | 608 | 275% |
| weird3.eth | $ 3,000.00 | 181 | 103% | 362 | 205% | 543 | 308% |
| Event Support | $ 3,000.00 | 181 | 103% | 362 | 205% | 543 | 308% |
| daveytea.eth | $ 2,818.29 | 176 | 106% | 351 | 212% | 527 | 318% |
| @solidityhaxor | $ 2,500.00 | 165 | 112% | 331 | 225% | 496 | 337% |
| @haoce505 | $ 2,500.00 | 165 | 112% | 331 | 225% | 496 | 337% |
| @h4nt3rx | $ 2,500.00 | 165 | 112% | 331 | 225% | 496 | 337% |
| stephancill.eth | $ 2,367.89 | 161 | 116% | 322 | 231% | 483 | 347% |
| Scope.sh | $ 2,367.89 | 161 | 116% | 322 | 231% | 483 | 347% |
| Kiwi News | $ 2,367.89 | 161 | 116% | 322 | 231% | 483 | 347% |
| bloomnetwork.eth | $ 1,881.11 | 143 | 130% | 287 | 259% | 430 | 389% |
| modularcrypto.eth | $ 1,818.29 | 141 | 132% | 282 | 264% | 423 | 395% |
| aexek.eth | $ 1,750.00 | 138 | 134% | 277 | 269% | 415 | 403% |
| @austinoa012 | $ 1,000.00 | 105 | 178% | 209 | 356% | 314 | 533% |
| illuminated.eth | $ 940.56 | 101 | 183% | 203 | 367% | 304 | 550% |
| dhive.eth | $ 940.56 | 101 | 183% | 203 | 367% | 304 | 550% |
| pabl0cks.eth | $ 877.74 | 98 | 190% | 196 | 379% | 294 | 569% |
| iviangita.eth | $ 877.74 | 98 | 190% | 196 | 379% | 294 | 569% |
| easlabs.eth | $ 877.74 | 98 | 190% | 196 | 379% | 294 | 569% |
| 2118.eth | $ 877.74 | 98 | 190% | 196 | 379% | 294 | 569% |
| andrewpage.eth | $ 780.00 | 92 | 201% | 185 | 403% | 277 | 604% |
| ETHGlobal Hackers (max 100 participants) | $ 500.00 | 72 | 245% | 144 | 491% | 216 | 736% |
## \[EP5.2] \[Executable] Commence Streams for Service Providers
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep5-2-executable-commence-streams-for-service-providers/18615) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/63865530602418424570813160277709124551851041237648860550576561576702951975816) |
This EP will initiate the Streams for Service Providers as selected on [EP4.9](https://docs.ens.domains/dao/proposals/4.9)
### Abstract
[EP 4.7](https://docs.ens.domains/dao/proposals/4.7) proposed the concept of Streams for service providers and set its budget at $3.6M per annum. EP4.9 selected the following Service providers and their annual budget:
| Service Provider Name | Annual Stream |
| ------------------------ | ------------- |
| ETH.LIMO | $500,000.00 |
| NameHash Labs | $600,000.00 |
| Resolverworks.eth | $700,000.00 |
| Blockful | $300,000.00 |
| Unruggable | $400,000.00 |
| Wildcard Labs | $200,000.00 |
| Ethereum Follow Protocol | $500,000.00 |
| Namespace | $200,000.00 |
| UNICORN.ETH | $200,000.00 |
The Metagov Working Group has decided this will be implemented in the following manner:
1. Superfluid has been selected as the stream platform (details of which can be found on [this RFP](https://discuss.ens.domains/t/rfp-stream-platform-for-ens-service-providers/18448))
2. A new wallet, the "[Stream Management Pod](https://app.safe.global/settings/setup?safe=eth:0xB162Bf7A7fD64eF32b787719335d06B2780e31D1)" has been created as a Global.Safe (Gnosis Safe) wallet. It requires 3 out of 5 signatures to execute any transaction. Its members are the 3 Metagov Stewards, the secretary and the DAO Governor contract.
3. **This EP includes 5 Executable Transactions**, as follows:
1. **APPROVE** Superfluid contracts to wrap one month worth of USDC streaming (300,000 USDC);
2. **WRAP** one month worth of USDC streaming (300,000 USDC to USDCx);
3. **START A STREAM** to the Stream Management Pod of 0.114155251141552512 USDC per second \[1];
4. **APPROVE** AutoWrap \[2] contract to wrap an additional 5.1M USDC (this, added to the already wrapped 300k, should be enough to cover 18 months of the stream, after that a new EP will be required to keep the stream running);
5. **ENABLE AUTO-WRAP** to keep wrapping USDC to USDCx on a monthly basis (lower limit 200,000, upper limit 500,000).
4. Meanwhile the Stewards are reaching out to all representatives of the stream providers. Alex Urbelis, the general Counsel for ENS Labs, has drafted a service provider agreement and is acquiring the services of Urbelis to run a basic KYC and Sanctions protection. All Service Providers will be required to go through this process before receiving their first stream.
5. On February 1st Stream Management Pod will start creating individual streams to the Organizations who have completed the steps outlined in bullet #4. Because of Superfluid unique no-upfront-capital-lockup streams, it means that when all of 9 Service Providers Streams start, the Stream Management Pod will be forwarding 100% of the money it receives directly into the Service Providers. \[3]
#### Notes
\[1]: USDC has a precision of 6 decimal places, but SuperUSDC has a precision of 18 decimals. The value of 0.114155251141552512 per second corresponds to approximately 9863.01 USDC per day and in 3,600,000.000000000018432 USDC per year in a non-leap year. In leap years (such as the current one) it will mean an extra $9.8K is paid in the 29th of February.
\[2]: [Autowrapper](https://etherscan.io/address/0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d#code) is a [series](https://etherscan.io/address/0x30aE282CF477E2eF28B14d0125aCEAd57Fe1d7a1#code) of [contracts](https://etherscan.io/address/0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d#code) developed by superfluid. When pinged (and anyone would be able to ping it), if the amount of tokens that the DAO has wrapped is below the lower limit, it will automatically wrap new tokens in order to keep the stream running. The goal is to reduce smart contract risk. If Superfluid is somehow hacked, ENS will not lose more than the upper limit set here (about 50 days worth of funds). If both Superfluid AND the autowrapper are hacked at the same time, ENS cannot lose more than the maximum USDC allowance (18 months worth of funds).
\[3]: Any capital that remains in the pod (due to the difference between the day this EP is executed and the day the last Service Provider stream is active) will be still considered under the DAO's ownership and will be used only as a buffer (if autowrapper fails, we will have some weeks to resolve it without interrupting payments) and to solve any logistical issues with service providers. It will NOT count towards Metagov's budget nor it will it be used to any other purpose than the service provider management.
### Specification
We will now details the transactions to be executed on this EP:
| Operation | Target | Decoded Calldata | Raw Calldata |
| ------------------------------------------------------------ | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| approve USDCx SuperToken contract to transfer 300k USDC | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 (USDC) | `function approve(address 0x1BA8603DA702602A8657980e825A6DAa03Dee93a, uint256 300000000000)` | 0x095ea7b30000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a00000000000000000000000000000000000000000000000000000045d964b800 |
| wrap 300k USDC to USDCX | 0x1BA8603DA702602A8657980e825A6DAa03Dee93a (Super-USDC) | `function upgrade(uint256 300000000000000000000000)` | 0x45977d03000000000000000000000000000000000000000000003f870857a3e0e3800000 |
| start flow to Safe with the flowrate of 0.1141... per second | 0xcfA132E353cB4E398080B9700609bb008eceB125 (Superfluid) | `function setFlowrate(address 0x1BA8603DA702602A8657980e825A6DAa03Dee93a, address 0xB162Bf7A7fD64eF32b787719335d06B2780e31D1, int96 114155251141552512) ` | 0x57e6aa360000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a000000000000000000000000b162bf7a7fd64ef32b787719335d06b2780e31d100000000000000000000000000000000000000000000000001958f989989a980 |
| approve auto-wrap for 5.1M | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 (USDC) | `function approve(address 0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d, uint256 5100000000000` | `0x095ea7b30000000000000000000000001d65c6d3ad39d454ea8f682c49ae7744706ea96d000000000000000000000000000000000000000000000000000004a36fb03800` |
| create auto-wrap schedule | 0x30aE282CF477E2eF28B14d0125aCEAd57Fe1d7a1 (Autowrapper) | `function createWrapSchedule (address 0x1BA8603DA702602A8657980e825A6DAa03Dee93a, address 0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d, address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, uint64 3000000000, uint64 1814400, uint64 4320000` | `0x5626f9e60000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a0000000000000000000000001d65c6d3ad39d454ea8f682c49ae7744706ea96d000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000001baf80000000000000000000000000000000000000000000000000000000000041eb00` |
All contracts have verifiable code. You can use tools such as the [Calldata decoder](https://tools.deth.net/calldata-decoder) to verify the correctness of the calldata and etherscan to look deeper into them. You can also *simulate the transactions yourself* using [this repo](https://github.com/d10r/ens-streams).
The terms for the createWrapSchedule are the address of the superToken (super-usdc), the address of the Strategy contract, the address of the base token (USDC), the expiry (set to the far future), lowerLimit and upperLimit. These last two are set in seconds and mean that if, when the autowrapper is pinged, the stream has less than 21 days in it's runway, then it will automatically wrap 50 days worth of funds.
## \[EP 5.20] \[Social] ENS Endowment Investment Policy Statement
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-proposal-for-introduction-of-ens-investment-policy-statement/19568) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x085a1e40c264ffd44567b6dce889f5943e72cfa8442eaeb81819261a38f0bd0a) |
### Abstract
This proposal suggests introducing and implementing an [Investment Policy Statement (IPS)](https://github.com/ensdomains/docs/blob/master/src/public/governance/dao-investment-policy.pdf) for the ENS Endowment.
The Investment Policy Statement (“IPS”) outlines the principles and guidelines for the effective management of the ENS Endowment Fund (the “Endowment”). And provides additional clarity to the Endowment Manager in their duties of achieving the mandate of the ENS Endowment established in [EP 2.2.4](https://discuss.ens.domains/t/ep2-2-4-social-rfp-ens-endowment/14069).
### Specification
The creation and implementation of the [IPS](https://github.com/ensdomains/docs/blob/master/src/public/governance/dao-investment-policy.pdf), will serve the following purposes:
1. Define and assign the responsibilities of all parties involved in the Endowment.
2. Establish clear investment goals and objectives for the Endowment assets.
3. Offer guidance and limitations to the Endowment Manager regarding the investment of the Endowment assets.
4. Establish a basis for evaluating the performance of the Endowment Manager.
5. Express the prudent standards that are expected in the management of the Endowment assets.
The proposed ENS Investment Policy Statement to be ratified can be read [here](https://github.com/ensdomains/docs/blob/master/src/public/governance/dao-investment-policy.pdf).
As specified in the IPS, this document will be continually reviewed annually.
#### Updates from Feedback
Following discussions, the community provided feedback on the draft IPS posted in the [September temp check post](https://discuss.ens.domains/t/temp-check-proposal-for-introduction-of-ens-investment-policy-statement/19568) and the weekly MetaGov calls.
Based on those discussions, the following changes have been incorporated into the final version of the IPS:
* **More conservative asset allocation:** Increase stablecoin allocation in the Endowment to 40% (up from 20%).
* **Regular transfers:** Introduce regular monthly transfers of income from the Controller to the Endowment to support continuous growth and reduce future funding requests.
### Proposal Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
* **Quorum:** The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
* **Approval:** Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
If approved, the ENS DAO should adopt the final Investment Policy Statement prepared by karpatkey for the ENS Endowment established under [EP 2.2.4](https://discuss.ens.domains/t/ep2-2-4-social-rfp-ens-endowment/14069). If not approved, karpatkey will reassess and propose an alternative structure based on the feedback received.
## \[EP 5.21] \[Social] Governance Security Bounty
::authors
| **Status** | Passed |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-governance-security-compensating-blockful-for-preventing-a-potential-attack-on-the-ens-dao/19710) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x5067725bef9cde0de0024adedb653a7a1752aefa726adf628b77048d85821a6d) |
### Summary
This proposal aims to compensate the blockful team for their work in identifying, analyzing, reporting and mitigating a severe vulnerability in ENS DAO's governance structure.
### Background
In March 2024, blockful uncovered a critical vulnerability that could have led to a [\~$150M](https://dune.com/steakhouse/ens-steakhouse) theft and protocol capture. Their subsequent work led to the implementation of the Security Council, significantly enhancing ENS DAO's resilience against attacks.
### Contribution Details
The team involved is a [different](https://discuss.ens.domains/t/blockful-service-provider-reports/19553#p-54163-other-contributions-not-related-to-service-provider-scope-14) squad than the one working on the scope of the [ENS service provider](https://discuss.ens.domains/t/blockful-service-provider-reports/19553). It was developed by 2 researchers, 1 smart contract engineer and 4 different auditors the team has worked with previously. Summing up to \~600 hours, the scope includes:
* Comprehensive vulnerability assessment and risk analysis: **[Here](https://mirror.xyz/research.blockful.eth/-PfMduhpxdypPrutofr6099T4ROpsAmX0fPNbvDgR_k)** is our detailed security report.
* Data analysis of ENS governance metrics and study of past DAO attacker's behaviors.
* Design, development and deployment of the Security Council contract and multisig.
* The Security Council was thought with several key features to balance security and decentralization.
* Smart contract implementation and testing ([GitHub](https://github.com/blockful-io/security-council-ens))
* Governance proposal drafting and support \[[1](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54), [2](https://snapshot.org/#/ens.eth/proposal/0xa0b1bfadf6853b5b0d59d3c4d73c434fc6389339887d05de805361372eb17c3a), [3](https://www.tally.xyz/gov/ens/proposal/42329103797433777309488042029679811802172320979541414683300183273376839219133)]
More details can be found on the links above for past proposals and the [report](https://mirror.xyz/research.blockful.eth/-PfMduhpxdypPrutofr6099T4ROpsAmX0fPNbvDgR_k).
### Compensation Rationale
As a team that is totally bootstrapped and never received any investment, this support us to keep it sustainable with the resources invested towards this initiative. The requested amount represents fair compensation for:
* The potential loss prevention of \~$150M, capture of the DAO and protocol. The attack is anything but theoretical and there are actually many groups of investors who specialize in "risk free value raiders". They have exerted the attack on other DAOs before. Currently there are [unknown whales](https://etherscan.io/address/0x245445940b317e509002eb682e03f4429184059d#tokentxns) buying ENS for +450 days and have \~2M ENS, showing how feasible the scenario is, more than the average quorum, in one wallet.
* A critical code bug bounty in [ENS is $250k USDC](https://immunefi.com/bug-bounty/ens/scope/#assets). Our work was much beyond identifying and disclosing.
* Significantly lower cost compared to standard rates charged by other security service providers in the DAO space, which typically demand liquid compensation. An example is that Open Zeppelin (one of the most reputable players in security) [charges $4M/year at Compound](https://compound.finance/governance/proposals/76), which recently [suffered](https://mirror.xyz/research.blockful.eth/v0GEP49oXP1gzMDlyP91-S4XIa8PIOd0vKq-6R8f54I) this type of attack.
* Months of dedicated work by the team involved (researchers, devs and auditors).
* The long-term value added to ENS through enhanced security.
* Our commitment to ENS's long-term success and continued contribution, as evidenced by the 2-year vesting schedule.
### Compensation Structure
* Total amount: 100k USDC + 15k vested ENS tokens
* Vesting period: 2 years
* Vesting start date: April 8, 2024 (date of initial research disclosure)
* Vesting schedule: Linear vesting
### Benefits to ENS DAO
* Sets a positive precedent that **responsible vulnerability disclosure and correction are rewarded**, encouraging future security contributions
* Preserves DAO treasury liquidity by using part of the bounty in ENS tokens instead of USDC or ETH
* Enhances governance security by increasing the number of engaged, security-focused token holders
### Conclusion
By approving this compensation, ENS DAO acknowledges the critical importance of security research and proactive governance improvements. The vesting structure ensures ongoing commitment and aligns incentives for continued contribution to ENS's security and stability.
### Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
Quorum: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
Approval: Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP 5.22] \[Executable] ENSv2 Development Funding
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-22-ensv2-development-funding-request/19762) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/33504840096777976512510989921427323867039135570342563123194157971712476988820) |
### Summary
This executable proposal seeks to implement the revised budget stream to ENS Labs develop, maintain and audit [ENSv2](https://discuss.ens.domains/t/ens-labs-development-proposal-ensv2-and-native-l2-support/19232). The motivation, justification, budget breakdown, and development plan was previously detailed in a [Temp Check](https://discuss.ens.domains/t/temp-check-ensv2-development-funding-request/19762) request.
### Background
With over 3 million .eth names and 20 million more ENS names registered by the likes of Coinbase, Uniswap, and Linea – ENS has become the standard for web3 identity. As Ethereum's roadmap evolves towards being rollup-centric, it's essential for ENS to adapt in parallel, ensuring it meets the needs of both the Ethereum ecosystem and its users.
To continue scaling and evolving ENS, ENS Labs is requesting an increase in its annual budget from $4.2M USDC to $9.7M USDC, and a one-time grant for future security audits of ENSv2. This revised funding is necessary for ENS Labs to develop, maintain, and audit ENSv2, a major upgrade that will enhance decentralization, flexibility, and scalability by leveraging Layer 2 solutions and redesigning the ENS protocol from the ground up.
#### Links
* [\[Temp Check\] ENSv2 Development Funding Request](https://discuss.ens.domains/t/temp-check-ensv2-development-funding-request/19762)
* [ENS Labs development proposal: ENSv2 and native L2 support](https://discuss.ens.domains/t/ens-labs-development-proposal-ensv2-and-native-l2-support/19232)
* [ENS Labs Transparency Reports](https://discuss.ens.domains/t/ens-labs-transparency-reports/19806)
### Specification
This executable proposal will initiate a new daily stream of 15,075.33 USDC from the ENS DAO treasury to ENS Labs, starting on January 1, 2025. This will run in addition to the existing streaming contract of 11,500 USDC/day at 0xB1377e4f32e6746444970823D5506F98f5A04201, for a total of 26,575.34 USDC/day ($9.7M USDC/year).
## \[EP 5.23] \[Executable] blockful's governance security bounty
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-23-executable-governance-security-bounty/19803) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/46071186312489687574960948336391811341595411932836110873328798657006776570015) |
### Summary
This proposal aims to compensate the blockful team for their work in identifying, analyzing, reporting and mitigating a severe vulnerability in ENS DAO's governance structure.
### Background
In March 2024, blockful uncovered a critical vulnerability that could have led to a [\~$150M](https://dune.com/steakhouse/ens-steakhouse) theft and protocol capture. Their subsequent work led to the implementation of the Security Council,
significantly enhancing ENS DAO's resilience against attacks.
### Contribution Details
The team involved is a [different](https://discuss.ens.domains/t/blockful-service-provider-reports/19553#p-54163-other-contributions-not-related-to-service-provider-scope-14) squad than the one working on the scope of the [ENS service provider](https://discuss.ens.domains/t/blockful-service-provider-reports/19553). It was developed by 2 researchers,
1 smart contract engineer and 4 different auditors the team has worked with previously. Summing up to \~600 hours,
the scope includes:
* Comprehensive vulnerability assessment and risk analysis: **[Here](https://mirror.xyz/research.blockful.eth/-PfMduhpxdypPrutofr6099T4ROpsAmX0fPNbvDgR_k)** is our detailed security report.
* Data analysis of ENS governance metrics and study of past DAO attacker's behaviors.
* Design, development and deployment of the Security Council contract and multisig.
* The Security Council was thought with several key features to balance security and decentralization.
* Smart contract implementation and testing ([GitHub](https://github.com/blockful-io/security-council-ens))
* Governance proposal drafting and support \[[1](https://snapshot.org/#/ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54), [2](https://snapshot.org/#/ens.eth/proposal/0xa0b1bfadf6853b5b0d59d3c4d73c434fc6389339887d05de805361372eb17c3a), [3](https://www.tally.xyz/gov/ens/proposal/42329103797433777309488042029679811802172320979541414683300183273376839219133)]
More details can be found on the links above for past proposals and the [report](https://mirror.xyz/research.blockful.eth/-PfMduhpxdypPrutofr6099T4ROpsAmX0fPNbvDgR_k).
### Compensation Rationale
As a team that is totally bootstrapped and never received any investment, this support us to keep it sustainable with the resources invested towards this initiative. The requested amount represents fair compensation for:
* The potential loss prevention of \~$150M, capture of the DAO and protocol. The attack is anything but theoretical and there are actually many groups of investors who specialize in "risk free value raiders". They have exerted the attack on other DAOs before. Currently there are [unknown whales](https://etherscan.io/address/0x245445940b317e509002eb682e03f4429184059d#tokentxns) buying ENS for +450 days and have \~2M ENS, showing how feasible the scenario is, more than the average quorum, in one wallet.
* A critical code bug bounty in [ENS is $250k USDC](https://immunefi.com/bug-bounty/ens/scope/#assets). Our work was much beyond identifying and disclosing.
* Significantly lower cost compared to standard rates charged by other security service providers in the DAO space,
which typically demand liquid compensation. An example is that Open Zeppelin (one of the most reputable players in security) [charges $4M/year at Compound](https://compound.finance/governance/proposals/76),
which recently [suffered](https://mirror.xyz/research.blockful.eth/v0GEP49oXP1gzMDlyP91-S4XIa8PIOd0vKq-6R8f54I) this type of attack.
* Months of dedicated work by the team involved (researchers, devs and auditors).
* The long-term value added to ENS through enhanced security.
* Our commitment to ENS's long-term success and continued contribution, as evidenced by the 2-year vesting schedule.
### Compensation Structure
* Total amount: 100k USDC + 15k vested ENS tokens
* Vesting period: 2 years
* Vesting start date: April 8 2024 (date of initial research disclosure)
* Vesting schedule: Linear vesting
* Will be sent to the meta-governance multisig transferred and vested to blockful.
### Benefits to ENS DAO
* Sets a positive precedent that **responsible vulnerability disclosure and correction are rewarded**,
encouraging future security contributions
* Preserves DAO treasury liquidity by using part of the bounty in ENS tokens instead of USDC or ETH
* Enhances governance security by increasing the number of engaged security-focused token holders
### Conclusion
By approving this compensation, ENS DAO acknowledges the critical importance of security research and proactive governance improvements. The vesting structure ensures ongoing commitment and aligns incentives for continued contribution to ENS's security and stability.
## \[EP 5.24] \[Executable] Term 5 Q4, Collective Working Group Funding Proposal
::authors
| **Status** | Rejected |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-24-executable-term-5-q4-collective-working-group-funding-proposal/19801) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/6949396467348678571876890705367894936837088742488849089767544172635343148173) |
### Description
This proposal executes all three Working Group funding requests for the October 2024 funding window as passed in [EP 5.17.1](https://discuss.ens.domains/t/5-17-1-social-funding-request-ens-meta-governance-working-group-term-5-oct-window/19677), [EP 5.17.2](https://discuss.ens.domains/t/5-17-2-social-funding-request-ens-ecosystem-working-group/19678), and [EP 5.17.3](https://discuss.ens.domains/t/5-17-3-social-funding-request-ens-public-goods-working-group/19679) as well as [EP 5.21](https://snapshot.org/#/ens.eth/proposal/0x5067725bef9cde0de0024adedb653a7a1752aefa726adf628b77048d85821a6d) and [EP 5.19](https://snapshot.org/#/ens.eth/proposal/0xfa54ff2b55f0495c96ec2d8645241bcff48ca6afe1f4925fb51f29c4667252df).
For more detail, view the [ENS Governance docs](https://basics.ensdao.org/funding-requests/funding-requests)
### Proposal Components
#### 1) [Meta-governance Funding Request \[EP 5.17.1\]](https://discuss.ens.domains/t/5-17-1-social-funding-request-ens-meta-governance-working-group-term-5-oct-window/19677)
The Meta-governance Working Group requests funding to fulfill anticipated budgetary needs through the next formal funding window in April 2025.
| Destination | USDC | ETH | $ENS |
| :---------------------------------------------------------------------------------------------------- | :-----: | :-: | :----: |
| [ENS Meta-Gov Main Multisig](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) | 354,000 | 0 | 45,000 |
This amount will cover all expected expenses (including the ENS required for vesting on 5.19 and 5.21) while maintaining a 100,000 USDC prudent reserve to ensure continuity if future funding is delayed.
#### 2) [Ecosystem Funding Request \[EP 5.17.2\]](https://discuss.ens.domains/t/5-17-2-social-funding-request-ens-ecosystem-working-group/19678)
The ENS Ecosystem Working Group requests funding to support operations through April 2025. This is the only funding request of Term 5. The working group is responsible for growing and improving the ENS Ecosystem by funding builders and projects that are ENS-specific or ENS-centric.
| Destination | USDC | ETH | $ENS |
| :----------------------------------------------------------------------------------------------------- | :-----: | :-: | :--: |
| [ENS Ecosystem Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 836,000 | 0 | 0 |
#### 3) [Public Goods Funding Request \[EP 5.17.3\]](https://discuss.ens.domains/t/5-17-3-social-funding-request-ens-public-goods-working-group/19679)
The ENS Public Goods Working Group requests funding to support operations through the next funding window in April 2025. The funds requested extend current needs through to next term to ensure that next season's stewards have available funding before the next funding window.
| Destination | USDC | ETH | $ENS |
| :---------------------------------------------------------------------------------------------------- | :-----: | :-: | :--: |
| [Public Goods Main Multisig](https://etherscan.io/address/0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d) | 226,000 | 0 | 0 |
### Specification
The following transfers are to be made from the DAO treasury:
1. Transfer 354,000 USDC to the Meta-governance safe:
* Address: `0x91c32893216dE3eA0a55ABb9851f581d4503d39b`
2. Transfer 836,000 USDC to the Ecosystem safe:
* Address: `0x2686A8919Df194aA7673244549E68D42C1685d03`
3. Transfer 226,000 USDC to the Public Goods safe:
* Address: `0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d`
4. Transfer 45,000 ENS to the Meta-governance safe:
* Address: `0x91c32893216dE3eA0a55ABb9851f581d4503d39b`
##### Total transfer amount: 1,416,000 USDC and 45,000 ENS
## \[EP 5.25] \[Executable] Collective Working Group Funding Request (Oct 2024) - Resubmission
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-25-executable-collective-working-group-funding-request-oct-2024-resubmission/19847) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/14573906698181916980991958251655570598275649222336388998984945658874299918898) |
### Description
This is a resubmission of \[EP 5.24], with no changes to the funding amounts or technical specifications.
### Abstract
This proposal executes all three Working Group funding requests for the October 2024 funding window as passed in [EP 5.17.1](https://discuss.ens.domains/t/5-17-1-social-funding-request-ens-meta-governance-working-group-term-5-oct-window/19677), [EP 5.17.2](https://discuss.ens.domains/t/5-17-2-social-funding-request-ens-ecosystem-working-group/19678), and [EP 5.17.3](https://discuss.ens.domains/t/5-17-3-social-funding-request-ens-public-goods-working-group/19679). For more detail, view the ENS Governance docs at [https://basics.ensdao.org/funding-requests](https://basics.ensdao.org/funding-requests)
### Proposal Components
***
#### 1) [Meta-governance Funding Request \[EP 5.17.1\]](https://discuss.ens.domains/t/5-17-1-social-funding-request-ens-meta-governance-working-group-term-5-oct-window/19677)
The Meta-governance Working Group requests funding to fulfill anticipated budgetary needs through the next formal funding window in April 2025.
| Destination | USDC | ETH | $ENS |
| :---------------------------------------------------------------------------------------------------- | :-----: | :-: | :--: |
| [ENS Meta-Gov Main Multisig](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) | 254,000 | 0 | 0 |
This amount will cover all expected expenses while maintaining a 100,000 USDC prudent reserve to ensure continuity if future funding is delayed.
***
#### 2) [Ecosystem Funding Request \[EP 5.17.2\]](https://discuss.ens.domains/t/5-17-2-social-funding-request-ens-ecosystem-working-group/19678)
The ENS Ecosystem Working Group requests funding to support operations through April 2025. This is the only funding request of Term 5. The working group is responsible for growing and improving the ENS Ecosystem by funding builders and projects that are ENS-specific or ENS-centric.
| Destination | USDC | ETH | $ENS |
| :----------------------------------------------------------------------------------------------------- | :-----: | :-: | :--: |
| [ENS Ecosystem Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 836,000 | 0 | 0 |
***
#### 3) [Public Goods Funding Request \[EP 5.17.3\]](https://discuss.ens.domains/t/5-17-3-social-funding-request-ens-public-goods-working-group/19679)
The ENS Public Goods Working Group requests funding to support operations through the next funding window in April 2025. The funds requested extend current needs through to next term to ensure that next season's stewards have available funding before the next funding window.
| Destination | USDC | ETH | $ENS |
| :---------------------------------------------------------------------------------------------------- | :-----: | :-: | :--: |
| [Public Goods Main Multisig](https://etherscan.io/address/0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d) | 226,000 | 0 | 0 |
***
### Specification
The following transfers are to be made from the DAO treasury:
1. Transfer 254,000 USDC to the Meta-governance safe:
* Address: `0x91c32893216dE3eA0a55ABb9851f581d4503d39b`
2. Transfer 836,000 USDC to the Ecosystem safe:
* Address: `0x2686A8919Df194aA7673244549E68D42C1685d03`
3. Transfer 226,000 USDC to the Public Goods safe:
* Address: `0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d`
##### Total transfer amount: 1,316,000 USDC
***
#### Calldata:
**5.17.1 Tx to Metagov**
```
{
"target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": 0,
"calldata": "0xa9059cbb00000000000000000000000091c32893216de3ea0a55abb9851f581d4503d39b0000000000000000000000000000000000000000000000000000003b23946c00"
}
```
**5.17.2 Tx to Ecosystem**
```
{
"target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": 0,
"calldata": "0xa9059cbb0000000000000000000000002686a8919df194aa7673244549e68d42c1685d03000000000000000000000000000000000000000000000000000000c2a57ba800"
}
```
**5.17.3 Tx to Public Goods**
```
{
"target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": 0,
"calldata": "0xa9059cbb000000000000000000000000cd42b4c4d102cc22864e3a1341bb0529c17fd87d000000000000000000000000000000000000000000000000000000349ea65400"
}
```
## \[EP 5.26] \[Executable] Implementation of EP 5.19’s ENS Governance Distribution Pilot Program
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-26-executable-implementation-of-ep-5-19-s-ens-governance-distribution-pilot-program/19878) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/50152158826647742094695349340830523178083147237337111134725087674188893435887) |
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-26-executable-implementation-of-ep-5-19-s-ens-governance-distribution-pilot-program/19878) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/50152158826647742094695349340830523178083147237337111134725087674188893435887) |
### Abstract
This executable proposal implements the Governance Distribution Pilot Program approved in [EP5.19](https://snapshot.org/#/ens.eth/proposal/0xfa54ff2b55f0495c96ec2d8645241bcff48ca6afe1f4925fb51f29c4667252df). Following the community's selection of the 30k ENS distribution option, this proposal authorizes the transfer of ENS tokens from the treasury to implement the program.
### Specification
This proposal authorizes:
1. The transfer of 30,000 ENS tokens from the DAO treasury to the Meta-governance working group's main wallet (main.mg.wg.ens.eth) for distribution to eligible recipients
2. The Meta-governance working group will then distribute these tokens through 2-year linear vesting contracts according to the allocation table below
This distribution follows the quadratic funding method, which is a progressive ratio where recipients receive ENS tokens proportional to the square root of their USDC/ETH contributions during January-September 2024. The complete distribution table is as follows:
#### Recipients
| From | To | SUM of Value | Squared Weight | % of total | ENS | % of value received |
| --------------------- | ---------------------------------- | -------------- | -------------- | ---------- | --------- | ------------------- |
| Ecosystem | ETHGlobal | $ 190,000.00 | 435.9 | 5.2% | 1,569.85 | 11.6% |
| | wslyvh.eth | $ 50,004.00 | 223.6 | 2.7% | 805.35 | 22.5% |
| | Onthis | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | ipns.eth | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | Fluidkey | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | Blockscout | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | beaconchain.eth | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | 1w3.eth | $ 25,000.00 | 158.1 | 1.9% | 569.44 | 31.9% |
| | Urbe Campus | $ 14,680.00 | 121.2 | 1.5% | 436.36 | 41.6% |
| | Discord Support | $ 13,000.00 | 114.0 | 1.4% | 410.63 | 44.2% |
| | generalmagic.eth | $ 11,563.43 | 107.5 | 1.3% | 387.28 | 46.9% |
| | Pugson | $ 10,000.00 | 100.0 | 1.2% | 360.15 | 50.4% |
| | Juicebox | $ 10,000.00 | 100.0 | 1.2% | 360.15 | 50.4% |
| | frolic.eth | $ 10,000.00 | 100.0 | 1.2% | 360.15 | 50.4% |
| | Drips | $ 10,000.00 | 100.0 | 1.2% | 360.15 | 50.4% |
| | Socket | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | ENS Fairy | $ 4,781.34 | 69.1 | 0.8% | 249.03 | 72.9% |
| | weird3.eth | $ 3,000.00 | 54.8 | 0.7% | 197.26 | 92.1% |
| | stephancill.eth | $ 2,367.89 | 48.7 | 0.6% | 175.25 | 103.6% |
| | Scope.sh | $ 2,367.89 | 48.7 | 0.6% | 175.25 | 103.6% |
| | Kiwi News | $ 2,367.89 | 48.7 | 0.6% | 175.25 | 103.6% |
| | aexek.eth | $ 1,750.00 | 41.8 | 0.5% | 150.66 | 120.5% |
| Ecosystem Total | | $ 490,882.44 | | | | |
| Public Goods | Rotki | $ 53,973.38 | 232.3 | 2.8% | 836.70 | 21.7% |
| | gashawk.eth | $ 40,000.00 | 200.0 | 2.4% | 720.29 | 25.2% |
| | buidlguidl.eth | $ 35,000.00 | 187.1 | 2.2% | 673.77 | 27.0% |
| | borderlessafrica.eth | $ 30,000.00 | 173.2 | 2.1% | 623.79 | 29.1% |
| | Revoke.Cash | $ 20,000.00 | 141.4 | 1.7% | 509.33 | 35.7% |
| | Firefly | $ 20,000.00 | 141.4 | 1.7% | 509.33 | 35.7% |
| | EIP-7212 | $ 20,000.00 | 141.4 | 1.7% | 509.33 | 35.7% |
| | ethdaily.eth | $ 14,797.60 | 121.6 | 1.5% | 438.10 | 41.4% |
| | Dappnode | $ 12,500.00 | 111.8 | 1.3% | 402.66 | 45.1% |
| | ETHDenver | $ 10,000.00 | 100.0 | 1.2% | 360.15 | 50.4% |
| | pairwise.eth | $ 8,402.18 | 91.7 | 1.1% | 330.12 | 55.0% |
| | apoorv.eth | $ 7,021.88 | 83.8 | 1.0% | 301.79 | 60.2% |
| | leticiaferraz.eth | $ 6,949.32 | 83.4 | 1.0% | 300.23 | 60.5% |
| | Urbe Campus | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | Latin Hackathon | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | eth-mexico.eth | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | DAOstar | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | aynieducativo.eth | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | glodollar.eth | $ 3,762.22 | 61.3 | 0.7% | 220.90 | 82.2% |
| | modularcrypto.eth | $ 1,818.29 | 42.6 | 0.5% | 153.57 | 118.2% |
| | daveytea.eth | $ 1,818.29 | 42.6 | 0.5% | 153.57 | 118.2% |
| | UPE | $ 940.56 | 30.7 | 0.4% | 110.45 | 164.4% |
| | illuminated.eth | $ 940.56 | 30.7 | 0.4% | 110.45 | 164.4% |
| | dhive.eth | $ 940.56 | 30.7 | 0.4% | 110.45 | 164.4% |
| | bloomnetwork.eth | $ 940.56 | 30.7 | 0.4% | 110.45 | 164.4% |
| | pabl0cks.eth | $ 877.74 | 29.6 | 0.4% | 106.70 | 170.2% |
| | iviangita.eth | $ 877.74 | 29.6 | 0.4% | 106.70 | 170.2% |
| | easlabs.eth | $ 877.74 | 29.6 | 0.4% | 106.70 | 170.2% |
| | 2118.eth | $ 877.74 | 29.6 | 0.4% | 106.70 | 170.2% |
| Public Goods Total | | $ 318,316.31 | | | | |
| Metagov | Karpatkey | $ 187,149.13 | 432.6 | 5.2% | 1,558.02 | 11.7% |
| | daemon.eth | $ 27,000.00 | 164.3 | 2.0% | 591.78 | 30.7% |
| | Lemma | $ 9,998.67 | 100.0 | 1.2% | 360.12 | 50.4% |
| | Tally | $ 8,999.54 | 94.9 | 1.1% | 341.66 | 53.1% |
| | Event Support | $ 3,000.00 | 54.8 | 0.7% | 197.26 | 92.1% |
| | daveytea.eth | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| | andrewpage.eth | $ 780.00 | 27.9 | 0.3% | 100.58 | 180.5% |
| Metagov Total | | $ 237,927.35 | | | | |
| Immunefi Bounty | Immunefi | $ 102,000.00 | 319.4 | 3.8% | 1,150.22 | 15.8% |
| | @UGWST\_COM | $ 75,000.00 | 273.9 | 3.3% | 986.30 | 18.4% |
| | @navad | $ 7,500.00 | 86.6 | 1.0% | 311.90 | 58.2% |
| | @Sagamore | $ 6,000.00 | 77.5 | 0.9% | 278.97 | 65.1% |
| | @adhd | $ 5,000.00 | 70.7 | 0.8% | 254.66 | 71.3% |
| | @solidityhaxor | $ 2,500.00 | 50.0 | 0.6% | 180.07 | 100.8% |
| | @haoce505 | $ 2,500.00 | 50.0 | 0.6% | 180.07 | 100.8% |
| | @h4nt3rx | $ 2,500.00 | 50.0 | 0.6% | 180.07 | 100.8% |
| | @austinoa012 | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| Immunefi Bounty Total | | $ 204,000.00 | | | | |
| ETH Global | TF Guo | $ 3,000.00 | 54.8 | 0.7% | 197.26 | 92.1% |
| | Nikolas Lionis | $ 2,000.00 | 44.7 | 0.5% | 161.06 | 112.7% |
| | Arthur Sabirzyanov | $ 2,000.00 | 44.7 | 0.5% | 161.06 | 112.7% |
| | Stephan Wittig | $ 1,500.00 | 38.7 | 0.5% | 139.48 | 130.2% |
| | Rashmi Abbigeri | $ 1,500.00 | 38.7 | 0.5% | 139.48 | 130.2% |
| | Mehran Saliminia | $ 1,500.00 | 38.7 | 0.5% | 139.48 | 130.2% |
| | Mattis Deisen | $ 1,500.00 | 38.7 | 0.5% | 139.48 | 130.2% |
| | Ben Levy | $ 1,375.00 | 37.1 | 0.4% | 133.55 | 136.0% |
| | Aryeh Greenberg | $ 1,375.00 | 37.1 | 0.4% | 133.55 | 136.0% |
| | Shoma Shiga | $ 1,250.00 | 35.4 | 0.4% | 127.33 | 142.6% |
| | Rao Araki | $ 1,250.00 | 35.4 | 0.4% | 127.33 | 142.6% |
| | sudolabel | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| | Simone Staffa | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| | Paolo Rollo | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| | Francesco Cirulli | $ 1,000.00 | 31.6 | 0.4% | 113.89 | 159.4% |
| | Yong Feng Ng | $ 875.00 | 29.6 | 0.4% | 106.53 | 170.5% |
| | Yik Kai Ng | $ 875.00 | 29.6 | 0.4% | 106.53 | 170.5% |
| | Junyao Chan | $ 875.00 | 29.6 | 0.4% | 106.53 | 170.5% |
| | Jing Jie Ng | $ 875.00 | 29.6 | 0.4% | 106.53 | 170.5% |
| | Tom Chauveau | $ 750.00 | 27.4 | 0.3% | 98.63 | 184.1% |
| | Roman GASCOIN | $ 750.00 | 27.4 | 0.3% | 98.63 | 184.1% |
| | Coline SEGURET | $ 750.00 | 27.4 | 0.3% | 98.63 | 184.1% |
| | Wojciech Staniszewski | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Patrick Fuchs | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Pascal Rüger | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Luca Orbke | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Joanna Daniluk | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Eason Chai | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Bartłomiej Tarczyński | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Antoni Koszowski | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Andrzej Daniel | $ 500.00 | 22.4 | 0.3% | 80.53 | 225.5% |
| | Yoshiki Takabayashi | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Shritesh Jamulkar | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Rohit Ramesh | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Nishen Kaushika Menerapitiyage Don | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Helen Femi Williams | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Francisco Cordero | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Danya Carolina Gómez Cantú | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Bianca Trovò | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Bernardo Vieira | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| | Adaku Agwunobi | $ 250.00 | 15.8 | 0.2% | 56.94 | 318.9% |
| ETH Global Total | | $ 35,000.00 | | | | |
| Grand Total | | $ 1,286,126.10 | 8329.9 | 100% | 30,000.00 | |
1. Value represents the total received of all transactions
2. Squared Weight is simply the square root of that value, which is used as a weight
3. % of total divided that by the total weight
4. ENS multiplies that percentage to the total budget
5. % of value received is a comparison of the value received in USDC with the value received in ENS, with ENS at $14
### Transaction
```json
{
"target": "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72",
"value": 0,
"calldata": "0xa9059cbb00000000000000000000000091c32893216de3ea0a55abb9851f581d4503d39b00000000000000000000000000000000000000000000065a4da25d3016c00000"
}
```
### Verification
* Target: ENS token contract (0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72)
* Recipient: main.mg.wg.ens.eth (0x91c32893216dE3eA0a55ABb9851f581d4503d39b)
* Amount: 30,000 ENS (30000000000000000000000 in wei)
* Function: transfer(address,uint256)
***
The Meta-governance working group will handle subsequent distributions to individual recipients through Hedgey vesting contracts following the approved allocation table.
The transaction will move the 30k $ENS to the main Meta-governance wallet. After the transaction completes, the Meta-governance working group will craft the Hedgey vesting contracts following the above allocation table.
## \[EP 5.27] \[Executable] Revoke the DAO's ability to upgrade the name wrapper
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-27-executable-revoke-the-daos-ability-to-upgrade-the-name-wrapper/19920) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/40272043175867710511047990376059633000673751036364092383567949469124429500507) |
### Abstract
The Name Wrapper's upgrade mechanism contains a vulnerability whereby a malicious DAO could use the upgrade mechanism to seize control of wrapped names without the owner's consent, documented [here](https://discuss.ens.domains/t/security-advisory-a-malicious-dao-update-could-reduce-the-registration-duration-of-registered-eth-2lds/17576/1).
Since the v2 migration plan makes the upgrade mechanism obsolete, we now know the mechanism will never be required. This EP proposes to remove the DAO's ability to upgrade the name wrapper.
### Specification
Admin control over the name wrapper gives the DAO two functions: it can set the upgrade contract, and it can specify the address of the metadata contract. Since we want to remove the former ability while preserving the latter, we propose the following sequence of actions:
1. Deploy a new metadata contract, identical to the current one but using a proxy. The proxy instance should be owned by the DAO to provide for future metadata upgrades.
2. Update the name wrapper to reference the new metadata contract instead of the old one.
3. Revoke admin ownership over the name wrapper.
A new metadata service has been deployed at 0x806f84F3789f51352C1B0aB3fFa192665d283808, and a transparent proxy was deployed in transaction 0xd0aca1f2efb2db5e3d494649004e341decb2e94a1f30e94f301b6626702ee4c8, at address 0xabb76d7e79de010117b147761013f11630a6799f, with the initial implementation set to the above address, and the owner set to wallet.ensdao.eth. The admin contract for this proxy is at 0xeae9309ddb1aadb4cf1ebad5e51aef999833a992.
The executable component of this proposal sets the metadata service address on the name wrapper to the above proxy, then revokes ownership over it.
## \[EP 5.28] \[Executable] Reimbursement of eth.limo's ongoing legal fees
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-28-executable-reimbursement-of-eth-limo-s-ongoing-legal-fees/20004) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/15212507956777005315602309329914215169878587763966450377165643673108805753590) |
### Description
#### Summary
This proposal aims to reimburse eth.limo for ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
#### Background
##### The Human Costs of Public Goods
At eth.limo we continuously strive to deliver a high quality ENS gateway experience. We understand the critical utility that our service provides and we have dedicated countless hours to developing and maintaining the gateway infrastructure that powers thousands of dApps and dWebsites alike.
Speaking beyond purely technical requirements, one aspect of operating eth.limo that is often overlooked is the human cost. We are a small team with limited resources who are dedicated 24/7 to ensure that we respond to support requests in a timely fashion, work with other cutting edge ecosystem projects for integrations, and provide on-call availability for any server-side issues that might arise. In addition, we are constantly handling abuse complaints and other matters that often go unmentioned.
We believe in public goods and the utility they provide, which is why we have sacrificed time with friends and family in order to fulfil our obligations to the ENS and broader Web3 communities by constantly working to ensure a stable and available user experience.
##### The Legal Costs of Public Goods
Operating public infrastructure comes with a unique set of challenges, many of which we were not expecting, such as enforcement and dispute-related legal fees. Being on the frontlines of bridging Web2 → Web3 means that we are often the first point of contact for law enforcement, abuse complaints, and legal and regulatory requests. As one can imagine, this quickly begins to take a toll on our financial resources and mental health.
At present, eth.limo has been labouring under US federal requests, as a third-party, that has dragged on for months and will likely continue to do so well into 2025. We are currently unable to provide further details regarding the nature of this matter, but rest assured, as soon as we are permitted to, we will provide a more fulsome summary to the Web3 community.
As a US company, we are legally required to cooperate with the US Federal Government in response to certain types of lawful requests. Such required compliance has proven to be an extreme financial burden in the form of fees and expenses from our lawyers and emotional distress not just on us individually, but to our families as well.
We negotiated significant discounts from our counsel, who are well-versed in Web3, and who recognize the importance of eth.limo and the significant public good service it provides. At present, we have no way to anticipate expected future legal costs associated with this specific set of legal requests, nor are we able to forecast any additional legal matters or proceedings that may arise as a result of maintaining eth.limo as a public good.
This has the indirect effect of limiting our ability to grow and scale the eth.limo service, as well as to pursue future plans relating to additional integrations and roadmap efforts. To put this into perspective, we have already spent close to $250k USD in legal fees over the past few months. Without additional funding, this very likely could consume our remaining financial resources, leaving us without the ability to continue to operate eth.limo as a public good.
### Links
[Temperature Check](https://discuss.ens.domains/t/temp-check-reimbursement-of-eth-limos-ongoing-legal-fees/19976/1)
### Specification
This executable proposal will initiate a transfer of 240,632.38 USDC from the ENS DAO treasury to ethdotlimo.eth. This amount represents the ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
#### Transaction Details
* **From**: ENS DAO Treasury (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7)
* **To**: USDC Token Contract (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
* **Recipient**: ethdotlimo.eth (0xB352bB4E2A4f27683435f153A259f1B207218b1b)
* **Amount**: 240,632.38 USDC (240632380000 considering USDC's 6 decimal places)
* **Purpose**: The reimbursement of eth.limo for ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
This transaction calls the `transfer` function of the USDC contract, transferring 240,632.38 USDC to eth.limo's address.
### Calldata
```json
{
"target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": 0,
"calldata": "0xa9059cbb000000000000000000000000b352bb4e2a4f27683435f153a259f1b207218b1b0000000000000000000000000000000000000000000000000000003806ceba60"
}
```
#### Rationale
By approving this compensation, ENS DAO acknowledges the importance of providing eth.limo with reimbursement of its legal fees so it can continue to operate a free and public ENS gateway that enables users to access Ethereum-native dApps and content.
## \[EP 5.29] Funding request for Unruggable to build and operate a network of gateways supporting the rollout of ENSIP-19: EVM-chain Reverse Resolution
::authors
| **Status** | Rejected |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-ep-5-29-funding-request-for-unruggable-to-build-and-operate-a-network-of-gateways-supporting-the-rollout-of-ensip-19-evm-chain-reverse-resolution/19902) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/13214174724111749338017943143826453367599509196993220699255450633508989705578) |
### Summary
We are requesting funding from the ENS DAO to build a production network of gateways. These gateways will support the rollout of reverse resolution for **Arbitrum, Base, Linea, Optimism, and Scroll.** We also plan to continue our research and development on the ENS protocol and actively contribute to the ENS ecosystem with a focus on resolving names from L2s. Our funding request focuses on infrastructure, talent acquisition and retention, and ongoing development to sustain this critical ENS infrastructure.
### Request
We are requesting **$1,200,000 USDC annually and 24,000 ENS tokens (vested over 2 years with a one year cliff).**
This request gives consideration to the feedback on our [Temp Check](https://discuss.ens.domains/t/temp-check-ep-x-x-funding-request-for-unruggable-to-build-and-operate-a-network-of-gateways-supporting-the-rollout-of-ensip-19-evm-chain-reverse-resolution/19902) on the ENS DAO forum.
### Executable Code
This proposal constitutes two streams:
* A stream of **$1,200,000 USDC** **per year** (12 months).
* A stream of **24,000 ENS** tokens over **2 years** (24 months) with a **1 year cliff** (12 months).

Both streams are controlled directly by the ENS DAO Wallet. They can be cancelled at any time with a DAO vote should Unruggable not fulfil their promises.
This calldata has been generated using thIs codebase: [](https://github.com/unruggable-labs/unruggable-stream/tree/dce44e0fc3a461f4f250c436101231e553829e03)[https://github.com/unruggable-labs/unruggable-stream/tree/3d3c49980defbab315b6e09385b22946dd9729b0](https://github.com/unruggable-labs/unruggable-stream/tree/3d3c49980defbab315b6e09385b22946dd9729b0), which generates and simulates execution of the below listed transactions.
Tenderly simulation links are listed below.
#### Stream 1 - $1,200,000 USDC.
**Platform:** [Superfluid](https://www.superfluid.finance/).
Superfluid is a tried and tested platform for streaming funds. It has been used for nearly a year now for [**\[EP5.2\] \[Executable\] Commence Streams for Service Providers.**](https://www.tally.xyz/gov/ens/proposal/63865530602418424570813160277709124551851041237648860550576561576702951975816)
Initialising the Superfluid stream involves **4 transactions**:
| Description | Target Name | Target Address | Function Signature | Function Arguments | Calldata \[1] | Simulation |
| --------------------------------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| This function approves the Super USDCx contract to spend $100,000 of USDC on behalf of the sender, the ENS DAO wallet. | USDC | [0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) | `function approve(address spender, uint256 amount) external returns (bool)` | `["0x1BA8603DA702602A8657980e825A6DAa03Dee93a", 100000000000]` | `0x095ea7b30000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a000000000000000000000000000000000000000000000000000000174876e800` | [Simulation](https://www.tdly.co/shared/simulation/7a33ba80-767d-4764-891f-b93690ad7b25) |
| This function 'upgrades' $100,000 USDC from the ENS DAO wallet/'Timelock' to USDCx. | USDCx | [0x1BA8603DA702602A8657980e825A6DAa03Dee93a](https://etherscan.io/address/0x1BA8603DA702602A8657980e825A6DAa03Dee93a) | `function upgrade(uint256 amount)` | `[100000000000]` | `0x45977d03000000000000000000000000000000000000000000000000000000174876e800` | [Simulation](https://www.tdly.co/shared/simulation/d564e4b9-3c5d-4e90-91f7-9ae78e32fbd1) |
| This function sets up the stream to the Unruggable multisig wallet. \[2] | Superfluid | [0xcfA132E353cB4E398080B9700609bb008eceB125](https://etherscan.io/address/0xcfA132E353cB4E398080B9700609bb008eceB125) | `function setFlowrate(address tokenAddress, address receiverAddress, int96 amountPerSecond)` | `["0x1BA8603DA702602A8657980e825A6DAa03Dee93a", "0x64Ca550F78d6Cc711B247319CC71A04A166707Ab", 38026517538495352]` | `0x57e6aa360000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a00000000000000000000000064ca550f78d6cc711b247319cc71a04a166707ab000000000000000000000000000000000000000000000000008718ea8ded5b78` | [Simulation](https://www.tdly.co/shared/simulation/725d872b-8174-4fa5-a60b-5d45eea1812f) |
| This function increases the amount of USDC (owned by the ENS DAO wallet/Timelock) that the Autowrap strategy contract is able to spend. | USDC | [0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) | `function increaseAllowance(address spender, uint256 increment)` | `["0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d", 1100000000000]` | `0x395093510000000000000000000000001d65c6d3ad39d454ea8f682c49ae7744706ea96d000000000000000000000000000000000000000000000000000001001d1bf800` | [Simulation](https://www.tdly.co/shared/simulation/d94d705b-0025-4500-b5d0-e4eba5221abe) |
#### Stream 2 - 24,000 ENS
Platform: [Hedgey](https://hedgey.finance/)
Hedgey has been utilised by the ENS DAO for allocating delegateable ENS tokens to deserving ecosystem participants.
Initialising the Hedgey stream involves **2 transactions**:
| Description | Target Name | Target Address | Function Signature | Function Arguments | Calldata \[1] | Simulation |
| ---------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Approve the `BatchPlanner` to spend 24,000 ENS tokens owned by the ENS DAO Wallet | ENS Token | [0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72](https://etherscan.io/address/0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72) | `function approve(address spender, uint256 amount) external returns (bool)` | `[ "0x3466EB008EDD8d5052446293D1a7D212cb65C646", 24000000000000000000000 ]` | `0x095ea7b30000000000000000000000003466eb008edd8d5052446293d1a7d212cb65c6460000000000000000000000000000000000000000000005150ae84a8cdf000000` | [Simulation](https://www.tdly.co/shared/simulation/82838efa-2dda-4660-abf7-991f2787388a) |
| Create the Vesting Plan. Tokens vested over 24 months, with a 12 month cliff. \[3] | Hedgey Batch Planner | [0x3466EB008EDD8d5052446293D1a7D212cb65C646](https://etherscan.io/address/0x3466EB008EDD8d5052446293D1a7D212cb65C646) | `function batchVestingPlans(address locker, address token, uint256 totalAmount,(address recipient, uint256 amount, uint256 start, uint256 cliff, uint256 rate)[], uint256 period, address vestingAdmin, bool adminTransferOBO, uint8 mintType)` | `["0x1bb64AF7FE05fc69c740609267d2AbE3e119Ef82", "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72", 24000000000000000000000, [["0x64Ca550F78d6Cc711B247319CC71A04A166707Ab", 24000000000000000000000, 1735065935, 1766601935, 380517503805175]], 1, "0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7", true, 4]` | `0x94d37b5a0000000000000000000000001bb64af7fe05fc69c740609267d2abe3e119ef82000000000000000000000000c18360217d8f7ab5e7c516566761ea12ce7f9d720000000000000000000000000000000000000000000005150ae84a8cdf00000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000064ca550f78d6cc711b247319cc71a04a166707ab0000000000000000000000000000000000000000000005150ae84a8cdf00000000000000000000000000000000000000000000000000000000000000676b014f00000000000000000000000000000000000000000000000000000000694c34cf00000000000000000000000000000000000000000000000000015a1422a526f7` | [Simulation](https://www.tdly.co/shared/simulation/d33f9323-8ec0-4402-a458-265b7fa546f7) |
\[1] You can deep dive into this calldata at the following link: [https://ethtools.com/calldata-collections/unruggable-executable-proposal](https://ethtools.com/calldata-collections/unruggable-executable-proposal)
\[2] `38026517538495352` represents $0.038.. USDC per second noting that USDC has 18 decimals and there are `31556926` seconds in a year.
\[3] `period`, and `mintType` arguments are taken from the Hedgey documentation: [https://hedgey.gitbook.io/hedgey-community-docs/for-developers/technical-documentation/token-vesting/integration-and-direct-contract-interactions](https://hedgey.gitbook.io/hedgey-community-docs/for-developers/technical-documentation/token-vesting/integration-and-direct-contract-interactions)
## \[EP5.3] \[Social] Determine ENS Labs' next steps in eth.link litigation
::authors
| **Status** | Approved $300k settlement |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep5-2-social-determine-ens-labs-next-steps-in-eth-link-litigation/18756) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x456ccb438eed5d189cbe51e5e36a88d2bb4dc0c61f12f6d9e310a7ba4798d5fc) |
### Abstract
Since 2017, ENS Labs has been operating eth.link as a public gateway for the Ethereum community, providing access to ENS+IPFS sites. Eth.link has been used by some of the largest projects in the space, including Uniswap.
Eth.link was kindly delegated to ENS Labs for this purpose by its owner, Virgil Griffith. In August 2022, a dispute arose between ENS Labs, Dynadot, GoDaddy, and Manifold Finance about ownership of eth.link after the transfer and auction of the domain without ENS' consent. The highest bidder for eth.link at the auction was Manifold Finance, who expressed their intention to [operate the service themselves](https://twitter.com/foldfinance/status/1566200320375476225). A full recitation of the facts surrounding the dispute can be found within [the complaint that ENS Labs filed](https://drive.google.com/file/d/1951CeiKQZ4jQvcpjKU53BnugVedIf8go/view?usp=sharing) in September 2022.
Before the domain could be transferred, ENS Labs and Virgil successfully obtained a preliminary injunction from a federal district court judge in Phoenix, Arizona. The Court ordered that Dynadot had to immediately return eth.link to ENS Labs. Since then, this litigation has been proceeding slowly through the courts. ENS Labs had to enforce the preliminary injunction as to Dynadot and Manifold Finance exited the lawsuit on jurisdictional grounds. Settlement discussions between the parties indicated that Manifold Finance should be included in any global settlement because of its potential claims to eth.link and against Dynadot.
Recently, Manifold Finance has extended a settlement offer. They are demanding $300,000, along with confidentiality and non-disparagement clauses. In return, they are offering an allparties settlement, which would result in the dismissal of the case and ENS Labs retaining the eth.link domain name.
ENS Labs believes that this is the appropriate juncture to solicit the DAO's input on how to proceed with the litigation. We are thus asking the DAO to instruct ENS Labs on the next steps to take in this case, whether that be agreeing to the settlement, offering a compromise amount, continuing the lawsuit, or dismissing the matter altogether, which would relinquish ENS Labs' possession of eth.link. Thus far, ENS Labs has been funding this litigation from its own finances. Our expenses so far amount to approximately $750,000. Continuing the case is likely to incur substantial additional costs.
Further, given the criticality of eth.link to the ENS ecosystem, we would like to request reimbursement from the DAO for the legal fees incurred in protecting possession of eth.link.
### Specification
This will be an approval vote, with four independent items:
1. Do you approve the proposed settlement?
2. Do you approve of offering a compromise amount?
3. Do you approve of continuing the litigation?
4. Do you approve reimbursing ENS labs for its legal expenses involved in pursuing this case?
You should vote on each outcome you would be happy with. For example, if you would be happy with either continuation or a compromise settlement, but not the full amount, you would vote for options 2, 3 and 4. If you prefer that the case be dismissed, vote only for option 4, or for no options.
If the reimbursement is not approved, or none of the options receive a majority (50%) of approving votes, ENS Labs will:
* Promptly post an interstitial on eth.link, warning users of the potential change in ownership and functionality of the domain, and offering alternatives including eth.limo.
* Dismiss the litigation without delay and without unnecessary further expenditure of funds.
Based on the outcome of the vote, ENS Labs will proceed with the case based on whichever of the courses of action (settlement or continuation) receives the higher proportion of approving votes. Subsequently, ENS Labs will post an executable proposal seeking reimbursement from the DAO for its legal expenses pursuing the case.
## \[5.4.1] \[Social] Funding Request: ENS Meta-Governance Working Group Term 5 (Q1/Q2)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-4-1-social-funding-request-ens-meta-governance-working-group-term-5-q1-q2/18883) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xfa1fdf0cfb94eabecf613ccd6b0c3a9247c21e64047cf330c000760970a02536) |
### Abstract
The ENS Meta-Governance Working Group requests funding of the below to **support operations until the September 2024 funding window**.
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)) and further required by [this snapshot proposal in Nov. 2023 modifying steward rules.](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Metagov Multisig to fulfill anticipated budgetary needs through September 2024.
| | USDC | ETH | $ENS |
| -------------------------- | :--: | :-: | :--: |
| ENS Meta-Gov Main Multisig | 374k | 0 | 105k |
### Description
#### Current Metagov Wallet Balances
(Values expected as of March 5th, 2024 - Use hyperlinked wallet names to see current balances)
| Address | ETH | USDC | $ENS |
| ---------------------------------------------------------------------------------------------------- | ------- | ------- | ------ |
| [ens-metagov.pod.xyz](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) | 85.68\* | 362,463 | 15,540 |
| [ens-endowmentfees.pod.xyz](https://etherscan.io/address/0x83DD97A584C4aD50015f7aA6B48bf4970A056d8f) | 0 | 0 | 0 |
\**This value includes 22.89 that the metagov safe loaned to the endowment fees payments that will be repaid to the metagov safe with executable that implements the new Endowment fees strategy*
### Expenditures
Meta-Gov sets aside funds to ensure coverage for mission-critical initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives. We anticipate that final expenditures will not surpass the expected expenses allocated for the term.
#### Expected Expenses through September 2024
| | USDC | ETH | $ENS |
| -------------------------------- | ----------- | ------ | -------- |
| Steward + Secretary Compensation | 294,000 | - | |
| Governance | 50,000 | 5 | 105k |
| DAO Tooling | 140,000 | - | - |
| Discretionary | - | 10 | - |
| **Total Balance** | **484,000** | **15** | **105k** |
#### Governance Distributions
| Recipient Category | Amount of $ENS | Method |
| --------------------------- | -------------- | ------------------------------------------------------------ |
| Contributors and Developers | 60k | Vesting contracts |
| Elected Stewards | 45k | Change to vesting contracts is planned for the 2025 guidance |
#### Description of Initiatives/Pods
**Steward + Secretary Compensation**: Working Group Steward and Secretary compensation as required by [revised steard working group rules](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) and [totaling $294,000 USDC](https://discuss.ens.domains/t/ens-dao-steward-compensation/18063).
**Governance**: Fee reimbursements and initiatives related to reducing friction in the governance process. This can also include $ENS distributed in order to lower barriers to the governance proposal process.
**DAO Tooling**: Developing interfaces and dashboards to improve the governance process and increase transparency across the DAO. An example of DAO tooling spend is our current engagement with Agora as they help build out an enhanced DAO proposal flow to streamline the proposal process.
**Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments. In this cycle, we've consolidated the former DAO Sponsorship category into this discretionary category.
### Conclusion
This funding request will allow the ENS Meta-Governance Working Group to continue its essential work in providing governance oversight, supporting the management and operation of working groups, and ensuring effective treasury management for the DAO. The requested funds will enable us to maintain our ongoing initiatives and develop new tools to enhance the governance process. We are grateful for the community's ongoing support and engagement, which is crucial to the success of the ENS DAO. The Meta-Governance Working Group remains committed to serving the ENS community and driving the long-term growth and sustainability of the ecosystem.
## \[5.4.2] \[Social] Funding Request: ENS Public Goods Working Group Term 5 (Q1/Q2)
::authors
| **Status** | Passed |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-5-executable-funding-request-ens-public-goods-working-group-term-5-q1-q2/18885) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xd3437f1c9ece8a309da116be5bffaf31fa40df5361e04e43f9c913970a8746ee) |
### Abstract
The ENS Public Goods Working Group requests funding of the below to **support operations until the September 2024 funding window**.
The Public Goods working group funds projects and builders improving the Web3 ecosystems. This funding stream is authorized in [Article III](https://docs.ens.domains/dao/constitution#iii-income-funds-ens-and-other-public-goods) of the ENS DAO Constitution. This funding supports initiatives related to open-source software, tooling, research and any practical implementations that broadly benefit a wide range of users of Ethereum and Web3.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)) and further required by [this snapshot proposal in Nov. 2023 modifying steward rules.](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
The current balance of the Public Goods multisig contains 147.2k USDC and 33.5 ETH.
The working group requests an additional 450.3k USDC and 21.5 ETH from the DAO to accommodate this proposed budget.
### Current Balances (March 2024)
| USDC | ETH | ENS |
| ------ | ---- | --- |
| 147.2k | 33.5 | 200 |
\*Balance information can be found at [https://enswallets.xyz](https://enswallets.xyz/)
### Expected Spend (Through September 2024)
| Initiative | USDC | ETH |
| ------------------- | ------ | --- |
| Large Grants | 387.5k | 0 |
| Small Grants | 0 | 50 |
| Bounties | 45k | 0 |
| Events + Hackathons | 115k | 0 |
| Discretionary | 50k | 5 |
| Total | 597.5k | 55 |
\*Mult-sig contains 200 ENS that has no planned use. This may be transferred back to the DAO wallet during the term.
### Description of Initiatives
#### [Large Grants](https://discuss.ens.domains/t/public-goods-group-budget-h1-2024/18725#large-grants-3)
Grants up to 50k USDC with applications accepted on a rolling basis throughout the year-long term. Large Grants will resume in Q2. With five grantees completing milestones from last term, the budget includes remaining payouts yet to be
disbursed. We plan to add at least two more grantees during Q2 while piloting new grants management software. In the second half of the year, we will run another full-size round supporting up to 10 grantees at a time with a 200k USD total prize
pool.
#### [Small Grants](https://discuss.ens.domains/t/public-goods-group-budget-h1-2024/18725#small-grants-4)
Multiple micro-grantsvoted on by the community. Small Grants will resume during the first half of the year shortly after ETHDenver. We have added the amount expected to spend through the end of the year with no increase from last term. This is
approximately 12.5 ETH per quarter. With market fluctuations, stewards may right-size and lower the amounts distributed during round
#### [Events and Hackathons](https://discuss.ens.domains/t/public-goods-group-budget-h1-2024/18725#events-and-hackathons-5)
The working group will support Public Goods events and hackathons. Funds have included expenses related to the funding of hackathons, events, and related participation in events (judging, panels, speaking) where necessary.
The current earmarked events are:
* [ETHGuatemala](https://ethereum.gt/)
* [EthLatam](https://ethlatam.org/)
* [ETHGlobal London](https://ethglobal.com/events/london2024)
* [ETHCanal](https://www.ethcanal.xyz/)
* [ETHCC](https://ethcc.io/)
* [ETHGlobal Brussels](https://ethglobal.com/events/brussels)
* [DAO Tokyo](https://dao-tokyo.xyz/)
* [ETHGlobal San Francisco](https://ethglobal.com/events/sanfrancisco2024)
* [ETHGlobal Bangkok](https://ethglobal.com/events/bangkok)
* [Devcon](https://devcon.org/en/)
This list is not guaranteed as several events are still in the planning stages.
The PG stewards will continuously assess opportunities to expand the public goods conversation and collaborations.
#### [Discretionary](https://discuss.ens.domains/t/public-goods-group-budget-h1-2024/18725#discretionary-6)
The funds in this initiative are reserved for additional grant opportunities and expenses that arise during the term. Spending on this initiative is at the discretion of the working group stewards.
## \[EP 5.5] Funding Request: ENS Public Goods Working Group Term 5 (Q1/Q2)
::authors
| **Status** | Passed |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-5-executable-funding-request-ens-public-goods-working-group-term-5-q1-q2/18885) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/48839151689001950442481252711111182244814765601408465024742109276815020082612) |
### Abstract
The ENS Public Goods Working Group requests funding to **support operations until the September 2024 funding window**.
The Public Goods working group funds projects and builders improving the Web3 ecosystems. This funding stream is authorized in [Article III](https://docs.ens.domains/dao/constitution#iii-income-funds-ens-and-other-public-goods) of the ENS DAO Constitution. This funding supports initiatives related to open-source software, tooling, research, and any practical implementations that broadly benefit a wide range of users of Ethereum and Web3.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)) and further required by [this snapshot proposal in Nov. 2023 modifying steward rules](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
The balance of the Public Goods multisig at the time of Snapshot contained 147.2k USDC and 33.5 ETH.
If passed, this proposal will transfer 450.3k USDC and 21.5 ETH from the DAO wallet to the Public Goods working group to accommodate the proposed budget below.
#### Balances (March 2024)\*
| **USDC** | **ETH** | **ENS** |
| :------- | :------ | :------ |
| 147.2k | 33.5k | 200 |
\*Balances above reflect amounts at time of original proposal at time of Snapshot. Current balance information can be found at [https://enswallets.xyz](https://enswallets.xyz).
#### Expected Spend (Through September 2024)\*
| **Initiative** | **USDC** | **ETH** |
| :------------------ | :--------- | :------ |
| Large Grants | 387.5k | 0 |
| Small Grants | 0 | 50 |
| Bounties | 45k | 0 |
| Events + Hackathons | 115k | 0 |
| Discretionary | 50k | 5 |
| **Total** | **597.5k** | **55** |
\*Multisig contains 200 ENS that has no planned use. This may be transferred back to the DAO wallet during the term.
***
### Description of Initiatives
#### Large Grants
Grants up to 50k USDC with applications accepted on a rolling basis throughout the year-long term. Large Grants will resume in Q2. With five grantees completing milestones from last term, the budget includes remaining payouts yet to be disbursed. We plan to add at least two more grantees during Q2 while piloting new grants management software. In the second half of the year, we will run another full-size round supporting up to 10 grantees at a time with a 200k USD total prize pool.
#### Small Grants
Multiple micro-grants voted on by the community. Small Grants will resume during the first half of the year shortly after ETHDenver. We have added the amount expected to spend through the end of the year with no increase from last term. This is approximately 12.5 ETH per quarter. With market fluctuations, stewards may right-size and lower the amounts distributed during round.
#### Events and Hackathons
The working group will support Public Goods events and hackathons. Funds have included expenses related to the funding of hackathons, events, and related participation in events (judging, panels, speaking) where necessary.
The current earmarked events are:
* [ETHGuatemala](https://ethereum.gt/)
* [EthLatam](https://ethlatam.org/)
* [ETHGlobal London](https://ethglobal.com/events/london2024)
* [ETHCanal](https://www.ethcanal.xyz/)
* [ETHCC](https://ethcc.io/)
* [ETHGlobal Brussels](https://ethglobal.com/events/brussels)
* [DAO Tokyo](https://dao-tokyo.xyz/)
* [ETHGlobal San Francisco](https://ethglobal.com/events/sanfrancisco2024)
* [ETHGlobal Bangkok](https://ethglobal.com/events/bangkok)
* [Devcon](https://devcon.org/en/)
This list is not guaranteed as several events are still in the planning stages. The PG stewards will continuously assess opportunities to expand the public goods conversation and collaborations.
#### Discretionary
The funds in this initiative are reserved for additional grant opportunities and expenses that arise during the term. Spending on this initiative is at the discretion of the working group stewards.
## \[EP 5.6] \[Executable] Enable Self-Funding for the Endowment
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-5-6-executable-enable-self-funding-for-the-endowment/18998) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/45720656345448826187222659689199787286494046921153399380076959662321080408931) |
Authorizes metagov to withdraw 30 ETH from the endowment each month for fees, and reimburses metagov for 43.54 ETH in fees already incurred.
### Abstract
This proposal outlines a strategic shift allowing the Endowment to autonomously finance its operations. Specifically, it grants the Metagov stewards the authority to withdraw up to 30 ETH monthly from the Endowment, designated for payments to karpatkey and [@steakhouse](https://discuss.ens.domains/u/steakhouse) for their services in managing the Endowment. This initiative provides the stewards with a direct allowance for these expenses, eliminating the need for these costs to be continually factored into their requests for DAO budget allocations.
Additionally, this proposal seeks to reimburse the [Metagov Safe](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) for the payments made to karpatkey and Steakhouse Financial during 2024, covering the service fees for [January](https://etherscan.io/tx/0x4ef4b34d397e6ce1fbe1fbe3e94340dcf02d590fc9d93c7107a76282beb201c6) and [February](https://etherscan.io/tx/0xdd631a42ccc3762e285276043926c52b86dedbc70fa34dddd611585a38534a89), which total 43.54 ETH.
### Motivation
Since the initiation of the Endowment through the execution of the [first tranche](https://discuss.ens.domains/t/ep3-4-executable-fund-the-endowment-first-tranche/16277#specification-3), payments to karpatkey and Steakhouse Financial for their services have been categorized as operational expenditures. These costs were funded through the Metagov Safe, necessitating routine funding requests from the Meta-Governance Working Group to the DAO.
To simplify and enhance the financial autonomy of the Endowment, we propose granting a monthly allowance of up to 30 ETH to the Metagov Safe by leveraging the Spending Limits feature available on Safe.
This measure allows Metagov stewards to settle Endowment fees directly from funds within the Endowment itself, thus eliminating the regular necessity to refill the Metagov Safe. Should the allowance cap be reached, further withdrawals will be paused until the commencement of the next 30-day cycle. This adjustment eradicates the need for frequent funding operations, paving the way for the Endowment's sustained self-sufficiency.
The monthly cap of 30 ETH has been carefully chosen to align with the Endowment's scale and historical fee structure, ensuring it suffices to cover monthly expenses. Should there be a need to revise this limit to better suit future requirements, adjustments can be facilitated through the submission of a new proposal.
Finally, to ensure the strategic shift is applied retroactively from the outset of 2024, this proposal requests that the Endowment reimburse the Metagov Safe for expenses incurred through payments to karpatkey and Steakhouse Financial. This reimbursement, aimed at covering the service fees for January and February 2024, amounts to a total of 43.54 ETH.
### Specification
The following payload will be executed by the DAO Wallet to create the mentioned allowance and refund:
```plaintext
Calldata:
0x6a76120200000000000000000000000040a2accbd92bca938b02010e17a5b8929b49130d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000002448d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001eb004f2083f5fbede34c2714affb3105539775f7fe6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024610b5925000000000000000000000000cfbfac74c26f8647cbdb8c5caf80bb5b32e4313400cfbfac74c26f8647cbdb8c5caf80bb5b32e4313400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024e71bdf4100000000000000000000000091c32893216de3ea0a55abb9851f581d4503d39b00cfbfac74c26f8647cbdb8c5caf80bb5b32e43134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a4beaeb38800000000000000000000000091c32893216de3ea0a55abb9851f581d4503d39b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8c00000000000000000000000000000000000000000000000000000000001b33acd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b700000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000
Target:
0x4f2083f5fbede34c2714affb3105539775f7fe64
Value:
0
Calldata:
0x6a76120200000000000000000000000091c32893216de3ea0a55abb9851f581d4503d39b0000000000000000000000000000000000000000000000025c3d2750b08200000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b700000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000
Target:
0x4f2083f5fbede34c2714affb3105539775f7fe64
Value:
0
```
## \[EP5.7] \[Social] Security Council
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-enable-cancel-role-on-the-dao/19090) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xf3a4673fe04a3ecfed4a2f066f6ced1539a5466d61630428333360b843653c54) |
### Abstract
The primary mission of ENS DAO is to govern the protocol and allocate resources from the treasury in line with the DAO's constitution and broader objectives. However, due to changing economic dynamics, the DAO is increasingly vulnerable to attacks aimed at draining its treasury.
To safeguard the DAO's integrity and longevity, a Security Council with the authority to cancel malicious proposals is needed. To avoid perpetuating centralized power, the Security Council's authority will have a built-in expiration date. After two years, anyone will be able to call a function that revokes the council's power to veto proposals, ensuring a time-limited mechanism to counter malicious attacks while promoting more delegation and governance distribution.
### Motivation
As ENS continues to grow, its treasury in ETH is always growing. Simultaneously, the percentage of tokens actively delegated is on the decline.

This imbalance creates a risk where an attacker could acquire enough $ENS to gain control of the DAO at a cost lower than the treasury's total value. This has been a growing concern since March 2023.

Past attacks on DAOs have exploited similar vulnerabilities, with some [being thwarted](https://twitter.com/AragonProject/status/1656028382939815937) by components with veto power. Currently, the ENS governance process involves a proposal passing through the governor, relying on delegated voting power for approval. If approved, the governor queues the proposal in a timelock contract, delaying execution by two days. While the governor can cancel proposals, it follows the same pathway as a malicious proposal, introducing potential risks.
The short-term solution was delegating 3.8M $ENS to a contract that can only vote "Against"; more details about this can be found in [Nick's forum post](https://discuss.ens.domains/t/introducing-veto-ensdao-eth/19088). The attack is still profitable and, depending on market conditions can be up to a 3x ROI, like in Dec 2023. We need a mid-term solution to cancel the attack, which is this proposal. An article about this research done by the Blockful team will be published [here](https://blockful.io/blog/ens-security-council-snapshot) after the proposal is executed and there is no attack risk.
### Specification
To enhance security, a veto contract will be deployed. Controlled by a Security Council multisig and will have the PROPOSER\_ROLE in the timelock, granting it the ability to cancel proposals without the power to initiate or modify other DAO actions. The scope of this proposal is to assign the PROPOSER\_ROLE to the veto contract,
To ensure decentralization, the contract will also feature a time-based expiration mechanism that allows anyone to revoke the PROPOSER\_ROLE after two years. This window provides time to strengthen delegation and address current vulnerabilities, facilitating the DAO's transition to a more secure governance model.
### Security considerations
Assigning the PROPOSER\_ROLE to a multisig within the timelock contract is overly broad for our requirements as it allows the address to add proposals directly to the queue. If the multisig signers are compromised, they could potentially propose and execute malicious changes. Therefore our approach would be to deploy a new contract similar to the current veto.ensdao.eth contract, which can only do one action: to CANCEL a transaction in the timelock. That would be a trivially simple contract and it would be hard locked to only accept calls from a newly created SAFE multisig.
The risk is mitigated but one scenario remains: if the whole multisig is compromised then a malicious entity could kick other signers and effectively stop the DAO from executing proposals by canceling all transactions, including any that would remove this contract from the proposal role. Anyways, after 2 years, anyone can remove the proposal role.
With that in light. the following considerations are essential for ensuring the Security Council's multisig operates securely:
* Availability of Signers: It is critical to avoid scenarios where signers are unavailable during emergencies. Events like the Shanghai attack, where real-life occurrences prevent signers from accessing their wallets, must be avoided. Council members should ensure wallets and necessary equipment are accessible at all times.
* Secure Wallet Practices: Security Council addresses should be exclusive to ENS-related operations. Private keys must be stored using best practices to minimize exposure to risks.
Finding the right balance for the multisig threshold is crucial. A higher threshold can complicate coordination but reduces the risk of malicious activity. A lower threshold, while more agile, could make the DAO more susceptible to attacks or unintended consequences if a few signers are compromised. The suggested composition is a 4/8 multisig.
### Council Operations
It is in the best interest of everyone to make clear the expectations and responsibilities ENS DAO put on those members, backed by the reputation, other roles and gains those might have in the organization.
The security council is expected to act only in emergency, in the given following situations or similar cases:
* If a proposal goes against the ENS constitution
* If a proposal is approved with malicious intent against the DAO longevity/sustainability
* If such proposal is approved by any group of voters, but directly financially incentivised to vote against the DAOs interests to preserve their own financial stake.
* If any approved proposal goes directly against the DAO for the sole benefit of an attacker.
Those definitions are not exhaustive, and the trust deposited in the elected members for the council also encompasses the trust in their capacity to:
* understand ENS DAO thoroughly
* listening to the community feedback on extreme situations
* take quick action on behalf of the DAO
* comprehend the proposals being approved and their repercussions
The Security Council members will be the same signers for the veto.ensdao.eth, their identities are known, have signed a pledged to uphold the ENS constitution and live in countries with a solid legal system.
## \[5.8] \[Social] ENS Steward Vesting Proposal
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-8-social-ens-steward-vesting-proposal/19059) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x1f328fd1fda5f3cabfdace3e521403def7ad41b0b0582e27334c135cd23c511d) |
### Abstract
Following discussion in the Metagov funding request thread and feedback on the Temp Check Proposal, we have put together this amendment proposal which looks to add the requirement of vesting to ENS distributions to stewards for the current term.
Under the current proposal, the MetaGov Working Group will be distributed liquid ENS tokens which will then be distributed individually to stewards. As discussed on the forum and on Meta-Gov calls, these tokens should be vested in order to ensure long-term alignment of stewards with the DAO, whilst ensuring that they are able to use the tokens to particiapte in governance.
This proposal is only in reference to adding vesting to current term steward allocations. With more discussion and input needed for any other changes to steward compensation going forward.
### Specification
All ENS disbursements to stewards will be vested on a linear 24 month schedule from the time of their appointment. In line with the 12 month term that each steward serves plus an additional 12 months of vesting to encourage longterm DAO alignment.
This vesting will be implemented by using Hedgey which allows stewards to access the full voting power of their allocated tokens up front, whilst ensuring that the monetary value of these tokens can only be accessed based on the vesting schedule.
All ENS marked for steward compensation will be transferred via executable proposal to the metagov WG multisig. Term 5 stewards were appointed at the beginning of Q1 2024, and as such are already 4 and a half months into their term.
For the current term's stewards, ENS vesting will be scaled retroactively based on the time since their appointment. \~37.5% of ENS will be distributed to stewards directly from the multisig, whilst the remaining ENS will then be deposited into each steward's vesting contract. These contracts will be set up by Hedgey.
### Vote
* For - Apply vesting to the current term
* Against - Do not apply vesting to the current term in line with the 2023/2024 guidance
* Abstain
This vote adjusts the structure of ENS token distributions to stewards, and if passed, the Meta-gov working group will implement this vesting schedule (and associated tooling) for all ENS token distributions to stewards.
## \[5.9] \[Social] Funding Request: ENS Meta-Governance Working Group Term 5 (Q1/Q2)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/5-9-1-social-funding-request-ens-meta-governance-working-group-term-5-q1-q2/19223) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x66d355555c24ed0d2fed0aee89e4fe009e2925c84144c4edc707d33e7c19e554) |
### Abstract
In March 2024, The ENS Metagov funding request for Q1/Q2 failed to gain the support needed to pass.\
The ENS Meta-Governance Working Group is now using the June 2024 funding window to request the Q1/Q2 funding to cover operations until the next funding window in September 2024.
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)) and further required by [this snapshot proposal in Nov. 2023 modifying steward rules.](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Metagov Multisig to fulfill anticipated budgetary needs through September 2024.
| | USDC | ETH | $ENS |
| -------------------------- | :--: | :-: | :--: |
| ENS Meta-Gov Main Multisig | 374k | 0 | 150k |
### Description
#### Current Metagov Wallet Balances (May 25th, 2024)
| | USDC | ETH | $ENS |
| -------------------------- | :--: | :--: | :--: |
| ENS Meta-Gov Main Multisig | 199k | 83.7 | 15k |
\*Updated Balance information can be found at [https://enswallets.xyz](https://enswallets.xyz)
### Expenditures
Meta-Gov sets aside funds to ensure coverage for mission-critical initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives. We anticipate that final expenditures will not surpass the expected expenses allocated for the term.
#### Expected Expenses in Q1/Q2 2024
| | USDC | ETH | $ENS |
| -------------------------------- | ----------- | ------ | -------- |
| Steward + Secretary Compensation | 294,000 | - | |
| Governance | 50,000 | 5 | 105k |
| DAO Tooling | 140,000 | - | - |
| Discretionary | - | 10 | - |
| **Total Balance** | **484,000** | **15** | **105k** |
#### Governance Distributions
| Recipient Category | Amount of $ENS | Method |
| --------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Contributors and Developers | 60k | Vesting contracts |
| Elected Stewards | 90k | A change to 90k and vesting contracts was required to comply with the vesting process described in \[[EP5.8](https://snapshot.org/#/ens.eth/proposal/0x1f328fd1fda5f3cabfdace3e521403def7ad41b0b0582e27334c135cd23c511d)] |
#### Description of Initiatives/Pods
* **Steward + Secretary Compensation**: Working Group Steward and Secretary compensation as required by [revised steward working group rules](https://snapshot.org/#/ens.eth/proposal/0x26a5c8dec547837495707e70446d1e7cd874a91f75753c602998f6e70083a266) and [totaling $294,000 USDC to cover the costs for all 9 stewards and supporting roles for a 6 month period](https://discuss.ens.domains/t/ens-dao-steward-compensation/18063).
* **Governance**: Fee reimbursements and initiatives related to reducing friction in the governance process. This can also include $ENS distributed in order to lower barriers to the governance proposal process. The $ENS distributions to stewards and service providers falls into this category.
* **DAO Tooling**: Developing interfaces and dashboards to improve the governance process and increase transparency across the DAO. An example of DAO tooling spend is our current engagement with Agora as they help build out an enhanced DAO proposal flow to streamline the proposal process.
* **Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments. In this cycle, we've consolidated the former DAO Sponsorship category into this discretionary category.
### Conclusion
This funding request will allow the ENS Meta-Governance Working Group to continue its essential work in providing governance oversight, supporting the management and operation of working groups, and ensuring effective treasury management for the DAO. The requested funds will enable us to maintain our ongoing initiatives and develop new tools to enhance the governance process. We are grateful for the community's ongoing support and engagement, which is crucial to the success of the ENS DAO. The Meta-Governance Working Group remains committed to serving the ENS community and driving the long-term growth and sustainability of the ecosystem.
## \[EP 6.1] \[Executable] Convert 6,000 ETH to USDC for DAO Operating Expenses
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/ep-6-1-executable-convert-6-000-eth-to-usdc-for-dao-operating-expenses/20138) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/33808096277765934415068056906696425640427679116963285327644834080891069190379) |
### Abstract
We propose to convert 6,000 ETH into USDC to replenish the USDC reserves in the [DAO's treasury](https://etherscan.io/address/0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7).
### Motivation
In February 2023, the DAO executed a swap of 10,000 ETH into USDC via [EP 3.3](https://www.tally.xyz/gov/ens/proposal/45461903078948131870051132081249892009497709518413744958551889217805827301425), generating approximately $16.2M in USDC. The rationale at the time was to secure 18–24 months of operational runway.
Over the past 21 months, the USDC reserves have been effectively utilised to fund ENS DAO's operations. However, these reserves have now been fully depleted. To ensure financial stability and effective liquidity management, it is prudent to secure a 12-month runway in the DAO's wallet to cover operating expenses.
We propose ENS convert 6,000 ETH (\~$20.4M at $3,200/ETH) to replenish the USDC reserves. These funds will be used to meet ongoing commitments, such as payments to [ENS Labs](https://discuss.ens.domains/t/ep-5-22-ensv2-development-funding-request/19762), and [Service Provider streams](https://docs.ens.domains/dao/proposals/5.2) and DAO Working Groups.
### Specification
The executable proposal will transfer 6,000 ETH from the ENS DAO Wallet to a [new Safe](https://etherscan.io/address/0x02D61347e5c6EA5604f3f814C5b5498421cEBdEB) created solely for the swap of ETH to USDC. The proposal will also sweep the ETH balance in the [Old Registrar Controller ](https://debank.com/profile/0x283af0b28c62c092c9727f1ee09c02ca627eb7f5)to the DAO wallet.
The payload to transfer 6k ETH from the DAO Multisig is available [here](https://gist.github.com/JeronimoHoulin/5e4728d36bf5d2b7ee08b9382f61bf78). Transaction details:
* From: ENS DAO Wallet ([wallet.ensdao.eth](https://etherscan.io/address/0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7#multichain-portfolio))
* Token: ETH
* Amount: 6,000
* Recipient: TWAP Safe ([0x02D6...BdEB](https://app.safe.global/home?safe=eth:0x02D61347e5c6EA5604f3f814C5b5498421cEBdEB))
karpatkey has deployed a [new Safe](https://app.safe.global/home?safe=eth:0x02D61347e5c6EA5604f3f814C5b5498421cEBdEB) dedicated solely for TWAPs, with karpatkey and ENS representatives as signers. The Safe has a threshold of 3 signatures and the following signers:
1. DAO Wallet ([wallet.ensdao.eth](https://etherscan.io/address/0xfe89cc7abb2c4183683ab71653c4cdc9b02d44b7))
2. karpatkey's Endowment manager Safe ([0xb423e0f6E7430fa29500c5cC9bd83D28c8BD8978](https://etherscan.io/address/0xb423e0f6E7430fa29500c5cC9bd83D28c8BD8978))
3. ENS Labs' cold wallet ([coldwallet.ens.eth](https://etherscan.io/address/0x690F0581eCecCf8389c223170778cD9D029606F2))
4. Metagov Working Group Safe ([main.mg.wg.ens.eth](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b))
This allows for the segregation of funds between other ENS-related wallets (e.g. the Endowment Safe). This proposal sends 6,000 ETH to the newly created Safe.
Signers will swap ETH to USDC via Cow's TWAP mechanism.
The rationale behind this framework is that [Cow's TWAP function](https://docs.cow.fi/cow-protocol/reference/contracts/programmatic/twap) is currently not supported by Tally or the Zodiac Roles Modifier (ZRM) permissions. Once TWAP permissions are integrated, ZRM can be onboarded to this Safe, allowing for the removal of the ENS signers.
Safe keyholders will execute the following swaps:
1. 1,000 ETH swap to meet immediate funding needs by the ENS DAO, executed as soon as funds become available.
2. 5,000 ETH swap via a 3-month TWAP, conducted in 90 parts (\~55.6 ETH sold per part), with wallet.ensdao.eth as recipient.
The payload to call withdraw() on the Old Registrar Controller, and send the funds to the DAO Multisig, is available [here](https://gist.github.com/JeronimoHoulin/f08e7a5704829df606602e53447569e3).
Transaction details:
* From: Old Registrar Controller (0x283af0b28c62c092c9727f1ee09c02ca627eb7f5)
* Token: ETH
* Amount: 4,241.966 (total balance)
* Recipient: ENS DAO Wallet (wallet.ensdao.eth)
## \[EP 6.10] \[Social] Select providers for Service Provider Program Season II
::authors
| **Status** | View results on [spp.vote](https://spp.vote/) |
| --------------------- | --------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20741) |
| **Votes** | [spp.vote](https://spp.vote/) |
This vote will select the Service Providers for the next installment of the program, as approved in [EP 6.3](https://discuss.ens.domains/t/ep-6-3-social-renew-service-provider-budget/20272) and [EP 6.5](https://discuss.ens.domains/t/6-5-amendment-metagovs-facilitation-plan-for-spp2/20638).
**Rank the service providers you want to fund — projects above 'NONE BELOW' are approved; those below are disqualified.**
### IMPORTANT - Please Read: How to Vote
This voting method allows you to specify which service providers you would like to see funded, in order of preference. Each service provider may submit up to two budgets: a basic scope and an extended scope. In order for a provider's extended scope to be approved, their basic scope must also be approved first.
This mechanism lets delegates express their preferences not only for which organizations (service providers) they support, but also which budgets they prefer.
Since this vote uses custom mechanics, the final ranking will differ significantly from what is displayed on Snapshot. We highly recommend using one of the alternative platforms below to vote and follow the results live. All these platforms use the same voting API as Snapshot, so voting through any of them (including Snapshot itself) will always result in a valid vote across all platforms.
* [Lighthouse](https://lighthouse.cx/download) (mobile) – Vote and see results
* [spp.vote](https://spp.vote/) by blockful – Vote and see results
* [Agora](https://agora.ensdao.org/) – See results only
Link to forum post with [UI walk-throughs](https://discuss.ens.domains/t/spp2-voting-walk-through/20724)
#### Step 1 – Move projects above "NONE BELOW"
Drag all the projects you want to fund above the "NONE BELOW" option. Projects you rank above the line are considered approved in your vote; projects you rank below it are considered not approved. Projects that end up below the "NONE BELOW" line in the final tally will be disqualified.
#### Step 2 – Rank by funding priority
Among the projects you placed above "NONE BELOW," rank them according to your funding priorities, considering their scope, team, goals, and cost. The algorithm compares each project against the others to determine the final result. The order of projects below "NONE BELOW" does not affect the outcome. Please try to rank as many projects as you think are worthy, so that if one or more of your top picks doesn't win, your lower-ranked choices can still have an impact.
#### Step 3 – Separate budgets (optional)
Some projects offer both a basic proposal and an extended scope that could be completed in addition to the basic proposal. You may choose to separate and rank them individually. If you rank an extended budget above the basic one, it will count as a vote for both, since the extended scope is dependent on the basic scope.
***
#### Application Index
| Company | Video | Application | BasicBudget | ExtendedBudget | TwoYearEligible |
| --------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------- | -------------- | --------------- |
| Web3.bio | [Video](https://drive.google.com/file/d/1ZLyLcOaO9hijySOMjRqJ0twlWptKdQ0g/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-web3-bio-application/20460) | $ 500,000 | $ - | - |
| Lighthouse Labs | [Video](https://drive.google.com/file/d/16hiJfBZFquWWJBy91J-PNUjeqYDQC784/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-lighthouse-labs/20404) | $ 300,000 | $ - | - |
| Agora | [Video](https://www.loom.com/share/601d20f50483465f92f36160cfabe05d) | [Link](https://discuss.ens.domains/t/spp2-agora-application/20443) | $ 300,000 | $ 100,000 | - |
| Ethereum Identity Fnd | [Video](https://drive.google.com/file/d/1IOZUNr9QyLCrfqoTUgNFr9V1MlsLuV41/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-ethereum-identity-foundation-application/20439) | $ 500,000 | $ 200,000 | ✅ |
| Tally | [Video](https://www.youtube.com/shorts/CvM3g8L_3FY) | [Link](https://discuss.ens.domains/t/spp2-tally-application/20491/2) | $ 300,000 | $ - | - |
| Wildcard Labs | [Video](https://drive.google.com/file/d/1L1d3B70uilMY3EqYivxafM1NF1VVS3iG/view) | [Link](https://discuss.ens.domains/t/spp2-records-xyz-by-wildcard-labs-application/20481) | $ 300,000 | $ 100,000 | ✅ |
| Decent | [Video](https://drive.google.com/file/d/1FQBXyDDe6RHv73k_AAgccl3vd3591jsz/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-decent-application/20497) | $ 300,000 | $ - | - |
| Enscribe | [Video](https://youtu.be/1dRxURznMw8) | [Link](https://discuss.ens.domains/t/spp2-enscribe-application/20474) | $ 400,000 | $ - | - |
| dWeb.host | [Video](https://www.youtube.com/watch?v=TuwGLqHhJps) | [Link](https://discuss.ens.domains/t/spp2-dweb-host-application/20435) | $ 300,000 | $ 100,000 | - |
| GovPal | [Video](https://www.youtube.com/watch?v=bw_bNeuOarM\&t=1s) | [Link](https://discuss.ens.domains/t/spp2-govpal-application/20459) | $ 300,000 | $ - | - |
| Curia Lab | [Video](https://drive.google.com/file/d/1yd7eIQJAuNJ3T4avAL-ki_vuCibTfrSz/view) | [Link](https://discuss.ens.domains/t/spp2-curia-lab-application/20470) | $ 300,000 | $ - | - |
| WebHash | [Video](https://drive.google.com/file/d/1jqfbGabOyLBdQFM0arIr9PXAItSfyhNU/view) | [Link](https://discuss.ens.domains/t/spp2-webhash-eth-application/20466) | $ 300,000 | $ - | - |
| PYOR | [Video](https://drive.google.com/file/d/1sYT6Jxa87ajSHhbzqin6rAC7ULA940PR/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-pyor-application/20429) | $ 300,000 | $ - | - |
| Namespace | [Video](https://www.loom.com/share/58b35446d32e41839e76ba0d64149a5d) | [Link](https://discuss.ens.domains/t/spp2-namespace-application/20456) | $ 400,000 | $ - | ✅ |
| Unruggable | [Video](https://www.youtube.com/watch?v=tpIwvKB0dqo) | [Link](https://discuss.ens.domains/t/spp2-unruggable-application/20485) | $ 400,000 | $ 300,000 | ✅ |
| Unicorn.eth | [Video](https://www.loom.com/share/8ad1dc73e3a643fab6633c1a222f61cb?sid=559a879e-2f18-410a-a003-77ec51c42726) | [Link](https://discuss.ens.domains/t/spp2-ens-accounts-powered-by-unicorn-eth/20467) | $ 300,000 | $ - | ✅ |
| Namestone | [Video](https://www.loom.com/share/81d2e05fb86e4111846f903c77cc1a5d) | [Link](https://discuss.ens.domains/t/spp2-namestone-application/20462) | $ 800,000 | $ - | ✅ |
| eth.limo | [Video](https://drive.google.com/file/d/1bCkKwA9pcxZozktxD4cAWBIni8LS3fCV/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-eth-limo-application/20369) | $ 700,000 | $ 100,000 | ✅ |
| blockful | [Video](https://www.youtube.com/watch?v=YghNB5nersQ) | [Link](https://discuss.ens.domains/t/spp2-blockful-application/20463/3) | $ 700,000 | $ 100,000 | ✅ |
| ZK Email | [Video](https://www.loom.com/share/6644bed1eeb44993926c58772ef72dff) | [Link](https://discuss.ens.domains/t/spp2-zk-email-application/20450) | $ 400,000 | $ 400,000 | - |
| 3DNS | [Video](https://www.youtube.com/watch?v=RJ0HTJeCwPw) | [Link](http://discuss.ens.domains/t/spp2-3dns-inc-ens-resolver-r-d-proposal/20496) | $ 500,000 | $ 200,000 | - |
| x23.ai | [Video](https://drive.google.com/file/d/1JpIZ4ZgGBE2Xdlun-YH0ytUQy9wr8q7y/view) | [Link](https://discuss.ens.domains/t/spp2-x23-ai-application/20464) | $ 300,000 | $ - | - |
| AlphaGrowth | [Video](https://drive.google.com/file/d/1C9ElKtxZD4BJJjKIywVHl0RSR2JIKXp_/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-alphagrowth-application/20451) | $ 400,000 | $ 400,000 | - |
| NameHash Labs | [Video](https://www.youtube.com/watch?v=g88tCK5TECU) | [Link](https://discuss.ens.domains/t/spp2-namehash-labs-application/20502/1) | $ 1,100,000 | $ - | ✅ |
| JustaName | [Video](https://drive.google.com/file/d/1RUxUgQE0_152xquWYpF43TJVLhGdQY6Q/view?usp=sharing) | [Link](https://discuss.ens.domains/t/spp2-justaname-application/20430) | $ 300,000 | $ - | - |
#### Proposal Sources & Links
* [\[EP 6.3\] \[Social\] Renew Service Provider Budget Forum](https://discuss.ens.domains/t/ep-6-3-social-renew-service-provider-budget/20272)
* [\[EP 6.3\] \[Social\] Renew Service Provider Budget Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x0cca1cf36731203e235b0e2de9041be3a16d9cdeadff6e15e1f1215c611e12ef)
* [SPP 2 Facilitation Plan (Original)](https://discuss.ens.domains/t/metagov-s-facilitation-plan-for-spp2/20340)
* [\[6.5 Amendment\] Facilitation plan for SPP2](https://discuss.ens.domains/t/6-5-amendment-metagovs-facilitation-plan-for-spp2/20638)
* [Application Index Tracker](https://discuss.ens.domains/t/spp2-application-index/20495)
* [Service Provider Season 2 Vote Amendment Proposal](https://discuss.ens.domains/t/temp-check-social-service-provider-season-2-vote-amendment-proposal/20526)
* [\[EP 6.4\] \[Social\] SPP2 Vote Amendment Proposal](https://snapshot.box/#/s\:ens.eth/proposal/0xf0c3a2fe4bd085ea74a072cafb830aaadb4830b557a3d122eab36058a17c1860)
* [\[EP 6.5\] \[Social\] SPP2 Vote Amendment Proposal II ](https://snapshot.box/#/s\:ens.eth/proposal/0x60c95ab69a427ce263f4c3c950df8da1134e96a3e76d139c8dac366271009530)
*The Discussion link below leads to a manifest file needed to support one of the custom voting UIs.*
For the ENS DAO discussion, please see this: [ENS DAO Forum Discussion Thread \[EP 6.10\]](https://discuss.ens.domains/t/6-10-social-select-providers-for-service-provider-program-season-ii/20741)
## \[EP 6.11] \[Executable] Collective Working Group Funding Request (April 2025)
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20788) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/18742211083269328003498907723174230327570776601682376043962489402709315500668) |
### Abstract
This proposal executes funding requests for the Meta-Governance and Public Goods Working Groups for the April 2025 funding window as passed in [EP 6.6.1](https://discuss.ens.domains/t/6-6-1-social-april-funding-request-ens-meta-governance-working-group-term-6/20536) and [EP 6.6.2](https://discuss.ens.domains/t/6-6-2-social-april-funding-request-ens-public-goods-working-group-term-6/20532). This bundled executable proposal follows the requirements set out in Rule 10.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/dao/proposals/1.8/)).
### Proposal Components
***
#### 1) [Meta-governance Funding Request \\\[EP 6.6.1\\\]](https://discuss.ens.domains/t/6-6-1-social-april-funding-request-ens-meta-governance-working-group-term-6/20536)
The Meta-Governance Working Group requests funding to fulfill anticipated budgetary needs through the next formal funding window in October 2025.
| Destination | USDC | ETH | $ENS |
| ----------------------------------------------------------------------------------------------------- | ------- | --- | ------- |
| [ENS Meta-Gov Main Multisig](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) | 589,000 | 0 | 100,000 |
This amount will cover all expected expenses outlined in the social proposal while leaving a prudent reserve to ensure continuity if future funding is delayed.
***
#### 2) [Public Goods Funding Request \\\[EP 6.6.2\\\]](https://discuss.ens.domains/t/6-6-2-social-april-funding-request-ens-public-goods-working-group-term-6/20532)
The ENS Public Goods Working Group requests funding to support operations through the next formal funding window in October 2025.
| Destination | USDC | ETH | $ENS |
| ----------------------------------------------------------------------------------------------- | ------- | --- | ---- |
| [ENS PG Main Multisig](https://etherscan.io/address/0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d) | 356,000 | 0 | 0 |
This amount represents the adjusted funding request after discussions in the forum, reducing the original request from 521k to 356k by adjusting the Strategic Grants and discretionary funding categories.
***
### Specification
The following transfers are to be made from the DAO treasury:
1. Transfer 589,000 USDC to the Meta-governance safe:
* Address: `0x91c32893216dE3eA0a55ABb9851f581d4503d39b`
2. Transfer 100,000 ENS to the Meta-governance safe:
* Address: `0x91c32893216dE3eA0a55ABb9851f581d4503d39b`
3. Transfer 356,000 USDC to the Public Goods safe:
* Address: `0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d`
##### Total transfer amount: 945,000 USDC and 100,000 ENS
***
####
## \[EP 6.12] \[Executable] Set resolver for .ceo TLD
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20820) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/75480516867756766284972947192514005324792532674550120092693062891336419998702) |
### Abstract
[EP6.7](https://discuss.ens.domains/t/ep-6-7-executable-transfer-ceo-tld-to-the-dnssec-registrar/20594) reconfigured the .ceo TLD, setting the owner record to the DNSSEC registrar contract. This allowed onchain claiming of .ceo 2LDs to resume, reclaiming control from a custom registrar that had been set by a previous owner of .ceo.
Unfortunately, this neglected to consider the necessary infrastructure for offchain claiming, which requires also setting the resolver record. As a result, a follow-up executable EP is required to set the resolver also.
To prove ownership of .ceo and their intention that we action this request, they have set a TXT record on `_ens.nic.ceo` to the address of the DNSSEC registrar, `0xB32cB5677a7C971689228EC835800432B339bA2B`. This can be verified with the following command:
```
dig TXT _ens.nic.ceo
```
### Specification
1. Call `setSubnodeOwner` on the ENS `Root` contract at `0xaB528d626EC275E3faD363fF1393A41F581c5897`, passing in the keccak256 hash of `ceo` and the address of the ENS timelock, `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`.
2. Call `setResolver` on the ENS registry contract at `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`, passing in the namehash of `ceo` and the address of the `OffchainDNSResolver`, `0xF142B308cF687d4358410a4cB885513b30A42025`.
3. Call `setOwner` on the ENS registry contract at `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`, passing in the namehash of `ceo` and the address of the DNSSEC reistrar at `0xB32cB5677a7C971689228EC835800432B339bA2B`.
## \[EP 6.13] \[Executable] - Service Provider Program Season 2 Implementation
::authors
| **Status** | Passed |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20971) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/6325634497264265012626716784077918930541180346289202027480596910133312093648) |
### Correction
The previous version of this proposal has incorrect text in the description. This version is corrected.
### Abstract
This executable proposal implements the Service Provider Program Season 2 (SPP2) following the approval of [EP 6.10](https://www.tally.xyz/gov/ens/proposal/50462913323863149622798490468303951055439459905477651666479638328507088159695) for service provider selection and the budget framework established in [EP 6.3](https://www.tally.xyz/gov/ens/proposal/45863606498975303062952719073086674668061306651606831273917754523416516421073).
This proposal transitions our existing streaming infrastructure from the $3.6M annual budget supporting 9 providers to the new $4.5M annual budget supporting 8 providers, including 6 continuing providers and 2 new additions.
### Specification
Following the selection of service providers in EP 6.10, this proposal implements the technical changes required to:
1. **Adjust Streaming Infrastructure** - Update the master flow rate from ENS DAO to the Stream Management Pod to accommodate the increased budget
2. **Provide Initial Funding** - Supply one month of USDC funding (375,000 USDC) to ensure uninterrupted service
3. **Configure Autowrap Parameters** - Set appropriate allowances for automatic USDC-to-USDCx conversion
The Stream Management Pod will continue to manage individual provider streams, adjusting rates for continuing providers and establishing new streams for JustaName and ZK Email.
#### Service Provider Allocations
The following providers and allocations have been approved:
| Service Provider | Annual Allocation | Stream Duration |
| -------------------------- | ----------------- | --------------- |
| ETH.LIMO | $700,000 | 2 years |
| Blockful | $700,000 | 2 years |
| Namehash Labs | $1,100,000 | 1 year |
| Ethereum Identity Protocol | $500,000 | 1 year |
| Unruggable | $400,000 | 1 year |
| Namespace | $400,000 | 1 year |
| ZK Email | $400,000 | 1 year |
| Justaname | $300,000 | 1 year |
| **Total** | **$4,500,000** | |
#### Technical Implementation
The implementation maintains our existing Superfluid architecture:
* ENS Treasury (Timelock) → Stream Management Pod → Individual Service Providers
* The Stream Management Pod continues to be controlled by 3 of 5 signatures (3 Metagov Stewards, Secretary, and DAO Governor)
* Security measures remain in place, limiting exposure to approximately 50 days of funding in case of contract compromise
### Transactions
#### Transaction 1: Approve USDCx
**Target:** `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` (USDC)\
**Function:** `approve`\
**Arguments:**
* `spender: 0x1BA8603DA702602A8657980e825A6DAa03Dee93a`
* `amount: 375000000000`
**Calldata:**
```
0x095ea7b30000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a000000000000000000000000000000000000000000000000000000000574fbde600
```
* Tenderly: [Approve USDCx](https://www.tdly.co/shared/simulation/2207ca50-6804-4e33-be61-4181ecd3f8e5)
#### Transaction 2: Upgrade USDC to USDCx
**Target:** `0x1BA8603DA702602A8657980e825A6DAa03Dee93a` (USDCx)\
**Function:** `upgrade`\
**Arguments:**
* `amount: 375000000000000000000000`
**Calldata:**
```
0x45977d03000000000000000000000000000000000000000000004f68ca6d8cd91c600000
```
* Tenderly: [Upgrade USDC](https://www.tdly.co/shared/simulation/6abf821b-779e-429b-b8dd-707b71360687)
#### Transaction 3: Set Flow Rate
**Target:** `0xcfA132E353cB4E398080B9700609bb008eceB125` (Superfluid)\
**Function:** `setFlowrate`\
**Arguments:**
* `token: 0x1BA8603DA702602A8657980e825A6DAa03Dee93a`
* `receiver: 0xB162Bf7A7fD64eF32b787719335d06B2780e31D1`
* `flowrate: 142599440769357573`
**Calldata:**
```
0x57e6aa360000000000000000000000001ba8603da702602a8657980e825a6daa03dee93a000000000000000000000000b162bf7a7fd64ef32b787719335d06b2780e31d100000000000000000000000000000000000000000000000001fa9d6f943a1705
```
* Tenderly: [Set Flow Rate](https://www.tdly.co/shared/simulation/9dd3a70d-cec4-4fac-88cf-9362fda170fc)
#### Transaction 4: Set Autowrap Allowance
**Target:** `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` (USDC)\
**Function:** `approve`\
**Arguments:**
* `spender: 0x1D65c6d3AD39d454Ea8F682c49aE7744706eA96d`
* `amount: 6375000000000`
**Calldata:**
```
0x095ea7b30000000000000000000000001d65c6d3ad39d454ea8f682c49ae7744706ea96d000000000000000000000000000000000000000000000000000005cc4b9c4600
```
* Tenderly: [Set Autowrap Allowance](https://www.tdly.co/shared/simulation/e192ea31-145c-4d50-9632-1342267f5b8b)
#### Transaction Details
1. **Approve USDCx**: Allows the USDCx contract to spend 375,000 USDC from the ENS DAO treasury for the initial month of funding
2. **Upgrade USDC to USDCx**: Wraps 375,000 USDC to USDCx (Superfluid's streaming token format)
3. **Set Flow Rate**: Increases the master stream from 0.114155251141552512 USDCx per second ($3.6M/year) to 0.142599440769357573 USDCx/second ($4.5M/year)
4. **Set Autowrap Allowance**: Authorizes the Superfluid autowrapper to convert up to 6.375M USDC over time, ensuring continuous funding availability
### Verification
The testing repository with calculation tools and verification scripts is available at [github.com/5ajaki/SPP2-Streams](https://github.com/5ajaki/SPP2-Streams).
### Implementation Timeline
Upon passage of this proposal:
1. The transactions will be executed immediately
2. The Stream Management Pod will receive the increased flow rate
3. Metagov stewards will coordinate with service providers to:
* Update existing provider streams to new rates
* Establish streams for new providers (JustaName and ZK Email)
* Calculate and distribute any backdated payments for rate increases
All providers will continue to be subject to the existing KYC and sanctions compliance requirements established in SPP1.
## \[EP 6.14] \[Social] Proposal to form the OpenBox Investment Committee
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20947) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xa9c47b281667a85f80e0cc9be5904438c9205e123352779cbb69b0ecf583307c) |
### Abstract
This social proposal seeks to authorize the formation of the **OpenBox Investment Committee,** a temporary committee tasked with evaluating a potential $5 million equity investment by the ENS DAO into OpenBox Inc. The proposal does **not** commit the DAO to any investment. Instead, it empowers a select group—including ENS Foundation directors, DAO delegates, and an ENS Labs observer—to conduct due diligence, assess the proposal, and deliver a formal recommendation to the DAO.
If the committee recommends proceeding, a separate executable proposal would be submitted for DAO approval prior to any transfer of funds.
As a general precedent, the ENS DAO is not focused on venture style investment, but utilizing the DAO treasury for an investment with the right strategic importance aligns with the DAO constitution.
### Background
OpenBox Inc. is a new venture led by Intercap, the technology investment firm behind projects like my.inc, my.box, and 3DNS. The company is developing the Open Domain Protocol (ODP), a registry infrastructure that enables DNS top-level domains to integrate natively with ENS, making them fully compatible with Ethereum wallets, dapps, and web3 identity tools.
To support this effort, OpenBox has invited the ENS DAO to invest $5 million over five years in exchange for a 10% equity stake. This would be the DAO's first equity investment in a for-profit entity and is designed to align the ENS ecosystem with upcoming opportunities in the 2026 ICANN gTLD application round—where control of new top-level domains will shape the next generation of naming on the internet.
### Motivation
The 2026 ICANN gTLD application round presents a rare and time-sensitive opportunity for ENS to extend its influence and establish itself as the naming standard across both web2 and web3. Competing protocols are already pursuing registry partnerships that could fragment the ecosystem and undermine ENS's leadership.
OpenBox offers a credible path for ENS to participate in this next wave of naming infrastructure—while maintaining alignment with its mission. However, because this would mark the DAO's first equity investment, it is essential to approach the opportunity with rigor and transparency.
This proposal creates a structured, time-bound process to evaluate the deal responsibly while preserving the ability to act quickly if the opportunity proves sound.
### Specification
#### **Authorization**
If passed, this proposal authorizes the formation of the OpenBox Investment Committee consisting of:
1. The three ENS Foundation directors
* [Nick.eth](https://app.ens.domains/nick.eth)
* [Avsa.eth](https://app.ens.domains/avsa.eth)
* [Validator.eth](https://app.ens.domains/validator.eth)
2. Two delegates appointed by the Meta-Governance working group
* [Coltron.eth](https://app.ens.domains/coltron.eth)
* [Clowes.eth](https://app.ens.domains/clowes.eth)
3. One representative from ENS Labs (non-voting observer)
* [Katherine.eth](https://app.ens.domains/katherine.eth)
4. Legal Counsel (non-voting consultant)
* To be retained and managed by Alex Urbelis
#### Confidentiality
The OpenBox Investment Committee may enter into a standard Non-Disclosure Agreement (NDA) with Intercap & OpenBox Inc. to facilitate access to sensitive business, legal, or technical information. While this may limit the public disclosure of certain details, the Committee remains responsible for providing the DAO with sufficient transparency to make an informed decision—balancing confidentiality obligations with the need for DAO accountability.
#### **Scope of Activities**
**Review and validate terms** of a potential investment to ensure they are commercially reasonable and appropriate for a minority investor, including:
* **Shareholder rights and protections** (e.g., information rights, protective provisions, tag-along rights)
* **Board participation**
* **Use of proceeds** (to confirm alignment between capital deployment and DAO priorities)
* **Reporting obligations** (e.g., cadence and format of updates from management)
* **Monetization and value realization** (e.g., liquidity and dividend mechanics)
* **Open Source Commitments** (an agreed to understanding of what components will be fully open source software)
**Conduct initial due diligence**, including but not limited to:
* Underlying business model
* Legal structure and corporate governance
* Technical evaluation of the Open Domain Protocol (ODP)
* Reference checks on key personnel
* Analysis of the team's track record and relevant experience
**Provide regular updates** to the Meta-Governance working group by having a designated representative attend weekly calls and report on the status and progress of the investment process.
**Draft recommendation** in the form of an Investment Memo that details the following:
1. **Due Diligence Summary**
1. Assess the OpenBox business model, team, legal structure, and strategic alignment with ENS DAO goals.
2. Summarize findings in a transparent and digestible format for delegates.
2. **DAO Fit Assessment**
1. Clarify the legal, operational, and reputational implications of the Foundation holding an equity stake.
2. Evaluate the DAO's ability to participate meaningfully and manage the investment over time.
3. **Deal Terms Review**
1. Evaluate whether the proposed terms are commercially reasonable given the structure and circumstances of the deal.
2. Ensure the terms are broadly fair, protect the DAO's interests, and align with standard market practices for minority investments.
4. **Recommendation Report**
1. Deliver a clear "Go / No-Go" recommendation based on the committee's findings.
2. If recommending to proceed, outline the next steps for finalizing the investment, including follow-on proposals to authorize the signing of definitive agreements and the transfer of funds.
#### Expenses
It is expected that the OpenBox Investment Committee may incur reasonable expenses in the course of its work. These expenses will be eligible for reimbursement through the existing Meta-Governance working group budget, subject to standard approval processes.
#### **Limitations**
This proposal is strictly exploratory and carries the following constraints:
* It **does not commit** the DAO to any investment decision.
* It **does not authorize** the transfer of any funds.
* It **automatically expires** 120 days after passage, unless extended by another Social Proposal to the full ENS DAO.
* It **may be terminated** by either party at any time with 15 days' written notice.
### Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
**Quorum**: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
**Approval**: Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
### Next Steps
If this proposal passes:
1. The OpenBox Investment Committee will be appointed within 7 days.
2. The group will engage with Intercap to define the investment process and timeline.
3. As materials are shared, the group will begin reviewing the investment opportunity.
4. Regular updates will be provided through Meta-Governance Working Group calls.
5. A formal Investment Memo and recommendation will be submitted to the DAO within the evaluation window.
## \[EP 6.15] \[Social] Enhancing ENS Governance with Tally’s Enterprise Support
::authors
| **Status** | Rejected |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20937/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xf06f3ad61f9f77c8ed362dd54913cc44d030841eebebfffce4dd6605b1b0e6f3) |
### Abstract
Tally proposes a formal enterprise level service agreement that elevates ENS governance UX, broadens the distribution of ENS primitives across
all governance users on Tally, and furnishes the DAO with battle-tested uptime, reporting, and support guarantees. This proposal formalises a
service agreement that ensures the DAO can hold us to explicit uptime and delivery standards.
### Scope of work
#### Proposal-lifecycle webhooks
We will ship a fully open-source webhook system that listens directly to Governor events, signs each payload, retries on failure, and delivers notifications to any Slack, Discord, Telegram, or custom endpoint the DAO chooses.
The webhooks will be deeply integrated into Tally’s backend infrastructure (proprietary), but the webhook spec and the onchain proposal events (on-chain publish, quorum reached, execution) are public, and anyone could add them to a community-run webhook system. Via these webhooks, delegates will be able to receive draft-published pings, quorum alerts, 24-hour reminders, execution confirmations, and more, reducing missed votes and improving quorum.
The part that would be harder for a community-run system to duplicate would be reliability. This proposal includes an SLA, monitoring, alerting and the engineering resources to keep the webhooks and the rest of the tally.xyz services running reliably for ENS DAO.
#### Deep ENS integrations
1. ##### Prioritize Namechain rollout
As soon as Namechain is live on mainnet, Tally will add support for it on tally.xyz. Tally will index, decode, and display governance contracts on the network.
2. ##### Indexing offchain ENS names
Tally will extend our resolver pipeline to ingest CCIP-Read & wildcard-enabled sub-name registries (eg \*.cb.id issued by Coinbase) and Farcaster’s \*.fcast.id Fnames, cryptographically verifying gateway signatures before caching in our indexer. Every user, regardless of where their ENS-compatible name is anchored, will see that name reflected on Tally profiles and proposal metadata.
3. ##### Action to Update ENS record
Create a low-code proposal builder that lets all DAOs on Ethereum mainnet easily modify text records directly from a proposal. This includes setting resolvers and records (text, address, reverse).
Core governance flows, ENS look-ups, and the waived 0.25% proposal fee all remain free, just as they have for the past 3 years. The paid scope accelerates work that is uniquely heavy for ENS. We could build these eventually, but a formal mandate moves them to the front of the queue *and* ties them to explicit SLAs the DAO can hold us to.
#### Indexing off-chain proposals (new from temp check)
Offchain Snapshot votes will be fetched, ordered canonically alongside executable proposals, and displayed in the same list view. Delegates will no longer need to context-switch or risk overlooking social-signal polls that lead to on-chain execution.
#### Enhanced Proposal Transparency (new from temp check)
**Full calldata preview** - The proposal builder will generate and display the complete ABI-encoded calldata for each action so delegates can verify it directly against third-party checkers such as Blockful, without resorting to “click-Publish-then-copy.”
**Import / export of action bundles** - Builders will be able to paste a single ABI-encoded blob or upload a JSON transaction bundle in the Gnosis Safe format; likewise, any proposal drafted on Tally can be exported in either format for external audit or reuse.
**Readable bytes32 fields** - Posted proposals will render bytes32 parameters in clean hexadecimal so reviewers no longer have to decode them offline.
#### Enterprise-grade support
ENS will have access to Tally’s in-house engineers directly available to proactively resolve support issues and assist users, even in cases where the issues are not confined exclusively to the Tally platform. In addition, we will be waiving the 0.25% transfer fee on every proposal.
**Support response time guarantees**
* Critical Issues (e.g., service outage, security breach): Initial response within 1 hour, updates every 2 hours until resolved.
* High-Priority Issues (e.g., significant performance issues, partial system failure): Initial response within 4 hours, updates every 6 hours until resolved.
* Medium-Priority Issues (e.g., UI/UX bugs, non-critical feature issues): Initial response within 1 business day, resolved within a commercially reasonable timeframe.
* Low-Priority Issues (e.g., minor bugs, general inquiries): Initial response within 3 business days, resolved within a commercially reasonable timeframe
#### KPIs and Success Metrics
##### Ongoing Program KPIs
* 90 % + attendance at weekly MetaGov calls by at least one Tally team member
* Maintain 99.9 % + uptime for the ENS Tally client (web + API)
* Support 100 % of on-chain governance proposals with timely frontend updates reflecting user feedback and governance activity
* Add full support for Namechain on mainnet launch
##### Quarterly KPIs
* Deliver quarterly reports detailing features shipped to the ENS Tally client and their alignment with ENS governance priorities
* Publish a quarterly feedback and fixes summary documenting bugs, feature requests, and actions taken by the Tally team
* Report ENS-specific usage metrics within Tally, including delegate discovery traffic, proposal creation frequency, and number of unique ENS-based user sessions
* Highlight integrations or UI/UX improvements that expand ENS visibility within Tally, such as showcasing ENS names in proposal authorship, delegate profiles, and voting summaries
#### SLAs
* Tally usage
* We will continue to track the number of proposals and % of votes per proposal made on Tally and report on those to the DAO.
* Roadmap feature usage
* As we roll out new features for the ENS DAO, we will track usage of those features and report on them to the DAO.
* Monthly office hours
* An open feedback session for ENS DAO contributors to suggest new features and contribute to our roadmap
* Uptime and availability
* System Uptime: 99.9% monthly uptime, ensuring the system is accessible with minimal disruptions.
* Scheduled Downtime: Maximum of 2% monthly allowance for scheduled maintenance, communicated in advance.
* Response and resolution time
* As per the Enterprise Support Levels section above.
* Maintenance and support
* Bug Resolution: Resolution of non-critical bugs within 5 business days and critical bugs within 1 business day. For bugs that are not possible to resolve in this time frame, a post-mortem analysis to be shared with the DAO following resolution.
* Regular Maintenance Updates: Regular monthly maintenance updates, including minor upgrades, patches, and performance improvements.
* [Public API access](https://apidocs.tally.xyz/)
* Tally provides open access to its governance API, allowing developers to query proposal data, vote records, delegate profiles, and DAO metadata. We ensure 99.9% monthly uptime for the API and will notify the DAO of any major updates, deprecations, or downtime.
* Feature requests and support for API integrations can be raised during monthly office hours or through direct support channels.
#### Costs
| Workstream | Year 1 Cost (USD) | Recurring (Year 2 onwards) |
| :---------------------------------------------- | :--------------------------------------------------------------- | :-------------------------------------------------------------- |
| Proposal lifecycle Webhooks | $28,000 | |
| ENS integration (off-chain indexing, Namechain) | $92,000 | |
| Offchain proposal integration | $20,000 | |
| Enhanced Proposal Transparency | $15,000 | |
| Enterprise Support Levels | $60,000 | |
| **Total** | **$215,000** | **$60,000** |
| Payment Split | $175,000 (USD) + $40,000 in ENS tokens to be used for governance | $40,000 (USD) + $20,000 in ENS tokens to be used for governance |
##### Payment Operations
As clarified by multiple delegates during the Meta-Governance Weekly Calls, Tally will be positioning this as a social proposal instead of an executable one, to request for funds for the above mentioned work scope from the [MetaGov Committee’s budget](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b).
A successful Snapshot vote will task the Meta-Gov stewards with working alongside Tally to define clear, time-bound milestones for Year 1 and to release each payment only after the relevant milestone is met to the DAO’s satisfaction. At the one-year mark the committee will review performance against those milestones and SLAs; it may then renew the agreement at the quoted Year 2 rate, or decline to renew, taking into account both its own assessment and any signal delegates provide.
#### No Exclusivity
We want to call out a common point of concern raised by multiple delegates across the temperature check post, as well as on the MetaGov Weekly Calls.
When we say dedicated we mean “formally accountable”, not “sole vendor.” We wholeheartedly agree that governance is more than just creating and voting on proposals, and supporting every end to end engagement is not something a single provider can feasibly, and optimally do today.
To reflect this explicitly, we have amended the title of the proposal from ‘Should the DAO have Tally as a Dedicated Governance Service Provider?’ to ‘**Enhancing ENS Governance with Tally’s Enterprise Support’.**
#### Next Steps
If this proposal passes,
1. **Post-approval coordination**
1. Tally and the Meta-Gov stewards will draft a time-boxed Year 1 milestone plan.
2. The plan will be posted on the forum and reviewed in the next weekly Meta-Gov call.
3. Delegates may raise questions in the thread at any time; Tally will reply promptly.
2. **Initial disbursement**
1. Once the milestone plan is ratified, the stewards will release **US$40 000** in stablecoins and **US$20 000 in ENS** (to be retained for on-chain voting) to cover the Year 1 enterprise support budget.
3. **Ongoing reporting and payments**
1. Subsequent disbursements will be made only after each milestone is completed to the stewards’ satisfaction.
2. Tally will provide ongoing progress updates during Meta-Gov Weekly calls.
4. **Year-end review**
1. As the twelve-month mark approaches, Tally and the stewards will prepare a comprehensive report detailing completed milestones, ongoing builds, and payment status to inform any renewal decision.
#### Conclusion
ENS has long been Tally’s most influential partner, anchoring on-chain identity and powering roughly 70% of all onchain votes cast through our platform. This agreement lets us double-down on that partnership - bringing real-time governance alerts, Namechain continuity, seamless record management, and iron-clad uptime, while the DAO retains full optionality, open code, and clear recourse if we fall short.
We are committed to engaging more consistently with working groups, Meta-Gov calls, and delegate discussions, and we welcome any further suggestions that strengthen ENS governance for the years ahead.
## \[EP 6.16] \[Executable] Enable L2 Reverse Registrars and new .eth registrar controller
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20969/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/42524979896803285837776370636134389407867034021879791462477783237030656381157), [Tally](https://tally.ensdao.org/dao/proposal/42524979896803285837776370636134389407867034021879791462477783237030656381157) |
## Abstract
This proposal enables five chain-specific reverse resolvers for L2 EVM networks, and one default reverse resolver as a fallback mechanism. The five chains are Arbitrum, Base, Linea, OP Mainnet and Scroll.
This proposal also enables a new .eth registrar controller and sets the reverse record of some currently un-named ENS contracts.
## Motivation
The current implementation of reverse resolution is limited to Ethereum Mainnet and assumes that every entity (a generic smart contract or user account) has the same address across every EVM chain. This has been falling out of line with reality given the rise in smart contract accounts, indicating that reverse resolution should be resolved via a namespace for each chain, rather than a single reverse namespace for the Ethereum ecosystem at large.
This functionality defined formally in [ENSIP-19](https://docs.ens.domains/ensip/19/), combined with [ENSIP-11](https://docs.ens.domains/ensip/11/), enables “L2 Primary Names,” meaning developers can build end-to-end ENS experiences without forcing their users to transact on Ethereum Mainnet.
To support optionally setting the default reverse record at registration time, a new .eth registrar controller must also be enabled. Since new controllers have significant overhead, we are also taking advantage of this opportunity to add a `referrer` field for registrations and renewals. This field is emitted unchanged from the registration and renewal events and allows clients to convey information about the source of a registration or renewal for potential DAO-based referral reward schemes (not defined in this proposal).
## Specification
### Description
Batch transaction for ENS DAO execution
### Transactions Summary
This proposal contains **16** transaction(s) to be executed by the ENS DAO Timelock.
| # | Contract | Function | Description |
| -- | ------------------------- | -------------------- | ---------------------------------------------------------------- |
| 1 | registry.ens.eth | `setResolver` | Call setResolver on registry.ens.eth |
| 2 | registry.ens.eth | `setSubnodeRecord` | Set Arbitrum reverse namespace |
| 3 | registry.ens.eth | `setSubnodeRecord` | Set Base reverse namespace |
| 4 | registry.ens.eth | `setSubnodeRecord` | Set Linea reverse namespace |
| 5 | registry.ens.eth | `setSubnodeRecord` | Set Optimism reverse namespace |
| 6 | registry.ens.eth | `setSubnodeRecord` | Set Scroll reverse namespace |
| 7 | ETH Registrar | `addController` | Authorise new controller on registrar |
| 8 | Reverse Registrar | `setController` | Authorise new controller on reverse registrar |
| 9 | Default Reverse Registrar | `setController` | Authorise new controller on new default reverse registrar |
| 10 | .eth Resolver | `setInterface` | Set new controller interface to new controller on .eth resolver |
| 11 | Reverse Registrar | `setDefaultResolver` | Set default resolver to new public resolver on reverse registrar |
| 12 | Reverse Registrar | `setNameForAddr` | Set primary name for DNSSEC contract |
| 13 | Reverse Registrar | `setNameForAddr` | Set primary name for registrar |
| 14 | Reverse Registrar | `setNameForAddr` | Set primary name for root |
| 15 | Reverse Registrar | `setNameForAddr` | Set primary name for new controller |
| 16 | Reverse Registrar | `setNameForAddr` | Set primary name for default reverse registrar |
### Detailed Transaction Information
### Description
Batch transaction for ENS DAO execution
### Transactions Summary
This proposal contains **16** transaction(s) to be executed by the ENS DAO Timelock.
| # | Contract | Function | Description |
| -- | ------------------------- | -------------------- | ---------------------------------------------------------------- |
| 1 | registry.ens.eth | `setResolver` | Call setResolver on registry.ens.eth |
| 2 | registry.ens.eth | `setSubnodeRecord` | Set Arbitrum reverse namespace |
| 3 | registry.ens.eth | `setSubnodeRecord` | Set Base reverse namespace |
| 4 | registry.ens.eth | `setSubnodeRecord` | Set Linea reverse namespace |
| 5 | registry.ens.eth | `setSubnodeRecord` | Set Optimism reverse namespace |
| 6 | registry.ens.eth | `setSubnodeRecord` | Set Scroll reverse namespace |
| 7 | ETH Registrar | `addController` | Authorise new controller on registrar |
| 8 | Reverse Registrar | `setController` | Authorise new controller on reverse registrar |
| 9 | Default Reverse Registrar | `setController` | Authorise new controller on new default reverse registrar |
| 10 | .eth Resolver | `setInterface` | Set new controller interface to new controller on .eth resolver |
| 11 | Reverse Registrar | `setDefaultResolver` | Set default resolver to new public resolver on reverse registrar |
| 12 | Reverse Registrar | `setNameForAddr` | Set primary name for DNSSEC contract |
| 13 | Reverse Registrar | `setNameForAddr` | Set primary name for registrar |
| 14 | Reverse Registrar | `setNameForAddr` | Set primary name for root |
| 15 | Reverse Registrar | `setNameForAddr` | Set primary name for new controller |
| 16 | Reverse Registrar | `setNameForAddr` | Set primary name for default reverse registrar |
### Detailed Transaction Information
#### Transaction 1: Call setResolver on registry.ens.eth
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setResolver`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `address resolver`: `0xA7d635c8de9a58a228AA69353a1699C7Cc240DCF`
**Encoded Calldata:**
```
0x1896f70aa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34000000000000000000000000a7d635c8de9a58a228aa69353a1699c7cc240dcf
```
***
#### Transaction 2: Set Arbitrum reverse namespace
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setSubnodeRecord`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `bytes32 label`: labelhash("8000a4b1") → 0xa7f8a095a00b663580c29f964c4bfc4ce8f41776d9ea5b70e2e08e69327a77bc
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0x4b9572C03AAa8b0Efa4B4b0F0cc0f0992bEDB898`
* `uint64 ttl`: `0`
**Encoded Calldata:**
```
0x5ef2c7f0a097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34a7f8a095a00b663580c29f964c4bfc4ce8f41776d9ea5b70e2e08e69327a77bc000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b70000000000000000000000004b9572c03aaa8b0efa4b4b0f0cc0f0992bedb8980000000000000000000000000000000000000000000000000000000000000000
```
***
#### Transaction 3: Set Base reverse namespace
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setSubnodeRecord`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `bytes32 label`: labelhash("80002105") → 0x72c29f4186361a46935e4e9c3af71d1cf73cac00186fceb1cd1945ed9ed3dec1
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xc800DBc8ff9796E58EfBa2d7b35028DdD1997E5e`
* `uint64 ttl`: `0`
**Encoded Calldata:**
```
0x5ef2c7f0a097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d3472c29f4186361a46935e4e9c3af71d1cf73cac00186fceb1cd1945ed9ed3dec1000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000c800dbc8ff9796e58efba2d7b35028ddd1997e5e0000000000000000000000000000000000000000000000000000000000000000
```
***
#### Transaction 4: Set Linea reverse namespace
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setSubnodeRecord`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `bytes32 label`: labelhash("8000e708") → 0xf5b2aa07eebc1b04c9923c2e20c5988f7ec95c4150e7fb00a49f74cf73ff795a
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0x0Ce08a41bdb10420FB5Cac7Da8CA508EA313aeF8`
* `uint64 ttl`: `0`
**Encoded Calldata:**
```
0x5ef2c7f0a097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34f5b2aa07eebc1b04c9923c2e20c5988f7ec95c4150e7fb00a49f74cf73ff795a000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b70000000000000000000000000ce08a41bdb10420fb5cac7da8ca508ea313aef80000000000000000000000000000000000000000000000000000000000000000
```
***
#### Transaction 5: Set Optimism reverse namespace
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setSubnodeRecord`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `bytes32 label`: labelhash("8000000a") → 0x77f44888a7cd760c9d34db42bba63325958f70077f99de6be6b318dd388d22c2
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF9Edb1A21867aC11b023CE34Abad916D29aBF107`
* `uint64 ttl`: `0`
**Encoded Calldata:**
```
0x5ef2c7f0a097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d3477f44888a7cd760c9d34db42bba63325958f70077f99de6be6b318dd388d22c2000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f9edb1a21867ac11b023ce34abad916d29abf1070000000000000000000000000000000000000000000000000000000000000000
```
***
#### Transaction 6: Set Scroll reverse namespace
**Target:** registry.ens.eth\
**Address:** `0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e`\
**Function:** `setSubnodeRecord`
**Parameters:**
* `bytes32 node`: namehash("reverse") → 0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34
* `bytes32 label`: labelhash("80082750") → 0xfc94dc633606a32d73e903a0aa85e12fbe1cabc6e53ee69c1893547fda6d9691
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xC4842814cA523E481Ca5aa85F719FEd1E9CaC614`
* `uint64 ttl`: `0`
**Encoded Calldata:**
```
0x5ef2c7f0a097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34fc94dc633606a32d73e903a0aa85e12fbe1cabc6e53ee69c1893547fda6d9691000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000c4842814ca523e481ca5aa85f719fed1e9cac6140000000000000000000000000000000000000000000000000000000000000000
```
***
#### Transaction 7: Authorise new controller on registrar
**Target:** ETH Registrar\
**Address:** `0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85`\
**Function:** `addController`
**Parameters:**
* `address controller`: `0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547`
**Encoded Calldata:**
```
0xa7fc7a0700000000000000000000000059e16fccd424cc24e280be16e11bcd56fb0ce547
```
***
#### Transaction 8: Authorise new controller on reverse registrar
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setController`
**Parameters:**
* `address controller`: `0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547`
* `bool enabled`: `true`
**Encoded Calldata:**
```
0xe0dba60f00000000000000000000000059e16fccd424cc24e280be16e11bcd56fb0ce5470000000000000000000000000000000000000000000000000000000000000001
```
***
#### Transaction 9: Authorise new controller on new default reverse registrar
**Target:** Default Reverse Registrar\
**Address:** `0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9`\
**Function:** `setController`
**Parameters:**
* `address controller`: `0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547`
* `bool enabled`: `true`
**Encoded Calldata:**
```
0xe0dba60f00000000000000000000000059e16fccd424cc24e280be16e11bcd56fb0ce5470000000000000000000000000000000000000000000000000000000000000001
```
***
#### Transaction 10: Set new controller interface to new controller on .eth resolver
**Target:** .eth Resolver\
**Address:** `0x30200E0cb040F38E474E53EF437c95A1bE723b2B`\
**Function:** `setInterface`
**Parameters:**
* `bytes32 node`: namehash("eth") → 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae
* `bytes4 interfaceID`: `0xe4f37f79`
* `address implementer`: `0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547`
**Encoded Calldata:**
```
0xe59d895d93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4aee4f37f790000000000000000000000000000000000000000000000000000000000000000000000000000000059e16fccd424cc24e280be16e11bcd56fb0ce547
```
***
#### Transaction 11: Set default resolver to new public resolver on reverse registrar
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setDefaultResolver`
**Parameters:**
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
**Encoded Calldata:**
```
0xc66485b2000000000000000000000000f29100983e058b709f3d539b0c765937b804ac15
```
***
#### Transaction 12: Set primary name for DNSSEC contract
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setNameForAddr`
**Parameters:**
* `address addr`: `0x0fc3152971714E5ed7723FAFa650F86A4BaF30C5`
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
* `string name`: `dnssec.ens.eth`
**Encoded Calldata:**
```
0x7a806d6b0000000000000000000000000fc3152971714e5ed7723fafa650f86a4baf30c5000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f29100983e058b709f3d539b0c765937b804ac150000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000e646e737365632e656e732e657468000000000000000000000000000000000000
```
***
#### Transaction 13: Set primary name for registrar
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setNameForAddr`
**Parameters:**
* `address addr`: `0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85`
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
* `string name`: `registrar.ens.eth`
**Encoded Calldata:**
```
0x7a806d6b00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f29100983e058b709f3d539b0c765937b804ac15000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000117265676973747261722e656e732e657468000000000000000000000000000000
```
***
#### Transaction 14: Set primary name for root
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setNameForAddr`
**Parameters:**
* `address addr`: `0xaB528d626EC275E3faD363fF1393A41F581c5897`
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
* `string name`: `root.ens.eth`
**Encoded Calldata:**
```
0x7a806d6b000000000000000000000000ab528d626ec275e3fad363ff1393a41f581c5897000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f29100983e058b709f3d539b0c765937b804ac150000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c726f6f742e656e732e6574680000000000000000000000000000000000000000
```
***
#### Transaction 15: Set primary name for new controller
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setNameForAddr`
**Parameters:**
* `address addr`: `0x59E16fcCd424Cc24e280Be16E11Bcd56fb0CE547`
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
* `string name`: `controller.ens.eth`
**Encoded Calldata:**
```
0x7a806d6b00000000000000000000000059e16fccd424cc24e280be16e11bcd56fb0ce547000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f29100983e058b709f3d539b0c765937b804ac1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000012636f6e74726f6c6c65722e656e732e6574680000000000000000000000000000
```
***
#### Transaction 16: Set primary name for default reverse registrar
**Target:** Reverse Registrar\
**Address:** `0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb`\
**Function:** `setNameForAddr`
**Parameters:**
* `address addr`: `0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9`
* `address owner`: `wallet.ensdao.eth` → `0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7`
* `address resolver`: `0xF29100983E058B709F3D539b0c765937B804AC15`
* `string name`: `default.reverse.ens.eth`
**Encoded Calldata:**
```
0x7a806d6b000000000000000000000000283f227c4bd38ece252c4ae7ece650b0e913f1f9000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7000000000000000000000000f29100983e058b709f3d539b0c765937b804ac150000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001764656661756c742e726576657273652e656e732e657468000000000000000000
```
***
## \[EP 6.17] \[Executable] Transfer .locker TLD to Orange Domains LLC
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21077/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/51903780073989583830128732176342966426696684927524697157008519276797273489808), [Tally](https://tally.ensdao.org/dao/proposal/51903780073989583830128732176342966426696684927524697157008519276797273489808) |
### Abstract
Orange Domains LLC is requesting the transfer of ownership of the “locker” Top Level Domain (TLD) in the ENS ecosystem. As the ICANN-accredited registry operator of the .locker TLD and controller of the .locker namespace on the Bitcoin Naming System (BNS), Orange Domains operates a comprehensive Web2-to-Web3 bridge that launched in general availability on October 23rd, 2024.
Our .locker solution enables seamless connection between traditional DNS domain names and Web3 digital identities, with Web2 domains registered through over 50 ICANN-accredited registrars (including GoDaddy and NameCheap) and corresponding Web3 identities minted on Bitcoin’s Stacks L2. Currently supporting Bitcoin, Stacks, Ethereum, and Solana address resolution, we seek ENS integration to provide .locker users with full utility across Ethereum’s vast ecosystem through native ENS resolution and reverse resolution capabilities.
This proposal aligns with ENS’s mission to integrate with existing internet infrastructure while bringing millions of Web2 users into Web3 through trusted, familiar registration channels.
### Proof of Ownership
To demonstrate our legitimate ownership of the .locker TLD and authorization for this transfer request, Orange Domains has set a TXT record on the official .locker DNS infrastructure:
DNS Record: \_ens.nic.locker
Value: dotlocker.eth
Verification Command: dig TXT \_ens.nic.locker
This record confirms our control over the .locker DNS namespace and our intention to delegate ENS management to our designated Ethereum address, following the same verification pattern established in previous TLD transfer proposals.
### Specification
#### Primary Transfer Action
This proposal transfers ownership of the “locker” TLD to Orange Domains LLC by calling setSubnodeOwner on the ENS Root contract at root.ens.eth, passing keccak256(“locker”) as the label parameter and dotlocker.eth as the owner parameter.
#### Technical Implementation Architecture
Multi-Chain Resolution System: Orange Domains will implement a hybrid resolver architecture that coordinates resolution across our existing multi-chain infrastructure (Bitcoin, Stacks, Solana) with new ENS capabilities on Ethereum.
Offchain Resolver with CCIP Read: We will deploy an ENS resolver utilizing EIP-3668 (CCIP Read) to enable gasless resolution while maintaining synchronization with our existing Web2 DNS infrastructure and multi-chain Web3 systems. This approach ensures consistency across all supported blockchain networks.
Gateway Implementation: Our existing resolution infrastructure will be extended with an ENS-compatible gateway that can serve Ethereum addresses, text records, and other ENS-standard data types while coordinating with our Bitcoin/Stacks resolution services.
#### Community and Ecosystem Benefits
Web2 User Onboarding: This integration enables millions of users registering .locker domains through familiar Web2 channels (GoDaddy, NameCheap, etc.) to automatically gain ENS functionality, significantly expanding ENS adoption beyond crypto-native users.
Cross-Chain Utility: .locker domains will serve as universal identifiers resolving consistently across Bitcoin, Stacks, Ethereum, and Solana, providing users with unified identity across major blockchain ecosystems.
Infrastructure Alignment: Following ENS’s stated goal that “for ENS to succeed, it must integrate with existing infrastructure,” this proposal bridges traditional DNS registration with ENS functionality through established ICANN processes.
Registrar Network Expansion: Leveraging our relationships with 50+ ICANN-accredited registrars creates new distribution channels for ENS-compatible domains through traditional domain registration workflows.
#### Migration and User Experience
Seamless Integration: Existing .locker domain holders will automatically gain ENS resolution capabilities without requiring additional registration or migration steps.
Backward Compatibility: All existing .locker functionality (Bitcoin, Stacks, Solana resolution) will be preserved and enhanced with new Ethereum capabilities.
Subdomain Management: Orange Domains will implement subdomain registration and management that maintains consistency across all supported blockchain networks while providing gasless updates through our offchain infrastructure.
### Governance Alignment
This proposal directly supports ENS’s constitutional principles by:
* Expanding Access: Bringing Web2 users into Web3 through trusted, familiar registration channels
* Infrastructure Integration: Building bridges between traditional internet infrastructure and decentralized naming
* Utility Enhancement: Providing cross-chain resolution that increases the practical value of decentralized naming
* Responsible Stewardship: Leveraging established ICANN accreditation and regulatory compliance to ensure professional namespace management
### Transaction Details
This proposal transfers the ownership of the “locker” TLD to Orange Domains by calling `setSubnodeOwner` on root.ens.eth (0xaB528d626EC275E3faD363fF1393A41F581c5897) with `keccak256("locker")` as the label, and `dotlocker.eth` as the owner.
### Conclusion
Orange Domains’ management of the .locker TLD in ENS represents a significant opportunity to bridge Web2 and Web3 naming infrastructure while maintaining the highest standards of professional registry operation. Our ICANN accreditation, existing multi-chain infrastructure, and extensive registrar partnerships position us to bring unprecedented scale to ENS adoption through traditional domain registration channels.
We respectfully request the ENS community’s support for this proposal, which will enhance utility for millions of potential users while advancing ENS’s mission of universal, decentralized naming.
## \[EP 6.18] \[Executable] Reactivate SPP2 streams
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21290/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/8152144177729545927999296682104713773450687318641051882785083122565237294645), [Tally](https://tally.ensdao.org/dao/proposal/8152144177729545927999296682104713773450687318641051882785083122565237294645) |
### Abstract
This proposal reactivates the Service Provider Program Season 2 (SPP2) streams that were interrupted due to a failure in Superfluid’s autowrap system. The issue has been resolved, and Superfluid has committed to covering any liquidation fees incurred by providers during the interruption. This proposal resumes the original payment streams approved in EP 6.3 and EP 6.10, including retroactive funding for the downtime.
### Motivation
Following the Superfluid autowrap failure ([post-mortem report](https://superfluidorg.notion.site/AutoWrap-System-Failure-August-2025-24f4b6e22ae98044bad6e55f7f200e0f)), the Timelock's USDCx balance ran out, interrupting the stream from the Timelock to the [Stream Management Pod](https://etherscan.io/address/0xB162Bf7A7fD64eF32b787719335d06B2780e31D1), which also ran out of USDCx, interrupting the streams to SPs. To maintain the continuity of ENS DAO’s commitments, this proposal restarts the streams and provides retroactive funding to cover the gap period, plus an additional week of pre-funding. The auto-wrapper will be able to add USDCx and ensure smooth operations going forward.
### Specification
This executable proposal will:
1. **Approve 500,000 USDC to the USDCx contract** to allow conversion for streaming.
2. **Wrap 500,000 USDC into USDCx** to provide sufficient liquidity for operations.
3. **Transfer 400,000 USDCx to the Stream Management Pod** as retroactive payment for the interrupted period. This transfer is done in USDCx rather than USDC to maintain complete visibility and tracking of all SPP program spending within the Superfluid dashboard, ensuring transparent monitoring of stream-related transactions.
4. **Recreate the stream** from ENS Treasury to the Stream Management Pod at the previously approved rate of **0.142599440769357573 USDCx/sec** (\~$4.5M/year), leaving approximately 100,000 USDCx in the Treasury for ongoing stream operations.
5. Transfer 0 ETH to the timelock - This is due a bug on Tally draft feature and has no impact.
## \[EP 6.19] \[Executable] Adopt The SEAL Safe Harbor Agreement
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21226/) |
| **Authors** | [@samczsun](https://discuss.ens.domains/u/samczsun) (SEAL), [@dickson](https://discuss.ens.domains/u/dickson) (SEAL), [@Alexu](https://discuss.ens.domains/u/alexu) (ENS) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/48262157524430528705514027771464261215955420389394621161356313649894506972547), [Tally](https://tally.ensdao.org/dao/proposal/48262157524430528705514027771464261215955420389394621161356313649894506972547) |
### Introduction
This proposal outlines ENS’s adoption of the SEAL ([Security Alliance](https://www.securityalliance.org/)) Whitehat Safe Harbor Agreement (“Safe Harbor Agreement”). By adopting the Safe Harbor Agreement, ENS improves the security of its on-chain assets by allowing whitehats to intervene during active exploits to save protocol funds.
#### What is the Safe Harbor Agreement?
The Safe Harbor Agreement addresses a critical need in crypto: enabling whitehats to intervene during active exploits when the urgency of an attack makes traditional processes too slow to save funds.
The Safe Harbor Agreement was created by SEAL, a nonprofit founded by samczsun, to secure the future of crypto. In addition to the Safe Harbor Agreement, SEAL runs multiple initiatives including SEAL 911 (emergency response hotline for exploits), SEAL Intel (crypto-native threat intelligence sharing), SEAL Frameworks (open source security best practices and playbooks), SEAL Wargames (incident response training), and more in development.
Key aspects of the agreement include:
* **Encouraging Whitehats to Protect the Protocol:** By adopting the Safe Harbor Agreement, ENS incentivizes whitehats to step in and protect the protocol during active exploits by limiting their legal exposure.
* **Intervention Only During Active Exploits:** Whitehats are authorized to act only when there is an immediate or ongoing exploit that threatens the protocol. This agreement is not intended for routine security testing or bug bounty reporting. It applies only to critical situations where the urgency of the exploit supersedes traditional procedures for responsible disclosure in order to save funds.
* **Mandatory Return of Rescued Funds:** Under the terms of the Safe Harbor, whitehats are required to return all rescued assets to a pre-designated recovery address controlled by the protocol within 72 hours of recovery to ensure these funds are quickly secured, preventing delay or potential loss.
* **Clear Guidelines and Legal Protection:** The agreement establishes strict rules for how whitehats must operate during an exploit, ensuring recovery efforts are conducted professionally and safely, minimizing the risk of mistakes or further damage to the protocol. By adhering to these guidelines, whitehats can limit their potential legal exposure, allowing them to act in good faith without fear of liability.
* **Incentivized Rescue Efforts:** To motivate whitehats to act during critical situations, the agreement offers a bounty system that rewards rescuers with a percentage of the recovered assets, up to a predefined cap, for successful interventions.
Safe Harbor has already been adopted by leading protocols such as Uniswap, Zksync, Pendle, Pancakeswap, and Balancer, establishing it as a trusted industry standard for empowering whitehats during active exploits.
### Rationale
ENS is committed to enhancing its security and protecting user funds during critical moments. While security audits and other preventive measures are crucial, the unpredictable nature of active exploits requires a swift, decisive response mechanism to minimize potential damage.
Benefits of adopting the Safe Harbor Agreement include:
* **Agile Defense Against Exploits:** Whitehats are authorized to intervene as soon as an active exploit is detected, enabling them to respond faster than traditional methods. Immediate action minimizes the window for malicious actors, reduces damages, and accelerates the recovery of assets during critical moments.
* **Clarified Rescue Process:** The agreement ensures that every step, from intervention to fund recovery, is predetermined and streamlined. Whitehats know exactly where to send recovered funds, preventing chaotic negotiations or rushed decisions during an exploit. This clarity ensures efficient, decisive action when it matters most.
* **Clear Financial Boundaries:** The predefined bounty system, with a cap matching ENS’s existing bug bounty, ensures that whitehats are incentivized fairly without creating conflicting priorities between exploit intervention and standard vulnerability disclosure. By setting expectations upfront, it eliminates post-exploit negotiations, ensuring funds are returned promptly without attempts to change the reward amount, keeping the process fair and transparent.
* **Aligning with Industry Best Practices:** By adopting the Safe Harbor Agreement, ENS aligns itself with leading security practices across the industry, reinforcing its commitment to staying at the forefront of protocol security.
Adoption of the agreement complements audits by providing an additional layer of security, ensuring that the protocol is better prepared to respond to active threats.
### Adoption Details
#### Bounty Terms
*Predetermined rewards for successful whitehats that recover protocol funds. For more information review the* [*Safe Harbor Scope*](https://frameworks.securityalliance.org/safe-harbor/scope-terms.html) *document.*
* **Percentage:** 10%
* **Cap (USD):** $250,000
* **Aggregate Cap (USD):** $250,000
* **Retainable:** False
* This means that whitehats cannot retain their bounty directly from the recovered assets. Instead, all rescued funds must be returned to the protocol’s designated asset recovery address, and the bounty will be paid out separately after verification.
* **Identity:** Named
* Whitehats must provide their full legal name. This requirement ensures compliance with legal obligations and is similar to the identity verification standards seen in traditional bug bounty programs.
* **Diligence Requirements:** KYC and OFAC Screening
* ENS requires all eligible whitehats to undergo Know Your Customer (KYC) verification and be screened against the Office of Foreign Assets Control (OFAC) sanctions lists. This process ensures that all bounty recipients are compliant with legal and regulatory standards before qualifying for payment.
#### Contact Details
*Designated security contacts for the protocol who whitehats will contact following a safe harbor recovery*
| Name | Contact |
| ----------------- | -------------------------------------------- |
| Alexander Urbelis | [alex@ens.domains](mailto\:alex@ens.domains) |
#### Chains & Asset Recovery Addresses
*Addresses controlled by the protocol which recovered protocol funds will be returned to by the whitehat*
| Chain | Asset Recovery Address |
| ------------- | ------------------------------------------ |
| ETH - Mainnet | 0x91c32893216dE3eA0a55ABb9851f581d4503d39b |
#### Accounts
*List of all on-chain assets owned by the protocol protected under Safe Harbor*
| Chain | Name | Address | Child Contract Scope |
| ----------- | -------------------------------------------- | ------------------------------------------ | -------------------- |
| ETH Mainnet | ENS DAO Wallet | 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7 | All |
| ETH Mainnet | ENS Gnosis Safe | 0xCF60916b6CB4753f58533808fA610FcbD4098Ec0 | All |
| ETH Mainnet | ENS Multisig | 0x911143d946bA5d467BfC476491fdb235fEf4D667 | All |
| ETH Mainnet | ENS EnDAOment | 0x4F2083f5fBede34C2714aFfb3105539775f7FE64 | All |
| ETH Mainnet | ENS Token | 0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72 | All |
| ETH Mainnet | ENS DAO Multisig, Eco Main | 0x2686A8919Df194aA7673244549E68D42C1685d03 | All |
| ETH Mainnet | ENS DAO Multisig, Eco IRL | 0x536013c57DAF01D78e8a70cAd1B1abAda9411819 | All |
| ETH Mainnet | ENS DAO Multisig, Hackathons | 0x9B9c249Be04dd433c7e8FbBF5E61E6741b89966D | All |
| ETH Mainnet | ENS DAO Multisig,Newsletters | 0x13aEe52C1C688d3554a15556c5353cb0c3696ea2 | All |
| ETH Mainnet | ENS DAO Multisig,Metagov Main | 0x91c32893216dE3eA0a55ABb9851f581d4503d39b | All |
| ETH Mainnet | ENS DAO Multisig, Metgov Stream | 0xB162Bf7A7fD64eF32b787719335d06B2780e31D1 | All |
| ETH Mainnet | ENS DAO Multisig,Public Goods Main | 0xcD42b4c4D102cc22864e3A1341Bb0529c17fD87d | All |
| ETH Mainet | ENS DAO Multisig, Public Goods, Large Grants | 0xebA76C907F02BA13064EDAD7876Fe51D9d856F62 | All |
| ETH Mainnet | ETHRegistrarController 1 | 0xF0AD5cAd05e10572EfcEB849f6Ff0c68f9700455 | All |
| ETH Mainnet | ETHRegistrarController 2 | 0xB22c1C159d12461EA124b0deb4b5b93020E6Ad16 | All |
| ETH Mainnet | ETHRegistrarController 3 | 0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5 | All |
| ETH Mainnet | ETHRegistrarController 4 | 0x253553366Da8546fC250F225fe3d25d0C782303b | All |
* *“All”: The Safe Harbor Agreement will cover the contract, along with all current and future subcontracts deployed by that address.*
* *Note: All Ethereum Name Service Domains (i.e., .eth domains) are under scope to be rescued and returned to the Asset Recovery Address. Their value will be based on: Each rescued .eth name is valued as* `alpha * base_rate(length) * min(remaining_years, year_cap)` *USD, where* `base_rate(length)` *is ENS’s base rate by length (3-char=$640/yr, 4-char=$160/yr, 5+=$5/yr),* `remaining_years` *is the paid registration time left at the rescue timestamp,* `alpha` *is the haircut factor and is set at 0.50, and* `year_cap`*=5 yrs. Names with* `remaining_years`*=0 (*`expired`*/*`grace`*/*`premium`*) are valued at $0. Wrapped names follow the valuation of their underlying .eth.*
### Implementation Plan
1. **Register Agreement On-Chain**:
* The agreement will be registered on Ethereum in the Safe Harbor Registry at address `0x1eaCD100B0546E433fbf4d773109cAD482c34686`, including all adoptionDetails. This ensures transparency and immutability.
2. **Communicate Adoption**:
* An official announcement will be made across all ENS communication channels, explaining the adoption and its significance to the community.
3. **Future Updates to Scope:**
* New versions of ENS will be reviewed and added to the Safe Harbor Agreement scope via ENS Governance vote, ensuring continued protection for all new contracts and functionalities.
### Transaction Information
Target: Safe Harbor Registry V2
Address: `0x1eacd100b0546e433fbf4d773109cad482c34686`
Function: adoptSafeHarbor
Parameter:
address agreementAddress: `0x3303a9a3eb71836c0e88e8ab4eaf0d478e29e04c`
Encoded Calldata: `0x344fbd200000000000000000000000003303a9a3eb71836c0e88e8ab4eaf0d478e29e04c`
### Conclusion
Adopting the SEAL Whitehat Safe Harbor Agreement equips ENS with a rapid response mechanism for active exploits, enabling whitehats to step in effectively when needed most. The agreement provides clear guidelines for action, increasing the protection of user funds and demonstrating ENS's commitment to proactive security.
**Note**: This proposal does **not** request any funds from the DAO treasury and does **not** involve any budget allocation. It solely seeks governance approval for ENS to adopt the SEAL Whitehat Safe Harbor Agreement.
### References
* **SEAL Whitehat Safe Harbor Agreement Documentation:** [Framework](https://frameworks.securityalliance.org/safe-harbor/index.html)
* **SEAL Whitehat Safe Harbor Agreement Legal Agreement:** [Link](https://github.com/security-alliance/safe-harbor/blob/main/documents/agreement.pdf)
* **ENS Bug Bounty**: [Bug Bounty](https://immunefi.com/bug-bounty/ens/information/)
## \[EP 6.2] \[Executable] Endowment expansion (3rd tranche)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-endowment-expansion-3rd-tranche/19851) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/31309365093913580207991288430108338667724061355449265288906484597789511363394) |
### Summary
This proposal aims to expand the Endowment by funding a third tranche, comprising 5,000 ETH, from the ENS DAO to the ENS Endowment.
Alongside the third tranche transfer, an update to the Allowance Module on the ENS Endowment is proposed; *resetTime* for ETH allowance (for fee payment) is to be changed from the current parameter of 43,200 seconds (30 days) to 36,000 seconds (25 days). The motivation for this is that there has been an accumulation of payment delays, such that current fee payments are delayed.
### Motivation
Since the establishment of the Endowment on March 7th, 2023, ENS has been setting the gold standard for DAO treasury management:
* **Asset allocation:** ENS has the 6th-largest stablecoin holding and 5th-largest majors (BTC, ETH) holdings of any Protocols ([source](https://defillama.com/treasuries)).
* **Income generation:** Since its inception, the Endowment has generated $2.92M in DeFi results (net of fees) for ENS. In 2024, DeFi results represented 12% of total revenue for ENS according to [ENS Revenue Report: Q3 2024](https://discuss.ens.domains/t/ens-revenue-report-q3-2024/19718). This is on track towards the core goal of self-sufficiency.
* **Asset location:** As of October 31, 2024, 71% of the funds were held in the Endowment, while the remaining 25% were held idle across DAO wallet and Registrar Controllers ([source](https://dune.com/karpatkey/ens-dao-fundflow)).
The original Request for Proposal in [\[EP2.2.4\]](https://docs.ens.domains/dao/proposals/2.2.4) sets out that the Endowment should be established gradually over time, in response to changing conditions and needs, and to achieve the eventual goal of self-sufficiency. To deliver on this vision for self-sufficiency, a further increase in the Endowment’s returns is needed. As the Endowment is fully utilised within the bounds of the existing mandate, it is clear that those additional returns must come from additional funds.. We think **now** is the right time to implement these increases, given the following developments:
* **Proven track record**: the Endowment has been operating for 1 year and 7 months, with *no funds lost.* During that time, the ENS community has gained familiarity with the Endowment in terms of both operations and infrastructure.
* **Investment Policy Statement as guardrails**: the [newly-adopted IPS](https://snapshot.org/#/ens.eth/proposal/0x085a1e40c264ffd44567b6dce889f5943e72cfa8442eaeb81819261a38f0bd0a) provides an additional layer of checks and balances, so that the DAO and its Metagov Working Group can hold the Endowment Manager accountable.
* **Vulnerability fix by @Blockful**: risk of governance takeover by “risk-free value raiders”, who could have taken over the control of the DAO and the Endowment, has been mitigated. The vulnerability has been fixed by the introduction of the [Security Council](https://www.tally.xyz/gov/ens/proposal/42329103797433777309488042029679811802172320979541414683300183273376839219133) and veto.ensdao.eth.
The proposed third tranche would be sized at 5,000 ETH, representing 42.4% of assets held in the Controller and the DAO Wallets (*per* the pie chart above) It would raise the capital utilisation rate by 10.5 percentage points from the current 70.8% to 81.3%.
### Endowment Updates
#### Updates
Karpatkey’s updates for the Endowment can be seen here: [2023 Review](https://discuss.ens.domains/t/karpatkey-2023-review-for-the-ens-endowment/18656), [1H 2024 Review](https://discuss.ens.domains/t/karpatkey-h1-2024-review-for-the-ens-endowment/19394).
Monthly reports on the Endowment can be found on karpatkey’s website ([here](https://reports.karpatkey.com/ens?month=9\&year=2024\¤cy=USD)).
#### What’s been done
* **Investment Policy Statement**: karpatkey has created and [formally introduced](https://snapshot.org/#/ens.eth/proposal/0x085a1e40c264ffd44567b6dce889f5943e72cfa8442eaeb81819261a38f0bd0a) an [Investment Policy Statement](https://drive.google.com/file/d/1zsV0k3J7s2QAJUoWxPnBpF6XAGW1HuD6/view) which defines the key roles, responsibilities and limitations of the Endowment and its Manager.
* **Risk Management Development**: karpatkey has designed and implemented a robust risk management stack, leveraging on dedicated risk data service providers, including [Hypernative](https://www.hypernative.io/) and [Redefine](https://redefine.net/). Through weekly meetings with Hypernative, karpatkey is continuously fine-tuning risk alerts and management, especially to cover protocol risks. Automatic, real-time risk alerts help mitigate potential risks. Detailed plans for the Endowment’s emergency protocol and war room are in place to assess and react to urgent situations.
* **Infrastructure Development**: karpatkey has worked very closely with Gnosis Guild to develop [and implement](https://discuss.ens.domains/t/ep-5-12-roles-modifier-v2-migration-updates-to-endowment-permissions/19173), Zodiac Roles Modifier v2. As a design partner, karpatkey provided feedback allowing Zodiac Roles Modifier to become more user-friendly and flexible. One notable improvement is permissions updates user interface, enhancing transparency and simplifying audits for the ENS community. A code review was also conducted for permissions update.
* **Permissions Updates**: the Endowment has been undergoing continuous permissions updates, allowing it to stay up-to-date with changing market landscape and protocols (\[[EP 4.1](https://discuss.ens.domains/t/ep-4-1-executable-approve-further-actions-and-strategies-for-the-endowment/17406)], \[[EP 4.2](https://discuss.ens.domains/t/4-2-executable-fund-the-endowment-second-tranche/17743)], \[[EP 4.5](https://discuss.ens.domains/t/ep-4-5-executable-endowment-permissions-to-karpatkey-update-3/18036)], \[[EP 5.12](https://discuss.ens.domains/t/ep-5-12-roles-modifier-v2-migration-updates-to-endowment-permissions/19173)], \[[EP 5.14](https://discuss.ens.domains/t/ep-5-14-executable-endowment-permissions-to-karpatkey-update-4/19503)]). Independent, thirdparty security review of our Permissions Updates has also been conducted by [Third Guard](https://thirdguard.com/), with the cost covered by karpatkey.
* **Dune Dashboards Development:** a variety of different Dune dashboards have been created to give public visibility over the DAO and the Endowment, and their respective operations. These include: the [DAO governance dashboard](https://dune.com/karpatkey/ens-dao-governance) (by karpatkey), the [fund flow dashboard](https://dune.com/karpatkey/ens-dao-fundflow) (by karpatkey) and the [financial reporting dashboard](https://dune.com/steakhouse/ens-steakhouse) (by Steakhouse)
* **Reporting:** weekly Endowment updates and monthly financial updates are provided during the DAO’s Metagov meetings. Monthly Endowment updates are also available on the karpatkey [website](https://reports.karpatkey.com/ens?month=9\&year=2024\¤cy=USD). Biannual Endowment updates are provided on ENS forum.
* **Partnerships:** karpatkey has negotiated and put in place a protocol fees rebate agreement with Stader Labs.
#### Future plans
* **Risk Management**: to further protect the Endowment against potential hacks and exploits in protocols that the Endowment deploys funds in, karpatkey has been developing Guardians and ‘Agile Execution App’, which automatically detect potential exploit events and exit at-risk positions.
* **Permissions Updates**: The Endowment will undergo continuous permissions updates. Immediate priorities include introducing other stablecoins and RWAs, onboarding new liquid staking protocols and keeping the permissions updated with protocol/contract upgrades.
* **Partnerships**: reinforce yields without taking additional risk by formulating partnership deals leveraging karpatkey’s DeFi network.
* **Analysis on Governance Attack:** karpatkey, together with the ENS community, will conduct further research into potential governance attack vectors that could put the Endowment at risk, and present potential solutions to the DAO.
### Specification
1. Fund Transfer\
Executed by the ENS DAO Multisig (payload available [here](https://gist.github.com/JeronimoHoulin/8195478708e88830de9aabfb67bc8710)).
Transfer 5,000 ETH to the Endowment (0x4F2083f5fBede34C2714aFfb3105539775f7FE64)
Value: 5000000000000000000000
2. Update the [Allowance Module](https://etherscan.io/address/0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134)
Executed by the ENS Endowment.\
Currently, the parameters of Allowance Module are as follows: allowance = 30 ETH, resetTimeMin = 43200 seconds (30 days). Due to payment delays in the past, we would like to propose a change in [resetTimeMin](https://etherscan.io/address/0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134#writeContract#F6) parameter, i.e. Change the [resetTimeMin](https://etherscan.io/address/0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134#writeContract#F6) for [main.mg.wg.ens.eth](https://etherscan.io/address/0x91c32893216dE3eA0a55ABb9851f581d4503d39b) in the Allowance Module from 30 days to 25 days (i.e. 43200 minutes to 36000).
```
"delegate": "0x91c32893216dE3eA0a55ABb9851f581d4503d39b",
"token": "0x0000000000000000000000000000000000000000",
"allowanceAmount": "30000000000000000000",
"resetTimeMin": "43200" → "36000",
"resetBaseMin": "28825613"
```
Payload available [here](https://gist.github.com/JeronimoHoulin/3e10411ac6d40b6e4087fc59df2719d5).
(Can be downloaded, unzipped, and dropped into [Safe’s transaction builder](https://app.safe.global/apps/open?safe=eth:0x4F2083f5fBede34C2714aFfb3105539775f7FE64\&appUrl=https%3A%2F%2Fapps-portal.safe.global%2Ftx-builder)).
Tenderly simulation available [here](https://dashboard.tenderly.co/public/safe/safe-apps/simulator/02add7c9-0ffc-49dc-b372-30fce90ccf9d).
## \[EP 6.20] \[Executable] Reimbursement for eth.limo’s Legal Fees
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21468) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/28621945985399756809323229823216459792275185227390789031203077499124321674250), [Tally](https://tally.ensdao.org/dao/proposal/28621945985399756809323229823216459792275185227390789031203077499124321674250) |
[Temp Check Discourse link](https://discuss.ens.domains/t/temp-check-reimbursement-for-eth-limo-s-legal-fees/21435)
#### Summary
This proposal aims to reimburse eth.limo for ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
#### Background
eth.limo provides critical public goods infrastructure for ENS, powering countless dApps and dWebsites. The eth.limo team is on call 24/7/365 to ensure uptime and availability as well as providing technical support for builders and projects. Operating such infrastructure involves not only technical upkeep but also significant human and legal costs.
Recent legal requests and compliance requirements in the U.S. have resulted in substantial and unpredictable legal fees for our small team. For a more detailed background and context, please refer to our recent post:
[Eth.limo - Legal Update & Full Summary](https://discuss.ens.domains/t/eth-limo-legal-update-full-summary/21377)
### Links
[Temperature Check](https://discuss.ens.domains/t/temp-check-reimbursement-for-eth-limo-s-legal-fees/21435)
#### Specification
This executable proposal will initiate a transfer of 109,818.82 USDC from the ENS DAO treasury to ethdotlimo.eth. This amount represents the ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
#### Transaction Details
* **From**: ENS DAO Treasury (0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7)
* **To**: USDC Token Contract (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
* **Recipient**: ethdotlimo.eth (0xB352bB4E2A4f27683435f153A259f1B207218b1b)
* **Amount**: 109,818.82 USDC (109818820000 considering USDC’s 6 decimal places)
* **Purpose**: The reimbursement of eth.limo for ongoing legal fees related to the operation of the eth.limo/eth.link gateway services.
This transaction calls the `transfer` function of the USDC contract, transferring 109,818.82 USDC to eth.limo's address.
### Calldata
```
{
"target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"value": 0,
"calldata": "0xa9059cbb000000000000000000000000b352bb4e2a4f27683435f153a259f1b207218b1b0000000000000000000000000000000000000000000000000000001991b635a0"
}
```
#### Rationale
By approving this reimbursement, ENS DAO affirms the importance of supporting eth.limo’s legal expenses so the service can continue operating a free, public ENS gateway for Ethereum-native dApps and content.
## \[EP 6.21] \[Executable] Set Primary Names for Core DAO Addresses
::authors
| **Status** | Passed |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21432/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/108835189906614532703236602621229289879643217303874617456878894788222576090451), [Tally](https://tally.ensdao.org/dao/proposal/108835189906614532703236602621229289879643217303874617456878894788222576090451) |
### Abstract
Several ENS DAO contracts lack primary names. This proposal establishes reverse records for core DAO addresses.
### Motivation
By setting reverse records for core DAO addresses:
* ENS DAO demonstrates best practices by using its own protocol fully, serving as an example for other DAOs
* ENS DAO contracts become easier to identify and navigate
* Names will resolve on sites that list the contracts like [enswallets.xyz](https://www.enswallets.xyz/)
### Details
Executing this proposal will set primary names for
1. The [ENS DAO wallet](https://etherscan.io/address/0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7)
2. The [ENS token](https://etherscan.io/address/0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72)
3. The [ENS Endowment wallet](https://etherscan.io/address/0x4F2083f5fBede34C2714aFfb3105539775f7FE64)
### Specification
Call `setName("wallet.ensdao.eth")` on the Reverse Registrar (reverse.ens.eth) to set the reverse record of 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7.
Call `setNameForAddr(0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72, 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7, 0xF29100983E058B709F3D539b0c765937B804AC15, "token.ensdao.eth")` on the Reverse Registrar to set the reverse record of 0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72.
Call `execTransaction()` on the Endowment multisig (endowment.ensdao.eth) with the encoded calldata for `setName("endowment.ensdao.eth")` to set the reverse record of 0x4F2083f5fBede34C2714aFfb3105539775f7FE64. The Safe transaction looks like this:
```
To: 0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb
Value: 0
Data: 0xc47f002700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000014656e646f776d656e742e656e7364616f2e657468000000000000000000000000
Operation: 0
SafeTxGas: 0
BaseGas: 0
GasPrice: 0
GasToken: 0x0000000000000000000000000000000000000000
RefundReceiver: 0x0000000000000000000000000000000000000000
Signatures: 0x000000000000000000000000Fe89cc7aBB2C4183683ab71653C4cdc9B02D44b7000000000000000000000000000000000000000000000000000000000000000001
```
## \[EP 6.22] \[Executable] ENS Contract Naming Season
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21402/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/89533866253315759669817396047764505253840458037760720608881002428435364696940), [Tally](https://tally.ensdao.org/dao/proposal/89533866253315759669817396047764505253840458037760720608881002428435364696940) |
*After positive discussion, feedback and support on the forum, we now move this proposal to a vote.*
**Execution:**
* **Send 75,000 USDC to Contract Naming Pod Multisig**
* **Send 10,000 ENS to Contract Naming Pod Multisig**
### Outline
**This proposal aims to launch ENS Contract Naming Season: a time-boxed program focused on the creation and empowerment of an ENS protocol integration leaderboard with the goal of driving adoption of ENS at a smart contract, protocol and DAO level.**
This proposal also outlines a **‘Temporary Contract Naming Pod’** with the explicit mandate to drive the communication, adoption and onboarding of different protocols and projects to the program over the next \~6 months. This pod will be primarily led by ENScribe with support from FireEyes and any other humans interested.
A budget for this temporary pod is also proposed, to be used for **two purposes;** USDC to be used by the pod to pay contributors (primarily Enscribe and any other organisation/human that facilitate the process (outreach and coordination with protocols for example). As well as ENS tokens to be used as incentive for existing and new projects to climb the leaderboard, and achieving proposal goals:
* Develop different engagement strategies for ENS contract naming and ENS leaderboard engagement.
* Creating a social drive for ENS contract naming and the leaderboard.
* Direct outreach and onboarding to given protocols and DAOs to encourage their participation in ENS contract naming season.
* Experiment with funding retroactive adoption of ENS names for prominent and high impact smart contracts across Ethereum.
* Develop a clear strategy and execution plan that drives more contracts to adopt ENS naming principles, as well as text records pertaining to the given project.
* Establish an approach to $ENS-based incentives that could be redeployed for future initiatives to drive ENS adoption in other areas (beyond contract naming).
We’re directly targeting approximately 30 large projects spanning L2 networks, DeFi protocols, Public Goods funding, staking and infra for naming incentives. We also expect smaller projects to embrace contract naming and propose themselves for rewards.
This proposal builds on the[ ENS: Propagating Use Cases, Registrations and Exposure](https://discuss.ens.domains/t/ens-propagating-use-cases-registrations-and-exposure/21170) concept and discussion, as well as meetings between Fire Eyes, Enscribe team, and other ENS contributors in an [open telegram group](https://t.me/+LdcTc3AxpPI4N2I5).
### Motivation
Clear, human-readable contract names improve user safety and UX, as well as being beneficial to wider ENS adoption. **Widespread contract naming further establishes ENS as the identity layer for Ethereum users and contracts: wallets and explorers can show clear provenance, users avoid scam addresses, and DAOs standardize their onchain presence.** The forum discussion, WG calls and wider discussion have identified this as “low-hanging fruit with outsized impact,” and suitable for a focused pilot funded by ENS DAO.
**Targets for this program and an ENS integration leaderboard are:**
* User-facing contracts in widely used Dapps including:
* DeFi (DEX pools, lending markets, bridges)
* Consumer (social, gaming, community, payments)
* Core protocol contracts (L2, DeFi protocols, DEX pools, lending markets, bridges, etc)
* DAO governance inc. multisigs, executors, treasuries
* ENS enablers: wallets, deployment platforms, infra that builds in contract naming
**By creating a leaderboard of projects that have successfully integrated ENS into their contract; naming will be shown on a number of different ‘tabs’ of the leaderboard.**
1. Apps that have named a number of the contracts that end users interface with.
2. DAOs that have named a number of their treasury, working groups, fund distribution and DAO contracts.
3. Protocol contracts that have been named to demonstrate versioning and show relationships between contracts.
4. Wallets and infra that have made ENS integrations easy and accessible, CC the existing work by [Namehash Labs](https://namehashlabs.org/ "Namehash Labs") and other community members on [ENSawards](https://ensawards.org/benchmarks).
### Budget & Timeline
* **Budget:**
* Initially a budget of **$75k USDC** to cover operational and contributor expenses.
* Up to **10,000 ENS** tokens to cover smart contract naming incentives
* **Timeline:**
* **Up to 6 months**, after which the program will be assessed, and either unused tokens sent back to the DAO, or rolled into a future program if the DAO sees the program and its subsequent reporting successful.
### Governance & Pod
* **Custody of Funds:** All funds held by Contract Naming Pod Multisig, with monthly distributions to contributors
* 100% of operating and incentive funds will be distributed to the pod multisig initially, with these funds then being distributed to contributors on a monthly basis, with oversight from the MetaGov working group.
* **Contract Naming Incentives Pod Responsibilities:**
* Maintain a public shortlist spreadsheet of target contracts and infrastructure providers.
* Approve awards via a simple majority, publish rationale and scores.
* Create a consistent rubric for incentive allocation for contracts
* Conflict of Interest - members recuse where applicable.
* Establish ENS best practices and guidelines for naming aimed at target project categories (Dapps, DAOs, protocols)
* **Pod Multisig Address:**
* contractnamingpod.eth
* 0x8Bf6F9F91D70a9a3c2FCe45dF30EcE735C54D624
* **Pod Multisig Members:**
* james.eth
* guildnavigator.eth
* ens.gregskril.eth
* nischal.eth
* estmcmxci.eth
* lightwalker.eth
### Success Metrics
* Number of contracts named during program
* Campaign engagement and support from leading L2 network, top tier protocols/Dapps and key voices in the Ethereum ecosystem
* Contract naming coverage across top protocols/DAOs by TVL/volume
* Wallet/explorer coverage for named contracts
* Standards adoption: # of repo templates, plugin downloads, PRs merged
* Cost-effectiveness: $ENS per impactful contract
### Timeline
* Proposal: Taking this proposal through forum and working group discussions ✅
* Vote: Proposal presented as an onchain proposal to the DAO to be voted on ✅
* Kick off: Empower Enscribe and a temporary pod to publish target shortlist, begin outreach, open submissions, etc. As well as creating content (tweets/articles) about this season!
* Monthly: Review submissions, distribute grants, update dashboard / spreadsheet
* Month 6: Final review with KPIs and recommendation back to the wider DAO.
### Caveats
During and post program we expect to see a measurable and meaningful increase in both contract naming with ENS and awareness of the importance of this for improving Ethereum UX and security.
However, given the wide range of targets, the speed with which they can comply with best practices and recommendations will vary. Where there are projects with large treasuries/TVL and significant user bases, it may not be possible to comply fully with recommendations in the given timelines, especially if they come onboard later in the season.
Hence vocal commitment or intent to to embrace this initiative could be considered a success for some projects should integration/naming work not be completed within the bounds of the initial season. ENS token incentives could prove to be valuable in getting some of these key projects over the line.
Additionally, there are limitations with respect to the pool of smart contracts which can have primary names set. There have been discussions on [potential ways forward](https://discuss.ens.domains/t/approaches-to-support-setting-primary-names-for-all-contracts/20919), however it is anticipated that through this initiative a better understanding of approaches to increase the potential coverage could be established.
To keep messaging simple, whilst primary naming is preferred, where not possible, a forward resolving name should be considered a win.
## \[EP 6.23] \[Executable] Endowment permissions to karpatkey - Update #6
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21396/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/12950686153984121876325788121804936905339482144562527684056466889156345680789), [Tally](https://tally.ensdao.org/dao/proposal/12950686153984121876325788121804936905339482144562527684056466889156345680789) |
## Abstract
This proposal introduces updated permissions for the Endowment, with a continued focus on diversification and alignment with the evolving market landscape and liquidity.
## Motivation
The proposed new permissions focus on strategies involving:
* Airdrop claim: Claim the SPK airdrop and add permissions to swap the SPK token
* Additional permissions on already permitted platforms for generating yield on Endowment assets, including:
* Balancer v3 pools: since the protocol upgrade in December 2024, liquidity and incentives have been migrating from v2 to v3 pools
* Curve ETH stable-pair pools
* New platform for generating yield on permitted assets: Morpho
* Morpho has now established itself as one of the leading lending platforms in DeFi and presents various attractive yield opportunities that can complement and diversify the current strategies for both ETH and stablecoins. With its minimal and immutable code, market isolation with singular collateral/loan pairs, and strong institutional backing, Morpho is one of the safest and most robust lending platforms.
* CowSwap TWAP functionality:
* kpk worked with the Gnosis Guild team to enable support for TWAP functionality in the Zodiac Roles module, which will unlock additional value when transacting with Endowment funds. TWAP orders allow large orders to be broken down into smaller chunks, reducing market impact and ensuring higher-quality execution.
* Remove irrelevant permissions:
* Remove USDM- and related- permissions, as [USDM has been acquired and wound down](https://medium.com/@MountainUSDM/mountain-protocol-signs-definitive-agreement-to-be-acquired-by-anchorage-digital-716d8b35c30c).
## Specification
### New permissions implemented in this payload
#### Airdrop Claim
* Spark - [Link](https://app.spark.fi/spk/airdrop)
* Check eligibility & claim SPK
#### Money Markets
* AAVE v3 - [Link](https://app.aave.com/markets/?marketName=proto_mainnet_v3)
* Deposit & Withdraw ETHx & claim rewards - [Link](https://app.aave.com/reserve-overview/?underlyingAsset=0xa35b1b31ce002fbf2058d22f30f95d405200a15b\&marketName=proto_mainnet_v3)
* Spark - [Link](https://app.spark.fi/markets)
* Deposit & Withdraw USDC & claim rewards - [Link](https://app.spark.fi/markets/1/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
* Deposit & Withdraw USDT & claim rewards - [Link](https://app.spark.fi/markets/1/0xdAC17F958D2ee523a2206206994597C13D831ec7)
* Deposit & Withdraw USDS & claim rewards - [Link](https://app.spark.fi/markets/1/0xdC035D45d973E3EC169d2276DDab16f1e407384F)
* Deposit & Withdraw wstETH & claim rewards - [Link](https://app.spark.fi/markets/1/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0)
* Compound V3
* Deposit & Withdraw USDS & claim rewards
### Morpho Lending Markets
Deposit, Withdraw, and Claim Rewards for the following morpho markets
* [cbBTC/USDC](https://app.morpho.org/ethereum/market/0x64d65c9a2d91c36d56fbc42d69e979335320169b3df63bf92789e2c8883fcc64/cbbtc-usdc?subTab=advanced) (86%)
* [wstETH/WETH](https://app.morpho.org/ethereum/market/0xb8fc70e82bc5bb53e773626fcc6a23f7eefa036918d7ef216ecfb1950a94a85e/wsteth-weth) (96.5%)
* [wstETH/WETH](https://app.morpho.org/ethereum/market/0xd0e50cdac92fe2172043f5e0c36532c6369d24947e40968f34a5e8819ca9ec5d/wsteth-weth) (94.5%)
* [WBTC/USDC](https://app.morpho.org/ethereum/market/0x3a85e619751152991742810df6ec69ce473daef99e28a64ab2340d7b7ccfee49/wbtc-usdc?tab=market\&subTab=advanced) (86%)
* [wstETH/USDC](https://app.morpho.org/ethereum/market/0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc/wsteth-usdc?tab=market\&subTab=advanced) (86%)
#### Rebasing
* Origin - [Link](https://app.originprotocol.com/#/ousd/)
* Enable rebasing for OETH (opt-in)
#### DEX LPing
* Balancer V3: Deposit (provide liq.), stake LP tokens, claim rewards, unstake and withdraw
* [wstETH-WETH](https://balancer.fi/pools/ethereum/v3/0xc4ce391d82d164c166df9c8336ddf84206b2f812)
* [osETH-WETH](https://balancer.fi/pools/ethereum/v3/0x57c23c58b1d8c3292c15becf07c62c5c52457a42)
* [WETH-ETHx](https://balancer.fi/pools/ethereum/v3/0x4ab7ab316d43345009b2140e0580b072eec7df16)
* Aura Finance: Deposit (stake LP or single asset entry), claim rewards, unstake
* [wstETH-WETH](https://app.aura.finance/#/1/pool/240)
* [osETH-WETH](https://app.aura.finance/#/1/pool/260)
* Curve: Deposit (provide liq.), stake LP tokens, claim rewards, unstake and withdraw
* [ETHx-ETH](https://www.curve.finance/dex/ethereum/pools/factory-v2-338/deposit/)
* [osETH-rETH](https://www.curve.finance/dex/ethereum/pools/factory-stable-ng-15/deposit/)
* [OETH-WETH](https://www.curve.finance/dex/ethereum/pools/factory-stable-ng-402/deposit/)
* Convex: stake LP tokens, claim rewards, unstake LP tokens, and withdraw
* ETHx-ETH
* osETH-rETH
#### Swaps
* CowSwap and Uniswap swap:
* Tokens in:
* SPK, MORPHO
* Tokens Out:
* USDC, USDT, DAI, USDS
* CowSwap TWAP:
* Tokens in:
* USDC, USDT, USDS, ETH
* Tokens Out:
* USDC, USDT, USDS, ETH
#### Remove permissions
* USDM from all permissions
* Curve: Remove permissions for swap, liquidity provision, staking, claim rewards, unstake and withdraw
* [sDAI-USDM](https://www.curve.finance/dex/ethereum/pools/factory-stable-ng-23/deposit/)
* Remove USDM from Token IN and Token OUT for all swaps
### Implications on the ENS Investment Policy Statement
There are no material implications to the ENS Investment Policy Statement as a result of the abovementioned changes. The [Investment Policy Statement](https://copper-added-anglerfish-892.mypinata.cloud/ipfs/bafybeiajihjdrplt75h36upclptjmkqziboekuf7e25fgfuyk2m54sonfi) is pinned on IPFS.
## Zodiac Roles Modifier Permissions Policy
The payload to be executed upon the successful approval of this proposal can be found [here](https://github.com/karpatkey/client-configs/blob/main/clients/ens-dao/mainnet/payloads/ensPermissionsUpdate6.json) (to be downloaded and dropped into [Safe’s transaction builder](https://app.safe.global/apps/open?safe=eth:0x4F2083f5fBede34C2714aFfb3105539775f7FE64\&appUrl=https%3A%2F%2Fapps-portal.safe.global%2Ftx-builder)).
The UI visualization of added (green), removed (red), and updated (blue) permissions is available [here](https://roles.gnosisguild.org/eth:0x703806E61847984346d2D7DDd853049627e50A40/roles/MANAGER/diff/RMyooL7Ul3J4BQkqjMtaGhwWTVUDApWnqPOLKDYeQk), as well as the resulting Tenderly simulation available [here](https://dashboard.tenderly.co/public/safe/safe-apps/simulator/491ff83d-726d-4cd7-9cb6-354b5ed5160a).
The permissions in this proposal have been tested beforehand through our [Test Safe](https://app.safe.global/transactions/history?safe=eth:0xC01318baB7ee1f5ba734172bF7718b5DC6Ec90E1).
EDIT: updated links to reflect inclusion of the permission to transfer SPK to the [ENS Timelock](https://etherscan.io/address/0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7).
## \[EP 6.24.1] \[Social] Funding Request: ENS Meta-Governance Working Group Term 6 (Oct. Window)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21549/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xc689edd77def6b9f6be6ca7fa1729e597c85ee12ae96e134d995a8b9fd78a21f) |
### Abstract
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Metagov Multisig to fulfill anticipated budgetary needs through the next formal funding window in April 2026.
Amount Requested
| | USDC | ETH | $ENS |
| -------------------------- | ---- | --- | ---- |
| ENS Meta-Gov Main Multisig | 379k | 0 | 0 |
This amount will cover all expected expenses outlined below while leaving a prudent reserve to ensure continuity if future funding is delayed.
### Description
#### Current Metagov Wallet Balances
| | USDC | ETH | $ENS |
| ----------------------------------------------------------------------------------------------- | ------- | ----- | ------ |
| ENS Meta-Gov Main Multisig | 164.85k | 58.63 | 82.47k |
| Up to date balance information can be found at [https://enswallets.xyz](https://enswallets.xyz) | | | |
Also taken into consideration for this funding request are existing balances, their use cases, and the coverage they provide for the next term.
USDC — $164,850. Primary operating currency for Steward/Secretary/Scribe compensation (\~$49,000/month) and other Meta-Gov spend (grants, tooling, discretionary). Provides \~3.4 months of compensation runway before other outflows. Additional near-term USDC commitments include Tally front-end services contract funded by Meta-Gov.
ETH — 58.63. Held as an operational buffer/liquidity backstop. Used during the term to smooth obligations (e.g., endowment payments, budget backfills) and converted via TWAP when appropriate. Treated as reserve rather than a source for new initiatives.
$ENS — 82.47k. Originally allocated for governance distributions and other programmatic uses. Given the current balance, no additional $ENS is requested in this proposal.
These balances provide short-term continuity and risk mitigation; they do not replace the need for additional USDC to ensure uninterrupted operations between funding windows.
### Expenditures
Meta-Gov sets aside funds to ensure coverage for mission-critical initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives in current & future terms.
#### Expected Expenses through April 2026
*(including November)*
| | USDC | ETH | $ENS |
| ------------------------------------------- | -------- | ----- | ----- |
| Steward, Secretary, and Scribe Compensation | 294k | - | - |
| Contract Audits | 100k | - | - |
| DAO Tooling | 100k | - | - |
| Discretionary | 50k | - | - |
| **Total Balance** | **544k** | **-** | **-** |
#### Description of Initiatives/Pods
**Steward + Secretary + Scribe Compensation**: Working Group Steward, Scribe, and Secretary compensation [as required by the steward working group rules](https://snapshot.box/#/s\:ens.eth/proposal/0x88de13f2f088390262d1d5e7db9ddff5a74d0b878fedf590a0448c32692078ba).
**Contract Audits**: Meta-governance maintains a balance to be used for contract audits. These audits are performed independently on contracts that are to be included in executable proposals if those contracts impact or affect any ENS protocol or ENS DAO contracts or processes.
**DAO Tooling**: Funding research and/or develpoment interfaces and dashboards to improve the governance process and increase transparency across the DAO.
**Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments.
Contract audits, DAO tooling, and discretionary funds are maintained for the next term's use.
### Conclusion
With a target budget of $544K and existing USDC of approximately $165K, Meta Governance is requesting the differential for the next term.
+544K Expected
-165K Existing
\=379K Requested
This funding request will allow the ENS Meta-Governance Working Group to continue its essential work in providing governance oversight, supporting the management and operation of working groups, and ensuring effective treasury management for the DAO. The requested funds will enable us to maintain our ongoing initiatives and develop new tools to enhance the governance process. We are grateful for the community's ongoing support and engagement, which is crucial to the success of the ENS DAO. The Meta-Governance Working Group remains committed to serving the ENS community and driving the long-term growth and sustainability of the ecosystem.
***
*Thanks @daostrat.eth for drafting this proposal and @5pence.eth for the review.*
## Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
Quorum: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
Approval: Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP 6.24.2] \[Social] Funding Request: ENS Ecosystem Working Group (Oct. Window)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21551/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x9b3f5463e52aadc35155e686f8416297b24e6c7e30cb527747e61cf17b42a5f6) |
### Abstract
The ENS Ecosystem Working Group requests funding of 470,000 USDC to support operations through April 2026. This is the only funding request of Term 6.
The ENS Ecosystem Working Group is responsible for growing and improving the ENS Ecosystem by funding builders and projects that are ENS-specific or ENS-centric.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
| | USDC | ETH | $ENS |
| ------------------------------------------------------------------------------------------------------ | :-----: | :-: | :--: |
| [ENS Ecosystem Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 470,000 | -- | -- |
### Description
#### ENS Ecosystem Multisig Balances - As of October 22, 2025
The ENS Ecosystem Working Group multisigs:
| Multisigs | USDC | ETH |
| :--------------------------------------------------------------------------------------- | -------: | -----: |
| [Main Multisig](https://etherscan.io/address/0x2686a8919df194aa7673244549e68d42c1685d03) | 172k | 25 |
| [IRL](https://etherscan.io/address/0x536013c57daf01d78e8a70cad1b1abada9411819) | - | - |
| [Hackathon](https://etherscan.io/address/0x9b9c249be04dd433c7e8fbbf5e61e6741b89966d) | 42k | 10 |
| [Newsletter](https://etherscan.io/address/0x13aEe52C1C688d3554a15556c5353cb0c3696ea2) | 1k | - |
| **Total** | **215k** | **35** |
#### Reserved for Initiatives
Ecosystem reserves ensure we can cover key initiatives, but reserving is not the same as spending. For example, we’ve set aside $55k for the bug bounty program. The actual amount spent will depend on whether any bugs are discovered.
| Initiatives | USDC | ETH |
| :---------------- | -------: | -----: |
| Hackathons | 350k | - |
| Grants | 100k | 10 |
| Ecosystem Support | 50k | - |
| Bug Bounty | 55k | - |
| IRL | 30k | - |
| **Total** | **585k** | **10** |
***
**Reconciliation**
| Initiatives | USDC | ETH |
| :-------------- | ---------: | ----: |
| Current Balance | 215k | 35 |
| Reserved | (585k) | (10) |
| Buffer | (100k) | (25) |
| **Total** | **(470k)** | **0** |
The ENS Ecosystem Working Group is requesting **470k in USDC** and zero ETH. This request ensures that there are sufficient resources to meet the expected future needs of the ecosystem working group. The buffer is an additional reserve to cover unforeseen expenses or opportunities.
***
#### Initiatives Description
| Initiative | Description |
| ----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hackathons | For our main partner, ETHGlobal, payments are made in January for the calendar year. Early commitment and payment provide better terms. |
| Grants | Grants support active builders in the ecosystem, including funding for hackathon winners. Examples of typical projects can be seen [here](https://discuss.ens.domains/t/term-6-grants-summary/20320/16). |
| Ecosystem Support | Support for open-source dependencies and funding for smart contract audits. This will become increasingly important with the launch of Namchain, which will require updates across the ecosystem. |
| Bug Bounty | Supports the official bug bounty program of ENS administered by [Immunefi](https://immunefi.com/bug-bounty/ens/information/). At the time of writing, the balance is 197k, and a top-up to the max limit of 250k is expected to occur this year. |
| IRL | Funding relates to events that coincide with conferences, such as EthCC & Devconnect. |
#### Historical Spending
For historical spending, please consult the [ENS Working Group Spending Summaries](https://discuss.ens.domains/t/ens-working-group-spending-summaries/20706). This thread provides a consolidated overview of spending across all working groups, not just the Ecosystem Working Group.
***
*This proposal was prepared by [slobo.eth](https://x.com/AlexSlobodnik), Lead Steward of the Ecosystem Working Group.*
## Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
Quorum: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
Approval: Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP 6.24.3] \[Social] Funding Request - ENS Public Goods Working Group Term 6 (Oct. Window)
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21550/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x7b603c5ada65cfcdbdfec9a33352edf731615fe96fbcc09daa7aa97b327e15ce) |
### Abstract
The Public Goods Working Group exists to fund initiatives that advance public goods funding within the wider ecosystem. We support builders, stewards, and community members working on public goods that are aligned with the values and goals of ENS.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules (EP 1.8). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all Working Groups requesting funding.
### Specification
This specification is the amount requested from the DAO treasury to the Public Goods Multisig to fulfill anticipated budgetary needs through to the next formal funding window in April 2026.
The Public Goods working group is requesting 110k USDC and 15 ETH from the DAO to support expected expenses as detailed below.
| | USDC | ETH | $ENS |
| -------------------- | ---- | --- | ---- |
| ENS PG Main Multisig | 110k | 15 | 0 |
This amount will be added to the existing balance to cover all expected expenses outlined below while leaving a small prudent reserve to ensure continuity if future funding is delayed.
### Description
Current Public Goods Wallet Balances as of Oct 21st, 2025
| | USDC | ETH | $ENS |
| -------------------- | ------ | ---- | ---- |
| ENS PG Main Multisig | 169.3k | 6.49 | 200 |
Updated balance information can be found at [enswallets.xyz](https://www.enswallets.xyz/)
### Expenditures
The Public Goods Working Group allocates funds to support the public goods ecosystem through strategic grants and builder grants. While we aim to estimate expenditures accurately, actual spending may shift based on new opportunities or unforeseen needs.
Expected intended expenses through to next funding window in 2026:
| | USDC | ETH | $ENS |
| ----------------- | ---------- | --------- | ----- |
| Strategic Grants | 225k | - | - |
| Builder Grants | 54.3k | 21.49 | - |
| **Total Balance** | **279.3k** | **21.49** | **-** |
#### Description of Initiatives
**1. Strategic Grants:** High-impact funding for initiatives aligned with the long-term vision of ENS and the broader public goods ecosystem. We are working on developing strategic initiatives focused on foundational infrastructure alongside our existing grants.
The pilot for Strategic Grants was [our funding of the DRC](https://discuss.ens.domains/t/ens-public-goods-working-group-funding-the-decentralization-research-center-drc/20319) back in March 2025. Since then, we have allocated stragegic grants partly [in tandem with the EF](https://discuss.ens.domains/t/ens-public-goods-aligning-with-the-new-ef-funding-team/21277) as part of our aligned collaboration on maximizing resource allocation to key projects in the ecosystem as follows:
* [Remix & Fabric](https://discuss.ens.domains/t/ens-public-goods-working-group-funding-remix-labs-fabric/20866/2)
* [Vyper](https://discuss.ens.domains/t/ens-public-goods-working-group-funding-remix-labs-fabric/20866/2)
* [Argot](https://discuss.ens.domains/t/ens-public-goods-working-group-funding-argot/21443)
* [ICANN Engament & Policy Advocacy](https://discuss.ens.domains/t/ens-public-goods-working-group-funding-icann-engagement-and-policy-advocacy/21471)\*
\*not associated with the EF
Strategic Grants is characterized by:
* **Larger Funding Amounts:** Providing substantial support to initiatives that require more significant resources to succeed
* **Internal Expertise Utilization:** Leveraging the expertise of our elected stewards rather than outsourcing key decision-making
* **Focused Impact Areas:** Targeting underfunded yet critical areas such as developer tools, core dependencies, and infrastructure. The matching funding from the EF in most cases ensures the funding achieves maximum impact for the projects funded.
* **Measured Outcomes:** Establishing clear criteria for success and impact measurement from the outset
The request for Strategic Grants is to ensure current grants discussions can be committed to and paid out until the end of term 6.
**2. [Builder Grants](\[https]\(https://discuss.ens.domains/t/think-big-build-in-good/19943\)):** Continues to support builders at all stages of their journey in building public goods. The platform now features USDC payments as well so better accounting and higher amounts of funding are easily distributed through this already tested and successful mechanism. This term we have received in excess of 200 applications for grants across project development cycles and verticals.
The request for Builder Grants is to ensure current approved grants are paid out as milestones complete and adding a buffer for ongoing applications that may be approved until the end of term 6.
### Conclusion
This funding request will allow the Public Goods Working Group to continue its essential work in stewarding public goods funding until the new term starts in 2026 and the next funding window opens. These resources help us support a diverse set of builders, projects, and community-driven efforts, ensuring mindful long-term sustainability and alignment with ENS values.
We are grateful as always for the ongoing support and engagement with our work.
*This proposal was prepared by @simona\_pop, thank you @Coltron.eth & @Sov for the input and review.*
***
## Success Criteria
For this social proposal to pass, the following quorum and voting requirements must be met:
Quorum: The proposal must receive a minimum of 1% of the total supply of $ENS (1 million votes) in the form of "For" and "Abstain" votes combined. "Against" votes do not count towards quorum.
Approval: Once the quorum is reached, the proposal requires a simple majority (>50%) of "For" votes among the "For" and "Against" votes to pass. "Abstain" votes do not count towards the approval calculation.
## \[EP 6.25] \[Social] Replace the Working Groups with the ENS Admin Panel
::authors
| **Status** | Rejected |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21616/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xbc44d9714ee818da49c25998cabdbe745f939fef74923255c3571a00e8977e5d) |
### Summary
This proposal calls for winding down the Meta-Governance, Ecosystem, and Public Goods Working Groups at the end of Term 6 (Dec 31, 2025) and the creation of the ENS Admin Panel on Jan 1, 2026.
### Motivation
The purpose of Working Groups at their creation was to "[promote stability and encourage long-term thinking and planning.](https://docs.ens.domains/dao/proposals/0.4/)"
A casual observation of working groups would suggest we are missing the mark and actually detracting from the north star goal of being a universal naming standard, often bringing attention to internal politics rather than external objectives.
Working Groups are subject to two main problems:
#### 1. No incentive for hard truths
When future funding depends on relationships, your incentives are to not hurt feelings. "I'll support your proposal if you support mine" becomes the norm. This prioritizes psychological safety over truth seeking, and without truth seeking, you get stuck with bad results.
#### 2. Inability to fire contributors
Working Groups can't curate who participates. Traditional organizations select their team and fire when needed while WGs are open by default, accumulating contributors based on availability rather than ability. The reality is bad contributors make good contributors leave.
An Admin Panel is needed to eliminate the subjective decision-making that Working Groups currently hold and shift DAO operations to a lean, administrative model that removes the perverse incentives outlined above.
### Details
#### Winding Down DAO Operations
If the social proposal passes, all Working Groups must return remaining funds to the DAO and transfer ownership of multisigs to the elected Admin Panel by December 31, 2025.
#### Admin Panel
The Admin Panel will consist of 1 Administrator and 4 Signers.
The Administrator will:
1. Execute transactions when necessary on stream.mg.wg.ens.eth
2. Pay KPK’s performance fees using investment yield.
3. Ensure all service providers and ENS Labs adhere to objective reporting requirements and provide a consolidated report.
4. Can provide space for a quarterly town hall where Service Providers and Labs can present.
5. Perform reasonable admin roles when necessary.
The Administrator will **not**:
* Have a grants program
* Have weekly calls
* Do anything beyond the 5 points above
Having one designated Administrator creates clear accountability and a direct point of responsibility. For security, this Administrator will be supported by 4 elected multisig Signers whose sole duty is to review and approve transactions within a reasonable time frame. If this proposal passes, the DAO would hold two separate social votes: one to elect the Administrator and one to elect the four Signers.
Compensation (To be distributed via stream of USDC from DAO):
* **Administrator** (1 spot): 120k USDC per year
* **Signer** (4 spots): 12k USDC per year per signer
## \[EP 6.26] \[Social] ENS Retro: An ENS DAO Retrospective & Stakeholder Analysis
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21648/) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x8d16992852893f05b23b0e26de27c9e6b2a8de1193c991e14f81ef13cd943517) |
## Summary
DAOs have had almost a decade of history, during which there have been very few retrospective reviews of DAO treasury spend. This proposal aims to bring more accountability to the DAO’s spending, developing clear and measurable datapoints that the DAO can use to continue to build its processes and decision making mechanisms.
This temp check proposes undertaking a formalised retrospective on ENS DAO; its impact, its spending, its goals and its outputs from the past two years. Examining grants, DAO service providers, DAO working groups and any other output from the DAO treasury.
This retro was initially an output of conversations at [Edge City](https://www.edgecity.live/) with Arnold and myself exploring [d/acc](https://vitalik.eth.limo/general/2023/11/27/techno_optimism.html) ideas on DAO evolution. ENS DAO is the golden example of how projects can actively expand output, community, contribution and opportunity by operating as a DAO - however, this doesn’t mean that we shouldn’t look within to improve our processes and operations. To maintain this industry leadership, ENS must be willing to self examine our goals, structure, spending and output in an honest and encouraging way.
This idea was then shared to a telegram group including working group stewards, ENS labs and clowes.eth because of how [This](https://discuss.ens.domains/t/toward-accountable-and-strategic-funding-in-ens/20732) post sparked initial thinking about more retrospective analysis of the DAOs outputs. This was then discussed during ENS & Governance events at Devconnect, and most recently the pre-proposal has been introduced to Metagov.org and Eugene who (as this proposal will outline) will ideally play the role of a data-backed, independent actor, motivated by increasing the rigor and efficacy of DAOs more broadly.
The retro will build upon the existing reporting structures developed across service providers and working groups (such as the quarterly updates from both, shoutout to Limes for these excellent [WG spending summaries](https://discuss.ens.domains/t/ens-working-group-spending-summaries/20706)).
**The goal of this proposal is to establish clear accountability standards for the DAO and measure outcomes against intentions. While gathering strong data to improve governance cycles, service provider selection, working groups and DAO growth.**
## Motivation
ENS DAO has grown significantly since its launch in 2021, supported by a wide range of contributors, funded initiatives, working groups, and service providers. While the high-level success of ENS is objective and clear, the DAO lacks some elements of structure and accountability. DAOs have already made immense impact on the growth and opportunity within Ethereum and we see this proposal as a way to continue improving these structures. The motivation of this proposal is to examine ENS DAO’s purpose, practices, desired outcomes, spending, outputs, and outcomes.
* What has been funded - What has not
* What has been delivered - What has not
* Tracking outputs from the ENS DAO as well as what impact do we think will be generated over a longer timeline (in as measurable ways as possible, as well as anecdotally where possible). - What outputs have not been tracked/considered
* What was considered to be reported on, what hasn’t, understanding previous reporting standards.
* What goals does the DAO have implicit and explicit - Are they only outlined in the constitution or do specific programs have specific goals?
* What are ways in which the DAO can be more rigorous and more easily held accountable?
* ENS DAO Stakeholder analysis that would use a combination of surveys and interviews to better understand the desired outcomes of the DAO, as well as the challenges it faces.
**This list obviously isn’t fully expansive of everything that will be covered in the retro and I’d encourage all ideas and additions here! An open call for different metrics, milestones or ideas that ENS could be evaluating.**
After speaking with a number of delegates, stewards and other contributors, we believe that a retrospective is the most high impact action that we can take as a DAO. Below is a synopsis of the conversations that lead us to this position:
* ENS DAO is one of the strongest DAOs in the ecosystem; establishing more formal accountability standards further strengthens our position. **Very few DAOs in history have conducted this type of activity, and this will continue ENS’ position as a clear industry leader.**
* Agreement that the SPP decision/vote structure needs improvement and that without conducting a retrospective on the decisions made to date it’s difficult to recommend a new path forward.
* Working groups were an output from initial ideation around the DAO. Understanding their goals, output and processes is a perfect first step before executing any specific next step.
This type of retro mirrors reporting norms expected from comparable scale traditional organisations, foundations, and public companies.
* Building structured evaluation into DAO operations improves signal for delegates and DAO contributors making DAO decisions.
* This sets a precedent around transparent DAO accountability.
**We acknowledge that this process could increase the workload of WG stewards, service providers, delegates, and DAO contributors in the short term, however ideally this process increases efficiencies and makes contribution easier in the long run. The intention is to create a foundational review that reduces ambiguity and improves operational efficiency in all future cycles!**
## Timeline & Contributors
We envision this process taking no more than 4 months, with the aim of having it completed by the start of March before the SPP vote.
The ENS DAO Retro & Stakeholder Analysis would be fully conducted by Eugene and Metagov.org as an independent party. Contributions and data provision can be provided by anyone (in or outside of the DAO) however the data collection and analysis will be managed independently by Metagov.org, to ensure that no internal DAO politics, or external parties acting in their own best interest, blur the intent or output of the retrospective.
**Another area for immediate feedback is the methods in which ENS stakeholders can contribute to this project.** Community members will be encouraged to provide all relevant data and reports, which will be publicly tracked. There will also be a surveys and interviews meant to gather more qualitative information, ranging from people’s understanding of the mission, to outlining potential challenges or problems the DAO needs to solve.
It is important to remind readers - the goal of this project is not produce a proposal of what ENS DAO does next. This retrospective and stakeholder analysis is meant to provide clarity on where the DAO is and what are the some the challenges it is facing. From there, the community will use this information to inform subsequent proposals on where to take ENS DAO in Q2 of 2026 and beyond.
## Request for Working Group Steward Term Extension
To ensure this retrospective informs the next SPP and WG cycles, this proposal also seeks to ratify the extension of Working Group Steward terms by up to 4 months, moving elections to \~March 2026.
We understand that a term extension without explicit opt in from WG stewards may incur some downstream effects as some WG stewards may have other commitments or already have made a decision about running in the next election. However this proposal would posit that by extending stewards term we encourage a minimum level of commitment in the retrospective where stewards have to opt out rather than opt in. This proposal would also extend the ongoing distributions to stewards to maintain their payment over this period.
If any steward wants to opt out and is not willing to continue to participate as a steward (or separately from the retro), then as long as one WG lead stays on the working group can be maintained over this extension (likely with an understood reduced output level, along with hopeful participation in the retro).
If a working group has all three stewards that are unwilling to participate in the term extension, this proposal would initially propose their WG would be ‘paused’ until the end of the extension and their multisig funds would be returned to the DAO.
**This element is obviously a large and important part of the proposal - But after discussion with the ENS ecosystem (on & offline) and ideating on WG lead participation, it seems incredibly important to have the existing WG stewards (many of which have been here for the last two years) participating and bringing insight to this process.**
*On top of the reality that these stewards have insight to bring, because of these retro discussions over the past \~4 weeks (which I will directly take responsibility for alongside the MetaGov WG) there hasn’t been an announcement or any space for new possible electorates to propose themselves, which is another reason to extend these elections so we can have more time to invite wider contributors to the working groups.*
*As a part of this proposal it was considered to enable WG elections during the retro (over coming weeks), since extending working groups in this way disrupts the current structure that serves the DAO and community. However after consideration, keeping the current working group stewards by extending the current term for up to 4 months gives the retro the highest likelihood of engagement and ease.*
## Budget Requirements
As outlined below in the specification section, this snapshot vote (and previous forum post) is only an initial signal about whether the DAO retro and stakeholder analysis should go ahead. Specific deliverables, proposal scope and budget breakdown will be presented by Metagov.org as a part of the discussion between the snapshot vote and executable proposal, though as an initial estimate it’s envisioned that this budget will be \~$125k +/- $25k.
This budget could be managed by a range of actors; the MetaGov Working group, ENS Labs or Metagov.org themselves. This budget would also be tied to deliverables, timeline and scope defined by Metagov.org in the subsequent proposal.
## Specification
This proposal is an initial temp check that is the first step in a multi-step process towards this retrospective:
* This proposal will be posted on snapshot to signal from the DAO that this proposal and retrospective is a worthwhile exercise. (This week)
* After a successful snapshot vote, this proposal will be further refined by Metagov.org to give a clearer scope of work around deliverables, budget breakdowns and clear goals & outputs of a DAO retrospective. (\~one week)
* ENS Working Group elections would be paused following this snapshot proposal until (at minimum) the following onchain proposal ratifies this proposal.
* A ratifying onchain vote would occur that would enact this proposal, kick off the retro, extend working group terms, distribute the retro budget and empower Metagov.org as the independent party of the initiative. (By December 17th)
* Work will commence immediately, accounting for time off during public holidays, with rolling updates shared on the forum.
**Effect on working group rules:**
This proposal affects Working Group elections and is utilising [Working Group rule 12.1](https://docs.ens.domains/dao/wg/rules#12-amendments) around Working Group Amendments.
* This proposal directly affects [Working group rule 3.2 around term time limits](https://docs.ens.domains/dao/wg/rules/#3-working-group-stewards) and [Working group rule 6. around delaying steward elections](https://docs.ens.domains/dao/wg/rules/#5-steward-elections), by proposing an extension to the current Working Groups stewards term (as well as their compensation) and delaying the Steward elections window until either: - This proposal has an onchain ratifying vote that extends WG terms and pushes the next election window until March after the ENS retrospective. - This snapshot proposal doesn’t pass, triggering a start to the elections whenever viable: - Triggering Working Group rule 6.1, where steward elections will take place “as soon as is practicable after the missed Nomination Window or missed Election Window.” CC the post from [Metagov Working group here](https://discuss.ens.domains/t/steward-elections-term-7-update-on-timing-and-next-steps/21683).
* If two or more WG stewards are no longer willing to continue in their positions, funds from that multisig will be returned to the DAO treasury, in line with the bylaws.
* If one WG steward is no longer willing to hold their multi-sig position, the Metagovernance working group will decide on multi-sig governance or funds being returned to the DAO.
## Conclusion
This retrospective is **an opportunity to elevate global DAO governance standards, reinforce accountability, and continue to set ENS up for long-term success.** By conducting this retrospective now and aligning upcoming governance cycles to incorporate its findings, the DAO strengthens its ability to deploy resources efficiently and transparently.
**Despite this being a doubted time period in the history of DAOs, I’m extremely confident in ENS DAO’s ability to prioritise decentralisation, community contribution and genuinely building in public alongside Ethereum. Conducting this retro aims to strengthen decentralised organisations as a whole and empower ENS to continued industry leadership.**
## \[EP 6.27] \[Executable] Endowment permissions to karpatkey - Update #7
::authors
| **Status** | Active |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/21641/) |
| **Votes** | [Agora](https://agora.ensdao.org/proposals/32193910699583510191805100765941306153785098144960716714178124679398515702376), [Tally](https://tally.ensdao.org/dao/proposal/32193910699583510191805100765941306153785098144960716714178124679398515702376) |
### Abstract
This proposal introduces a routine update to the permissions for the Endowment Manager. These updates continue to evolve diversification to lending markets. This update also removes a permission no longer needed.
### Motivation
The permissions in this update focus on in increasing the availability of lending markets, specifically Morpho Vaults curated by kpk and others on Fluid Protocol.
### Specification
This proposal adds and removes the following contracts and functions:
#### ✅ Additions
##### 1. Tokens
| Token | Functions Allowed | Token Address (Mainnet) |
| ----- | ----------------- | ------------------------------------------ |
| GHO | `approve` | 0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f |
##### 2. Morpho Lending Markets
| Market | Functions Allowed | Vault Contract Address (Mainnet) |
| ---------------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------------------------------ |
| [kpk USD Prime](https://app.morpho.org/ethereum/vault/0xe108fbc04852B5df72f9E44d7C29F47e7A993aDd/kpk-usdc-prime) | `deposit` `withdraw` `redeem` | 0xe108fbc04852B5df72f9E44d7C29F47e7A993aDd |
| [kpk USDC (v2)](https://app.morpho.org/ethereum/vault/0x4Ef53d2cAa51C447fdFEEedee8F07FD1962C9ee6/kpk-usdc) | `deposit` `withdraw` `redeem` | 0x4Ef53d2cAa51C447fdFEEedee8F07FD1962C9ee6 |
| [kpk ETH Prime](https://app.morpho.org/ethereum/vault/0xd564F765F9aD3E7d2d6cA782100795a885e8e7C8/kpk-eth-prime) | `deposit` `withdraw` `redeem` | 0xd564F765F9aD3E7d2d6cA782100795a885e8e7C8 |
| [kpk ETH (v2)](https://app.morpho.org/ethereum/vault/0xBb50A5341368751024ddf33385BA8cf61fE65FF9/kpk-eth) | `deposit` `withdraw` `redeem` | 0xBb50A5341368751024ddf33385BA8cf61fE65FF9 |
##### 3. Fluid Protocol Lending Markets
| Market | Functions Allowed | Contract Address (Mainnet) |
| ------------------- | ----------------------------- | ------------------------------------------ |
| Fluid protocol USDC | `deposit` `withdraw` `redeem` | 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33 |
| Fluid protocol USDT | `deposit` `withdraw` `redeem` | 0x5C20B550819128074FD538Edf79791733ccEdd18 |
| Fluid protocol GHO | `deposit` `withdraw` `redeem` | 0x6A29A46E21C730DcA1d8b23d637c101cec605C5B |
#####
4\. Other
| Market | Functions Allowed | Contract Address (Mainnet) |
| ----------------------- | ----------------- | ------------------------------------------ |
| Fluid Merkl Distributor | `claim` | 0x7060FE0Dd3E31be01EFAc6B28C8D38018fD163B0 |
#### ❌ Removals
##### 1. Other
| Name | Functions Removed | Contract Address (Mainnet) |
| ----------------------------- | ----------------- | ------------------------------------------ |
| Universal Rewards Distributor | `claim` | 0x330eefa8a787552DC5cAd3C3cA644844B1E61Ddb |
### Reviewing Zodiac Roles Modifier Permissions Policy
To review, the following resources are below:
* **Payload:** [https://github.com/karpatkey/client-configs/blob/main/clients/ens-dao/mainnet/payloads/ensPermissionsUpdate7.json](https://github.com/karpatkey/client-configs/blob/main/clients/ens-dao/mainnet/payloads/ensPermissionsUpdate7.json) (Updated to remove EURc)
* **Zodiac Diff Visualisation Tool:** [https://roles.gnosisguild.org/eth:0x703806E61847984346d2D7DDd853049627e50A40/roles/MANAGER/diff/fiM5U8aU0VkbG4NglApFoWkapISvh5vuvcfqsVXUJE?annotations=false](https://roles.gnosisguild.org/eth:0x703806E61847984346d2D7DDd853049627e50A40/roles/MANAGER/diff/fiM5U8aU0VkbG4NglApFoWkapISvh5vuvcfqsVXUJE?annotations=false)
### Considerations
The assets in these lending markets are considered to conform to the risk tolerance specified in the [Investment Policy Statement (IPS)](https://copper-added-anglerfish-892.mypinata.cloud/ipfs/bafybeiajihjdrplt75h36upclptjmkqziboekuf7e25fgfuyk2m54sonfi).
Morpho vaults curated by kpk collect no additional fees.
### Next Steps
The proposal will be introduced in the next meta-governance call. Pending review from Blockful and no revisions following the discussion in during the meta-gov call, this proposal will progress to an on-chain executable vote.
## \[EP 6.3] \[Social] Renew Service Provider Budget
::authors
| **Status** | Passed, increase budget to $4.5M/year |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20272) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x0cca1cf36731203e235b0e2de9041be3a16d9cdeadff6e15e1f1215c611e12ef) |
The Service Provider's streams were initiated almost exactly a year ago, and while it's approved for 18 months, it is supposed to be a program reevaluated yearly. Here is the proposed format for this year. This vote intends to be a DAO check on whether to renew the program and if so, under what budget.
### Vote
The vote will be a Ranked Choice Vote on either to approve or reject and budget. Options will be:
* Renew and increase budget to $4.5 Million per year
* Renew and maintain budget at $3.6 Million per year
* Renew but reduce budget to $2.7 Million per year
* Do not renew the program.
The budget is set per year. However the actual required budget will need to cover 19 months, because as detailed below, 1/3 of the streams will be budgeted for 2 years and we will add another 3 months of runway to make sure the program is not interrupted by eventual delays in the 2026 vote.
### What is the Service Provider Program
The ENS constitution states that "Any income generated to the ENS treasury is to be used first of all to ensure the long-term viability of ENS, and to fund continuing development and improvement of the ENS system.". The goal of this program is to create a more diverse and decentralized base of developers and companies involved in the improvement of the ENS system, by creating a guaranteed income stream to support their continued work. Streams last at least one year.
### Who can apply?
Any company offering services they believe will add value to the ENS ecosystem is eligible to apply. While this process has traditionally focused on developers, delegates now have discretion to determine what services qualify as beneficial.
#### Eligibility Requirements:
* The applicant must be an existing company, over one year old, with an established team and reputation.
* The company or its team members must have serious prior experience with ENS, blockchain, or internet domain related projects.
* The company must secure endorsement of at least 50k delegated ENS tokens, either through public backing by a delegate or by demonstrating support via Snapshot.
* Neither the company nor its team members may reside in OFAC-sanctioned countries.
### Submission Process
**Candidates will be required to submit a proposal demonstrating their eligibility and outlining their plans. The proposal must include the following:**
1. **Past Achievements:**\
A list of their accomplishments in ENS, the blockchain space, or domain systems.
2. **Scope of Work and Budgets:**
* A **basic scope**, which outlines the minimum yearly budget they would accept to perform their work, along with the specific goals and deliverables they aim to accomplish within that budget.
* Optionally, they may also provide an **extended scope**, which includes an increased budget and details the additional projects or goals they would pursue if granted this higher budget.
3. **Proposal Format:**\
The submission must be provided both as a written document and as a short video (no longer than 5 minutes) where the team discusses the above points.
4. **Quarterly KPIs:**\
The proposal must include a set of quarterly Key Performance Indicators (KPIs) to define what "success" looks like for their basic and extended scope. These may include specific targets, such as product releases, user acquisition numbers, or other measurable metrics that can be used to evaluate their progress against their own promises. Althought we encourage developers to explore new areas of research outside these given metrics, considerable thought should be given to these metrics, and every quarter you will be required to post an update on them. Failing targets in two consecutive targets will trigger a Service Assessement (see below) by Metagov stewards.
5. **Budget Guidelines:**
* All budgets must be submitted as integer multiples of $100k per year.
* The minimum budget request is $300k per year, and the maximum is $1.3M per year.
### What will be selection proccess look like?
1. **Eligibility & Voting**
* The MetaGov Working Group reviews candidates for eligibility.
* Eligible candidates are included in a ranked-choice DAO vote with the option **"None Below"**.
* A quorum of **1M ENS** votes is required; otherwise, the process halts and a new vote is conducted.
2. **Budget Streams**
* **Two-Year Stream**: 1/3 of the yearly budget for a two-year duration.
* **One-Year Stream**: Remaining 2/3 of the yearly budget for one year.
3. **Evaluation Process**\
Projects are assessed in ranked order:
* If **"None Below"** is reached, evaluation stops.
* If the candidate has been part of the Service provider program for at least a year AND if the **extended budget** fits within the remaining two-year stream budget, assign to the **two-year stream** . Subtract the extended budget from the two-year stream budget.
* Assign to the **one-year stream** if:
1. The **extended budget** fits the one-year budget. Subtract its extended budget from the one-year stream.
2. OR if the **basic budget** fits the one-year budget, subtract the its basic budget from the one-year stream.
* If none of these conditions are met, the project is eliminated.
4. **Completion**
* Evaluation ends when all projects are assessed, the remaining budget on all streams reaches zero or **"None Below"** is selected.
### Relevant Dates
The Submission process will start as soon as this vote ends, the deadline for submission of proposals will be \*March 31st\*\* and the vote for the selection will start soon after that. Those with the two year stream will be guaranteed a stream until at least february 2027, while the others will be at least february 2026, when they will need to submit again.
### Resposibilities for selected service providers
#### Brand name and association with ENS DAO
Selected providers will be rewarded with the streams, but will also carry the responsibility to represent ENS to the world. They will be granted usage of the ENS brand name (within guidelines).
The stream will be managed by the Metagovernance Stewards, but they are to enact representing the DAO's intent. They will have access to pause or move streams due to security concerns or upon the request of the service provider. They can only terminate a stream if there is a sucessful DAO vote requesting them to do so (which the DAO is free to do at any point for any reason).
#### Open Source
All work done directly funded by this program must be Open Source and Freely Licensed (MIT). Service Providers are free to also have proprietary codebases but the works establised in their proposals and quarterly reports must also be available on github or other public repositories.
#### Quarterly reports
Service Providers must provide a detailed written report on their accomplishments every quarter. They are also required to present at working group meetings when requested by stewards and to give at least one presentation at a conference each year (remote attendance is acceptable if necessary). These reports must include any metrics or KPIs promised for the reporting quarter, as well as any new metrics or KPIs proposed for future quarters. Additionally, the report must state the total amount received during the quarter. While Service Providers are encouraged to include financial spending details, this is at their discretion and not a mandatory requirement.
#### Increased funding
Selected service providers may request specific, non-recurring grants at any time, following the usual governance process on the forum. However, to request an increase in their ongoing stream budget, they must meet the following conditions:
* They must have been a service provider for at least one year.
* At least six months must have passed since their most recent stream-related request, whether it was part of a service provider submission or another stream adjustment process, regardless of either it was sucessful or not.
Service Providers can terminate their own stream at any time without notice, thus liberating them from any further obligations towards the DAO. (Note: Terminating their stream does not exempt them from potential liability for any misconduct or unresolved issues.)
### Responsabilities for Metagov Working Group
The ENS DAO can terminate streams for any reason following the proper governance procedure and after a DAO vote. Additionally, Metagov or Ecosystem Stewards can and should trigger a Service Assessement if any of these conditions are met:
* A service provider fails to publish their quaterly report twice
* A service provider falls short of the KPIs on their proposal twice *in a row*.
* A service provider is unresponsive to attempts to contact them
* A service provider is believed to be actively participating in a behavior or project that is considered harmful to the ENS system or brand.
The Metagov Working will then appoint a person that will conduct an investigation on the claims and publish recommendations on how to solve the issue moving forward. Solutions might include (but are not limited to) a reconsideration of new KPIs, a demand of internal reorganization for the service provider, a renegotiation of terms or even the termination from the program. Once the report is published, a DAO wide vote will executed to decide on the proper outcome for the provider.
## \[EP 6.4] \[Social] Service Provider Season 2 Vote Amendment Proposal
::authors
| **Status** | Superseded by [EP 6.5](/dao/proposals/6.5) |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20526/57) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0xf0c3a2fe4bd085ea74a072cafb830aaadb4830b557a3d122eab36058a17c1860) |
### Abstract
EP 6.3 was passed with a budget of $4.5M for 2025 on the 25th of February and pertains to Service Provider budgets and allocation mechanisms for 2025. After broad discussion between delegates, working groups and service providers, a proposed change to the voting process is now being presented for vote.
### Vote
This is a proposed amendment to the evaluation criteria for Service Providers. On April 1st there was an Delegate All Hands meeting in which many delegates expressed the desire to be able to fine tune their vote in order to express preference over not only the teams, but also their respective budgets. This was followed by extensive discussion between delegates, working groups and Service Providers, leading to the below amendment:
*The goal here is to propose a new rule change while keeping the same properties as having a single budget be decided in one simultaneous vote.*
#### Current Evaluation Process, as voted on snapshot
> **Evaluation Process**
>
> Projects are assessed in ranked order:
>
> * If "None Below" is reached, evaluation stops.
> * If the candidate has been part of the Service provider program for at least a year AND if the extended budget fits within the remaining two-year stream budget, assign to the two-year stream . Subtract the extended budget from the two-year stream budget.
> * Assign to the one-year stream if:
> * The extended budget fits the one-year budget. Subtract its extended budget from the one-year stream.
> * OR if the basic budget fits the one-year budget, subtract the its basic budget from the one-year stream.
> * If none of these conditions are met, the project is eliminated.
#### New proposed rule amendment
The vote will present both extended and basic budgets as separate options and a given voter can pick *either* budget to rank their candidates. They do not need to rank both budget options separately, as they are considered the same candidate.
The rank of each candidate will be the rank of it's highest ranked budget option, according to a Copeland methodology (using average support as a tiebreaker). Then a pairwise comparison will be made between the two budget options and the preferred one will be set as its selected budget.
#### Vote Processing Algorithm
1. **Votes Preprocessing**:
* For providers with both basic and extended budget options, the algorithm enforces the lowest option to be ranked immediately after the highest option (of the same provider).
* If a provider has only one budget option, no special enforcement is needed for that provider.
* This grouping ensures accurate pairwise comparisons between different between different providers and then budget options from the same provider.
2. **Pairwise Comparisons (copeland)**:
* For each pair of candidates (provider), we calculate the total voting power supporting each over the other.
* A candidate wins a head-to-head matchup if the total voting power ranking them higher exceeds that of their opponent.
* Each win contributes 1 point to a candidate's Copeland score.
* The pairwise comparison between basic and extended must also be stored, for defining the preference on the budget.
3. **"None Below" Handling**:
* The "None Below" option serves as a cutoff point in a voter's ranking.
* Candidates ranked above "None Below" are considered ranked.
* Candidates ranked below "None Below" are considered unranked by that voter.
* A ranked candidate always wins against an unranked candidate in pairwise comparisons.
4. **Scoring and Ranking**:
* Candidates are ranked by their Copeland score (descending), with average support as a tiebreaker.
#### Allocation Process
1. **Budget Type Determination**:
* Each provider's budget (basic or extended) is determined by their internal head-to-head match result.
2. **Stream Allocation**:
* Candidates are processed in Copeland ranking order.
* Candidates that are in top 5 and were selected in SPP1, are elegible for the 2-year stream.
* All other candidates receive allocations from the 1-year stream.
* From top to bottom, try to fit projects in the 2 year stream budget, and then on the 1-year stream budget using the standard knapsack algorithm, stopping once budgets are exhausted or None Below is reached.
* If a service providers extended scope got a majority vote over basic scope and the extended scope doesn't fit into the remaining 1-year budget but the basic budget does, then the given service provider's basic budget is included.
* If a candidate is ranked below "None Below", they're rejected regardless of budget availability.
3. **Budget Transfer Mechanism**:
* After processing the top 5 candidates, any remaining 2-year budget transfers to the 1-year stream. Final 1-year budget = (Initial 1-year budget) + (Leftover 2-year budget).
4. **Rejection Criteria**:
* A candidate is rejected if:
* They're ranked below the "None Below" option
* There's insufficient budget
### Updated Timelines
The initial proposal stated a submission deadline of March 31st, and vote to begin *soon* after that.
This vote will be conducted over the next 5 days. Then, if the vote is successful MetaGov will be interfacing with voting UI teams to ensure sufficient testing and timelines before the final SPP vote. There will be a minimum of 3 days between this proposal closing and the start of the final vote, to allow Service Providers to update their proposals if necessary.
### Conclusion
If this amendment proposal passes, the MetaGov working group, delegates and governance UI providers will enact the updated proposal process.
We would like to thank everyone who has taken the time to be involved in this discussion and have been blown away by the level of engagement & productivity throughout.
## \[EP 6.5] \[Social] Service Provider Season 2 Vote Amendment Proposal II
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20526/42) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x60c95ab69a427ce263f4c3c950df8da1134e96a3e76d139c8dac366271009530) |
### Abstract
Season 2 of the Service Provider Program was approved with a $4.5M budget on February 25th of this year. During the Delegate All Hands meeting on April 1st, delegates expressed a desire for more granular voting — not only to approve candidates, but also to vote on individual budget allocations.
In the weeks that followed, extensive discussions took place on how to address this through an amendment. Two main proposals emerged from these discussions, now formally designated as EP6.4 and EP6.5.
### Vote Results
There are now two active proposals to amend the Service Provider Program. Here's how the outcome of this vote should be interpreted:
* If this vote passes but receives fewer votes than EP6.4, then this amendment is considered null.
* If this vote passes and receives more votes than EP6.4, then EP6.4 is considered superseded.
* If this vote fails to reach either a majority or consensus, then only the results of EP6.4 should be considered valid.
Absolutely — here's a clearer and more polished version of your section on the main differences between the proposed amendments, with improved grammar, flow, and formatting, while staying faithful to your original content:
### Main Differences Between Proposed Amendments
* **Ballot Reordering and Expressivity**:\
Both amendments enhance the expressiveness of the SPP voting system, allowing voters to choose both teams and their budgets (as opposed to the current model, where budget size is inferred from ranking). However, **EP6.5** goes further by enabling voters to place an *extended* budget request **below multiple basic budgets**. This allows voters to express preferences such as: “This team should receive its extra funding, but only after these other teams get their basic funding.”
* **Ballot Interpretation**:\
Both amendments involve reordering ballots based on how voters rank options.
* **EP6.4** always bundles a candidate’s basic and extended budget requests together, preserving their relative order in the original ballot.
* **EP6.5**, on the other hand, only reorders ballots when an *extended* budget is ranked **above** its corresponding basic budget — to avoid accidental inconsistencies in voter intent.
* **Basic vs. Extended Budget Competition**:
* In **EP6.4**, a candidate’s basic and extended budgets compete only with each other. Whichever is ranked higher wins.
* In **EP6.5**, a candidate’s *extended* budget competes with **all** other allocations for the same budget amount, not just the candidate’s own basic option. This allows for a more nuanced prioritization across teams.
* **Complexity of Rules**:
* **EP6.4** introduces a custom ballot preprocessing step, a distinct counting method, and special downgrade rules for extended budgets.
* **EP6.5** has a simplified preprocessing, but achieves similar outcomes through emergent behavior from its ruleset, which may lead to rankings on Snapshot that are more closely aligned with what is displayed in custom UIs.
***
### Amended rules for the Service Provider Program
#### 1. Proposals
Teams can propose a **basic budget**, and optionally an **extended budget**, which is listed as the **extra amount** they’d like on top of the basic. The ballot would include all budget options as independent entries to be ranked independently.
Candidates will have a chance to edit their proposal, but as it stands, these are the current asks:
| Company | Basic Scope | Extra Ask |
| -------------------------------- | ----------- | --------- |
| **AlphaGrowth** | $400,000 | +$400,000 |
| **ZK.Email** | $400,000 | +$400,000 |
| **Blockful** | $400,000 | +$300,000 |
| **Unruggable** | $400,000 | +$300,000 |
| **3DNS** | $500,000 | +$200,000 |
| **Ethereum.Identity.Foundation** | $500,000 | +$200,000 |
| **JustaName** | $400,000 | +$200,000 |
| **NameHash.Labs** | $1,100,000 | +$200,000 |
| **Namespace** | $400,000 | +$200,000 |
| **Agora** | $300,000 | +$100,000 |
| **dWeb.host** | $300,000 | +$100,000 |
| **EthLimo** | $700,000 | +$100,000 |
| **Wildcard.Labs** | $300,000 | +$100,000 |
| **Curia.Lab** | $300,000 | – |
| **Decent** | $300,000 | – |
| **Enscribe** | $400,000 | – |
| **GovPal** | $300,000 | – |
| **Lighthouse\_Labs** | $400,000 | – |
| **Namestone** | $800,000 | – |
| **PYOR** | $300,000 | – |
| **Tally** | $300,000 | – |
| **Unicorn.eth** | $300,000 | – |
| **Web3bio** | $500,000 | – |
| **WebHash** | $300,000 | – |
| **x23.ai** | $300,000 | – |
#### 2. Preprocessing Ballots
Before counting, each ballot is checked: if a voter ranks a team’s extra budget above its basic, the basic entry is moved directly above the extra. No changes are made otherwise.
#### 3. Creating the Rank
Each entry is treated as a separate candidate and ranked using the **Copeland method**. If two entries have the same number of match victories, **average support** is used as a tiebreaker (in a sports comparison, this would be equivalent to "total points/goals scored" being used as a tiebreaker between teams with equal number of victories).
#### 4. Budget Allocation
Once ranking is complete, entries are evaluated in order, using a **total budget of $4.5 million**:
1. Assign an entry to the **2-year stream** if it is a **current service provider**, ranked in the **top 10**, *and* assigning it would **not cause the total allocated to 2-year grants to exceed $1.5 million**.
2. If those conditions aren’t met, assign the entry to the **1-year stream** if its budget fits within the **remaining total budget** (regardless of the 2-year cap).
3. Stop the evaluation if the **$4.5M total budget** has been fully allocated, if there are **no more valid candidates**, *or* if **“None Below”** is reached.
## \[6.6.1] \[Social] April Funding Request - ENS Meta-Governance Working Group Term 6
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20536) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x2c56d8776c8be3a824d010f94f00108716acaa31ede92cd03692e779af8a051d) |
### Abstract
The Meta-Governance Working Group is responsible for providing governance oversight and supporting the management and operation of working groups through DAO tooling and governance initiatives as well as treasury management for the DAO.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules ([EP 1.8](https://docs.ens.domains/v/governance/governance-proposals/term-1/ep12-working-group-rules)). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all three Working Groups.
### Specification
This specification is the amount requested from the DAO treasury to the Metagov Multisig to fulfill anticipated budgetary needs through the next formal funding window in October 2025.
| | USDC | ETH | $ENS |
| -------------------------- | ---- | --- | ---- |
| ENS Meta-Gov Main Multisig | 589k | 0 | 100k |
This amount will cover all expected expenses outlined below while leaving a prudent reserve to ensure continuity if future funding is delayed.
### Description
#### Current Metagov Wallet Balances
| | USDC | ETH | $ENS |
| ----------------------------------------------------------------------------------------- | ----- | ---- | ---- |
| ENS Meta-Gov Main Multisig | 84.3k | 83.6 | 4.5k |
| \*Up to date balance information can be found at [enswallets.xyz](https://enswallets.xyz) | | | |
### Expenditures
Meta-Gov sets aside funds to ensure coverage for mission-critical initiatives. While we strive to estimate term expenditures accurately, the final spending depends on pending initiatives.
#### Expected Expenses through October 2025
| | USDC | ETH | $ENS |
| -------------------------------- | -------- | ----- | -------- |
| Steward + Secretary Compensation | 294k | - | - |
| Governance | - | - | 100k |
| Contract Audits | 150k | - | - |
| DAO Tooling | 150k | - | - |
| Discretionary | 45k | - | - |
| **Total Balance** | **639k** | **-** | **100k** |
#### Description of Initiatives/Pods
**Steward + Secretary Compensation**: Working Group Steward, Scribe, and Secretary compensation [as required by the steward working group rules](https://snapshot.box/#/s\:ens.eth/proposal/0x88de13f2f088390262d1d5e7db9ddff5a74d0b878fedf590a0448c32692078ba).
**Governance**: Fee reimbursements and future initiatives related to reducing friction in the governance process. This includes 70k $ENS to be distributed to DAO contributor, Stewards, and Service Provider roles. In Term 6 this amount was increased to allow for launch of programs to reward delegators and delegates.
**Contract Audits**: Meta-governance maintains a balance to be used for contract audits. These audits are performed independently on contracts that are to be included in executable proposals if those contracts impact or affect any ENS protocol or ENS DAO contracts or processes.
**DAO Tooling**: Funding research and/or develpoment interfaces and dashboards to improve the governance process and increase transparency across the DAO.
**Discretionary**: Funds distributed at the discretion of stewards towards new initiatives + governance experiments.
### Conclusion
This funding request will allow the ENS Meta-Governance Working Group to continue its essential work in providing governance oversight, supporting the management and operation of working groups, and ensuring effective treasury management for the DAO. The requested funds will enable us to maintain our ongoing initiatives and develop new tools to enhance the governance process. We are grateful for the community's ongoing support and engagement, which is crucial to the success of the ENS DAO. The Meta-Governance Working Group remains committed to serving the ENS community and driving the long-term growth and sustainability of the ecosystem.
## \[6.6.2] \[Social] April Funding Request - ENS Public Goods Working Group Term 6
::authors
| **Status** | Passed |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20532) |
| **Votes** | [Snapshot](https://snapshot.box/#/s\:ens.eth/proposal/0x2c07add832383dc6900077406b4241a34dc4923ba209e2d07d1a4243a18fcdef) |
*This is an updated budget for this funding window to account for better treasury management at this time - a new funding request may be put forward in the October window which was not initially planned when scoping out this budget*
## Abstract
The Public Goods Working Group exists to fund initiatives that advance public goods funding within the wider ecosystem. We support builders, stewards, and community members working on public goods that are aligned with the values and goals of ENS.
This social proposal is submitted to satisfy the requirements set out in Rule 10.1.1 of the Working Group Rules (EP 1.8). If this proposal is passed, the funding request will be included in a collective executable proposal put forward by all Working Groups requesting funding.
## Specification
This specification is the amount requested from the DAO treasury to the Public Goods Multisig to fulfill anticipated budgetary needs through the next formal funding window in October 2025.
| | USDC | ETH | $ENS |
| -------------------- | ---- | --- | ---- |
| ENS PG Main Multisig | 356k | 0 | 0 |
This amount will cover all expected expenses outlined below while leaving a small reserve to ensure continuity if future funding is delayed.
## Description
Current Public Goods Wallet Balances as of April 2, 2025
| | USDC | ETH | $ENS |
| -------------------- | ---- | ---- | ---- |
| ENS PG Main Multisig | 139k | 24.6 | 200 |
Updated balance information can be found at enswallets.xyz
## Expenditures
The Public Goods Working Group allocates funds to support the public goods ecosystem through strategic grants, builder grants, and discretionary initiatives. While we aim to estimate expenditures accurately, actual spending may shift based on new opportunities or unforeseen needs.
Expected Expenses through October 2025
| | USDC | ETH | $ENS |
| -------------------------- | -------- | ----- | ----- |
| Strategic Grants | 300k | - | - |
| Builder Grants | 150k | - | - |
| Discretionary (10% buffer) | 45k | - | - |
| **Total Balance** | **495k** | **-** | **-** |
## Description of Initiatives
**1. Strategic Grants:** High-impact funding for initiatives aligned with the long-term vision of ENS and the broader public goods ecosystem. We are working on developing strategic initiatives focused on foundational infrastructure alongside our existing grants.
The pilot for Strategic Grants is our funding of the DRC. Since they are also receiving external matching funds for any contribution, our funding of 150,000 USDC equates to $300,000 in total funding dedicated to advancing decentralization advocacy and policy engagement.
Strategic Grants will be characterized by:
**Larger Funding Amounts:** Providing substantial support to initiatives that require more significant resources to succeed
**Internal Expertise Utilization:** Leveraging the expertise of our elected stewards rather than outsourcing key decision-making
**Focused Impact Areas:** Targeting underfunded yet critical areas such as developer tools, core dependencies, and infrastructure
**Measured Outcomes:** Establishing clear criteria for success and impact measurement from the outset
**2. Builder Grants:** Support for builders at all stages of their journey in building public goods. The platform will feature USDC payments as of next month so better accounting and higher amounts of funding can easily be distributed through the already tested and successful mechanism.
**3. Discretionary Buffer:** A 10% margin to provide flexibility for time-sensitive or emergent opportunities that align with the working group’s mandate. This may include hackathon sponsorship or event support.
**Conclusion**
This funding request will allow the Public Goods Working Group to continue its essential work in stewarding public goods funding. These resources will help us support a diverse set of builders, projects, and community-driven efforts, ensuring long-term sustainability and alignment with ENS values.
We are grateful for the ongoing support and engagement with our work.
## \[6.7] \[Executable] Transfer .ceo TLD to the DNSSEC registrar
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/temp-check-executable-transfer-ceo-tld-to-the-dnssec-registrar/20594) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/51329136884099251878034959419745117799040381230875971532699817044496491926852) |
### Abstract
The .ceo TLD, formerly owned by Kred Pty, has since been acquired by XYZ. Prior to the formation of the DAO, the previous owner asked for .ceo to be delegated to a custom address so they can manage a bespoke DNS integration. The new owner has requested that this change be undone, and that ownership of .ceo be reverted to the DNSSEC registrar so owners of .ceo TLDs can use the standard integration to claim their names on ENS.
To prove ownership of .ceo and their intention that we action this request, they have set a TXT record on `_ens.nic.ceo` to the address of the DNSSEC registrar, `0xB32cB5677a7C971689228EC835800432B339bA2B`. This can be verified with the following command:
```
dig TXT _ens.nic.ceo
```
### Specification
Call `setSubnodeOwner` on the ENS `Root` contract at `0xaB528d626EC275E3faD363fF1393A41F581c5897`, passing in the keccak256 hash of `ceo` and the address of the DNSSEC registrar, `0xB32cB5677a7C971689228EC835800432B339bA2B`.
### Transactions
Address
Value
Function
Argument
Value
0xaB528d626EC275E3faD363fF1393A41F581c5897
0
setController
address
0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7
controller
true
0xaB528d626EC275E3faD363fF1393A41F581c5897
0
setSubnodeOwner
label
0xa695017707ee0c04095f723270b3c315654d16e337ad54039175a4b000894676
owner
0xB32cB5677a7C971689228EC835800432B339bA2B
## \[EP 6.9] \[Executable] Revoke root controller role from legacy ENS multisig
::authors
| **Status** | Passed |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Discussion Thread** | [Forum](https://discuss.ens.domains/t/20644) |
| **Votes** | [Tally](https://www.tally.xyz/gov/ens/proposal/83558494563463316177076768398348085020294312678713085260352382286714788322618) |
### Abstract
We have identified that the legacy ENS multisig, which originally controlled ENS before the DAO was created, still has the 'controller' role on the ENS root. This means that a majority of multisig keyholders could create or replace any ENS TLD other than .eth. .eth is locked and cannot be modified by the DAO or anyone else.
In order to correct this oversight, this proposal revokes the legacy multisig's controller role from the root contract.
### Specification
Call `setController` on the ENS `Root` contract at `0xaB528d626EC275E3faD363fF1393A41F581c5897`, passing in the address of the legacy multisig, `0xCF60916b6CB4753f58533808fA610FcbD4098Ec0`.
## Process of Submitting a Proposal
### Passing a Proposal
#### Types of Proposal
There are three main types of governance proposals you can make:
1. **[Executable Proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/executable-proposal-template.md):** This is a proposal for a series of smart contract operations to be executed by accounts the DAO controls. These can include transfers of tokens as well as arbitrary smart contract calls. Examples of this include allocating funding to a workstream multisig wallet, or upgrading an ENS core contract. Executable proposals have a quorum requirement of 1% and require a minimum approval of 50% to pass.
2. **[Social Proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/social-proposal-template.md)**: This is a proposal that asks for the agreement of the DAO on something that cannot be enforced onchain. Examples of this include a proposal to change the royalty percentage for the ENS secondary market on OpenSea, or a petition to the root keyholders. Social proposals have a quorum requirement of 1% and require a minimum approval of 50% to pass.
3. **[Constitutional Amendment](https://github.com/ensdomains/docs/tree/master/src/public/governance/constitutional-amendment-template.md)**: This is a social proposal that asks the DAO to amend the constitution. Your draft proposal should include a [diff](https://en.wikipedia.org/wiki/Diff) showing the exact changes you propose to make to the constitution. Rules for amending the constitution are set in the constitution itself, and currently require a quorum of 1% and a minimum approval of two thirds to pass.
#### **Phase 1: Temperature Check — Discourse**
The purpose of the Temperature Check is to determine if there is sufficient will to make changes to the status quo.
To create a Temperature Check, ask a general, non-biased question to the community on [discuss.ens.domains](https://discuss.ens.domains) about a potential change (example: "Should ENS decrease registration costs for 3-letter domains?"). Forum posts should be in the "DAO-wide -> Temperature Check" category.
Temperature checks are informal and optional; it's up to you to use the feedback to decide if you want to proceed further with your proposal.
#### **Phase 2: Draft Proposal — GitHub**
The purpose of the Draft Proposal is to establish formal discussion around a potential proposal.
To create a Draft Proposal, [create a new governance proposal](https://github.com/ensdomains/governance-docs/new/main/governance-proposals) in the governance-docs repository on GitHub. Start by copying the template for an [executable proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/executable-proposal-template.md), [social proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/social-proposal-template.md), or [constitutional amendment](https://github.com/ensdomains/docs/tree/master/src/public/governance/constitutional-amendment-template.md), as appropriate. Once you have written your proposal, create a Draft Pull Request for it. Start a new post in the DAO-wide -> Draft Proposals" category with a link to the PR for discussion.
Reach out to your network to build support for the proposal. Discuss the proposal and solicit delegates to provide feedback on it. Be willing to respond to questions on the Draft Proposal topic and in comments on the pull request. Share your viewpoint, although try to remain as impartial as possible.
If your proposal is an executable proposal, you will need to specify the actions your proposal will take while it is in draft stage. You may wish to wait until the proposal is stable before doing this. The executable proposal template explains how to do this.
If your proposal is a constitutional amendment, you will need to produce a diff showing the exact changes you are proposing to make. The easiest way to do this is to go to the [constitution](/dao/constitution), click "Edit on GitHub", then click the pencil icon to edit the document in a fork. You can then create a pull request via the GitHub UI and include this in your proposal. You should do this in a separate branch to your draft proposal; while the proposal will be merged as soon as it goes to a vote, the amendment will only be merged if the proposal passes.
Once you are confident the proposal is in a stable state, you can proceed to phase 3.
#### **Phase 3: Active Proposal — Snapshot / Governance Portal**
Use GitHub to flag your PR as Ready for Review. A contributor will:
1. Merge your PR if it meets the requirements.
2. Assign your proposal a proposal number in the form EP###.
3. Schedule the proposal for a snapshot vote.
If your proposal is a Social Proposal or a Constitutional Amendment, that's it! If the snapshot vote passes, the proposal is passed and you are done.
If your proposal is an Executable Proposal, you will now need to submit it to the governor contract for voting onchain.
To enact an Executable Proposal:
1. Ensure at least 100k ENS is delegated to your address in order to submit a proposal, or find a delegate who has enough delegated ENS to meet the proposal threshold to propose on your behalf.
2. Call the propose() function of the ENS governor (at [governor.ensdao.eth](https://etherscan.io/address/0x323a76393544d5ecca80cd6ef2a560c6a395b7e3)) to deploy your proposal.
Once the propose() function has been called, a seven day voting period is started. Ongoing discussion can take place on your proposal post. If the proposal passes successfully, a two day timelock will follow before the proposed code is executed.
## Moderator Checklists \[Process documentation and checklists for DAO moderators handling proposals]
### Advancing a proposal to a vote
When the author of a Draft Proposal asks for it to be advanced to a vote, and you agree, follow the below steps:
* [ ] Modify the title to include the next sequential EP number (eg `[EP4] ...`).
* [ ] Move from Draft Proposals to Active Proposals category.
* [ ] Delete Discourse poll (if any).
* [ ] [Create a Snapshot vote](https://snapshot.org/#/ens.eth/create):
* [ ] 5 day duration.
* [ ] Simple voting unless otherwise called for in the proposal.
* [ ] Copy and paste the title and contents of the proposal to the vote.
* [ ] Add a link to the forum thread at the bottom.
* [ ] Replicate the proposal in the governance docs:
* [ ] Create the header table with a link to the forum thread and snapshot vote.
* [ ] Copy and paste the title and contents of the proposal.
* [ ] Set the status to 'Active'.
* [ ] Submit as a PR for the docs.
* [ ] Edit the forum thread to link to the Snapshot vote at the top.
* [ ] Send a forum DM to the 'delegates' group announcing that the proposal is up for voting.
* [ ] Send a tweet announcing that the proposal is up for voting.
### Proposal pass/rejection
When a proposal's voting period concludes, follow the below steps:
* [ ] Update the proposal in the governance docs:
* For an Executable Proposal that just passed its Snapshot vote, set the status to 'Awaiting Execution'.
* Otherwise, set the status to 'Passed' if it passed and 'Rejected' if it did not.
* [ ] Update the forum thread:
* [ ] Remove the Snapshot/Tally link at the top.
* [ ] List the current status (as above) at the top of the proposal.
* [ ] If the proposal is Passed or Rejected, lock the thread.
* [ ] If the proposal is an Executable Proposal and passed its snapshot vote:
* Do the "Executing a proposal" checklist below if it is ready to be executed.
* Otherwise, add a note to the forum thread about when it will be scheduled for execution.
* [ ] If the proposal is a Constitutional Amendment:
* Merge the PR to the constitution if it passed.
* Close the PR otherwise.
* [ ] If the proposal requires any other action, alert those responsible of the need to enact it.
* [ ] Send a tweet announcing the result of the proposal.
### Executing a proposal
When an Executable Proposal is ready to be executed, follow the below steps. If you do not have sufficient voting power to submit an executable proposal, ask someone else to do this for you.
* [ ] Construct the executable proposal on the interface of your choice, such as [Tally](https://www.tally.xyz/gov/ens/proposals) or [Agora](https://agora.ensdao.org/), following the instructions in the proposal.
* [ ] Have someone else double-check the proposal is structured correctly for you.
* [ ] Optionally, use [Tenderly](https://dashboard.tenderly.co) to simulate the effects of submitting the proposal directly to the timelock contract to check it has the expected effect.
* [ ] Submit the proposal to the chain.
* [ ] Add a link to the vote on Tally to the top of the proposal on the forum thread.
* [ ] Update the status of the proposal in the governance docs to 'Active'.
* [ ] Send a forum DM to the 'delegates' group announcing the proposal is up for execution, with a link to the Tally proposal page.
* [ ] Send a tweet announcing that the proposal is up for voting.
## Governance Process \[An overview of the ENS DAO's governance processes, and how you can get involved]
This document is a suggested process for developing and advancing ENS Governance Proposals. It is a living document intended to be owned, modified and enforced by the ENS community.
### Venues
[discuss.ens.domains](https://discuss.ens.domains) is a Discourse forum for governance-related discussion. Community members must register for an account before sharing or liking posts. Registering for the forum allows community members to post in the general forum; for access to the working groups, fill out the [participant request form](https://airtable.com/shrv2xP39SmuCcd5j).
There are three workstream categories: [Meta-Governance](https://discuss.ens.domains/c/meta-governance/28), [Public Goods](https://discuss.ens.domains/c/public-goods/37), and [ENS Ecosystem](https://discuss.ens.domains/c/ens-ecosystem/32). Each category has subcategories for each of the steps of the governance process described below.
#### Snapshot
[Snapshot](https://snapshot.org/#/ens.eth/) is a simple voting interface that allows users to signal sentiment offchain. Votes on snapshot are weighted by the number of ENS delegated to the address used to vote.
#### Governance portals
[Tally](https://tally.ensdao.org) and [Agora](https://agora.ensdao.org) are governance portal that allows token holders to delegate their votes, and allows delegates to create and vote on binding proposals.
### Getting Work Done
You are probably here because you want the DAO to *do* something. The primary mechanism by which the DAO gets things done is via "Requests for Proposal" (RFPs). An RFP is a request from the DAO for contributors to offer to do work on its behalf, and receive compensation in return.
Anyone who identifies a need can write an RFP, and if the RFP is passed, anyone can write a proposal in response and be awarded the work. Even if you believe you can do the work yourself, you will still need to pass an RFP in order to be awarded the work (and corresponding compensation) by the DAO.
RFPs vary in detail and complexity. An RFP for improving the DAO's documentation may only be a paragraph or two long, and proposals for it will be equally short. At the other extreme, an RFP for managing the DAO's funds may be lengthy, and a successful proposal could be multiple pages justifying the proposer's ability to take on the job.
#### The RFP Process
RFPs all follow this process:
1. Write a draft RFP ([template here](https://github.com/ensdomains/docs/blob/master/src/public/governance/rfp-template.md)) and post it as a discussion thread in the appropriate working group on [the DAO forum](https://discuss.ens.domains/). At a minimum, RFPs must:
a. Explain the need for the RFP and describe the work to be done - the scope of work and deliverables.
b. Specify the requirements for a winning bid - criteria for selection.
c. Provide a timeline for submissions and completion of the work.
d. Nominate a party who will select a winning bid and approve & disburse compensation (the RFP manager). Normally this will be the working group who adopts the RFP.
e. Specify a maximum budget for the RFP.
2. Incorporate feedback from DAO participants into your draft. When you believe it is ready, tag the stewards of the working group and request they consider adopting it.
3. If the stewards agree to adopt your RFP, they will decide if it can be paid out of WG funds, or if it needs a DAO wide vote.
a. If the RFP can be paid out of WG funds, they will set a submission period and post it as an active RFP.
b. Otherwise, the stewards will create an executable proposal (or, they may ask you to do this) asking the DAO as a whole to approve the RFP. The proposal should contain the RFP. The executable component should specify approvals from the DAO funds to the RFP manager in the amount of the maximum budget for the proposal.
4. Once the RFP is approved - either by the WG or by a DAO-wide vote - the submission period begins. You or a WG steward should create a post on the DAO forum for proposals, and anyone can submit a proposal to this thread.
5. Once the submission period is concluded, the RFP manager selects a winning bid. Normally the manager will be the stewards of the working group who has adopted your RFP.
6. The author of the winning proposal commences the work. As they meet milestones specified in the RFP and their proposal, they can request compensation from the RFP manager, who disburses it from the allocated funds.
### Passing a Proposal
#### Types of Proposal
There are three main types of governance proposals you can make:
1. **[Executable Proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/executable-proposal-template.md):** This is a proposal for a series of smart contract operations to be executed by accounts the DAO controls. These can include transfers of tokens as well as arbitrary smart contract calls. Examples of this include allocating funding to a workstream multisig wallet, or upgrading an ENS core contract. Executable proposals have a quorum requirement of 1% and require a minimum approval of 50% to pass.
2. **[Social Proposal](https://github.com/ensdomains/docs/tree/master/src/public/governance/social-proposal-template.md)**: This is a proposal that asks for the agreement of the DAO on something that cannot be enforced onchain. Examples of this include a proposal to change the royalty percentage for the ENS secondary market on OpenSea, or a petition to the root keyholders. Social proposals have a quorum requirement of 1% and require a minimum approval of 50% to pass.
3. **[Constitutional Amendment](https://github.com/ensdomains/docs/tree/master/src/public/governance/constitutional-amendment-template.md)**: This is a social proposal that asks the DAO to amend the constitution. Your draft proposal should include a [diff](https://en.wikipedia.org/wiki/Diff) showing the exact changes you propose to make to the constitution. Rules for amending the constitution are set in the constitution itself, and currently require a quorum of 1% and a minimum approval of two thirds to pass.
#### **Phase 1: Temperature Check — Discourse**
The purpose of the Temperature Check is to determine if there is sufficient will to make changes to the status quo.
To create a Temperature Check, ask a general, non-biased question to the community on [discuss.ens.domains](https://discuss.ens.domains) about a potential change (example: “Should ENS decrease registration costs for 3-letter domains?”). Forum posts should be in the "DAO-wide -> Temperature Check" category.
Temperature checks are informal and optional; it's up to you to use the feedback to decide if you want to proceed further with your proposal.
#### **Phase 2: Draft Proposal — GitHub**
The purpose of the Draft Proposal is to establish formal discussion around a potential proposal.
To create a Draft Proposal, [create a new governance proposal](https://github.com/ensdomains/governance-docs/new/main/governance-proposals) in the governance-docs repository on GitHub. Start by copying the template for an [executable proposal](executable-proposal-template.md), [social proposal](social-proposal-template.md), or [constitutional amendment](constitutional-amendment-template.md), as appropriate. Once you have written your proposal, create a Draft Pull Request for it. Start a new post in the DAO-wide -> Draft Proposals" category with a link to the PR for discussion.
Reach out to your network to build support for the proposal. Discuss the proposal and solicit delegates to provide feedback on it. Be willing to respond to questions on the Draft Proposal topic and in comments on the pull request. Share your viewpoint, although try to remain as impartial as possible.
If your proposal is an executable proposal, you will need to specify the actions your proposal will take while it is in draft stage. You may wish to wait until the proposal is stable before doing this. The executable proposal template explains how to do this.
If your proposal is a constitutional amendment, you will need to produce a diff showing the exact changes you are proposing to make. The easiest way to do this is to go to the [constitution](/dao/constitution), click "Edit on GitHub", then click the pencil icon to edit the document in a fork. You can then create a pull request via the GitHub UI and include this in your proposal. You should do this in a separate branch to your draft proposal; while the proposal will be merged as soon as it goes to a vote, the amendment will only be merged if the proposal passes.
Once you are confident the proposal is in a stable state, you can proceed to phase 3.
#### **Phase 3: Active Proposal — Snapshot / Governance Portal**
Use GitHub to flag your PR as Ready for Review. A contributor will:
1. Merge your PR if it meets the requirements.
2. Assign your proposal a proposal number in the form EP###.
3. Schedule the proposal for a snapshot vote.
If your proposal is a Social Proposal or a Constitutional Amendment, that's it! If the snapshot vote passes, the proposal is passed and you are done.
If your proposal is an Executable Proposal, you will now need to submit it to the governor contract for voting onchain.
To enact an Executable Proposal:
1. Ensure at least 100k ENS is delegated to your address in order to submit a proposal, or find a delegate who has enough delegated ENS to meet the proposal threshold to propose on your behalf.
2. Call the propose() function of the ENS governor (at [governor.ensdao.eth](https://etherscan.io/address/0x323a76393544d5ecca80cd6ef2a560c6a395b7e3)) to deploy your proposal.
Once the propose() function has been called, a seven day voting period is started. Ongoing discussion can take place on your proposal post. If the proposal passes successfully, a two day timelock will follow before the proposed code is executed.
### **Governance Terminology**
**ENS**: An ERC-20 token that designates the weight of a user’s voting rights. The more ENS a user has in their wallet, the more weight their delegation or vote on a proposal holds.
**Delegation**: ENS holders cannot vote or create proposals until they delegate their voting rights to an address. Delegation can be given to one address at a time, including the holder’s own address. Note that delegation does not lock tokens; it simply adds votes to the chosen delegation address.
**Executable Proposal**: An executable proposal is a type of proposal that is executed by the governance contract through timelock. It can replace the governance contract, transfer tokens from the community treasury, or perform an almost infinite range of other onchain actions. In order to create a proposal, an address must have at least 0.1% (100k ENS) of all ENS delegated to their address. Proposals are stored in the “proposals” mapping of the Governor smart contract. All proposals are subject to a 7-day voting period.
**Quorum**: In order for a vote to pass, a certain percentage of ENS tokens must vote in the affirmative. The current quorum requirements are:
* Executable Proposals: 1%
* Social Proposals: 1%
* Constitutional Amendments: 1%
The purpose of this quorum is to ensure that the only measures that pass have adequate voter participation.
**Voting on Executable Proposals**: Users can vote for or against single proposals once they have voting rights delegated to their address. Votes can be cast while a proposal is in the “Active” state. Votes can be submitted immediately using “castVote” or submitted later with “castVoteBySig” (For more info on castVoteBySig and offline signatures, see EIP-712). If the majority of votes (and a 1% quorum of ENS) vote for a proposal, the proposal may be queued in the Timelock.
**Voting Period**: Proposals on Snapshot have a 5 day voting period. Once an executable proposal has been put forward, ENS community members will have a seven day period (the Voting Period) to cast their votes.
**Timelock**: All governance actions are delayed for a minimum of 2 days by the timelock contract before they can be executed.
import { EmbedLink } from '../../components/EmbedLink'
import { Repository } from '../../components/Repository'
## Smart Contracts
The Ethereum Name Service is made up of a set of smart contracts.
These smart contracts are responsible for storing and managing information associated with names.
### Resolution
The resolution process outlines how a name is resolved.
This includes the process of finding a resolver, and then using that resolver to fetch information about a name.
### Resolvers
Every name has a resolver, responsible for fetching information about a name, such as address, avatar, and more.
Resolvers allow for programmatic control over the information associated with a name, implemented in solidity.
There are various resolvers to choose from, such as the [Public Resolver](/resolvers/public) or [write your own](/resolvers/writing).
### Registry & Registrars
The smart contracts can be found on github at [ensdomains/ens-contracts](https://github.com/ensdomains/ens-contracts).
{[
['The Registry', '/registry/ens'],
['ETH Registrar', '/registry/eth'],
['DNS Registrar', '/registry/dns'],
['Reverse Registrar', '/registry/reverse'],
].map((list) => (
))}
### Source Code
The code for the ENS Smart Contracts as well as information around the latest deploys, tests, and more can be found on github.
### ENSv2
## ENSv2 Smart Contracts Overview
Welcome to the next evolution of the Ethereum Name Service!
ENSv2 introduces a suite of upgraded smart-contracts designed to make the protocol
more scalable, modular and future-proof. This section will outline the high-level
architecture, guiding principles and migration strategy for ENSv2.
:::note
The information on this page is a work-in-progress. Expect updates as the design is finalised and audits are completed.
:::
### What's new in ENSv2?
* **Native L2 Support** – contracts have been designed with [Namechain](https://ens.domains/ensv2) and other Layer 2 deployments
with cross-chain resolution in mind, building on existing [CCIP-Read support in ENSv1](/resolvers/ccip-read).
* **Hierarchical Registries** – while ENSv1 used a single flat registry for all
names, ENSv2 allows each name to provide its own registry implementation for
subnames. This provides name owners and developers with direct control over
the ownership and transfer rules for names and subnames.
* **Permissions as Standard** - All of the functionality enabled by the [Name Wrapper
in ENSv1](/wrapper/overview) has been integrated into the core of ENSv2, using a new, highly flexible,
role-based permissions model.
* **No Grace Period** - The grace period is no longer a part of the ENS protocol, meaning names expire when they say they expire. Upon expiration, names immediately enter into the [temporary premium](/registry/eth#premium--auctions) period. The owner of a recently-expired name doesn't have to pay the premium fee during this period.
* **Contract Factories** - Rather than relying on large multi-user contracts such as
the default public resolver, every name gets its own resolver, and every name
with subnames gets its own registry contract. This is made possible by the low cost of
L2 transactions, and simplifies the contracts significantly, while offering users
new functionality such as the possibility of 'aliasing' multiple domains to
the same records.
### What hasn't changed?
* **Resolvers** - while we have developed new resolver contracts to take advantage
of the changed environment enabled by ENSv2 and Namechain, the interface used
by resolvers remains the same, and all existing ENSv1 resolvers will continue
to work seamlessly in ENSv2.
* **True Ownership** - ENSv2 continues to prioritize trust minimization, enabling
you to own your name fully, without having to worry about interference from
centralized third-parties.
* **Truly multi-chain** - Although ENSv2 hosts .eth names on Namechain by default,
ENS continues to support all L2s. Names can be 'ejected' from Namechain to L1,
and from there can either be managed directly on L1 or delegated to another L2.
### ENSv2 Registry Architecture
#### Overview
ENSv1 used a simple architecture, where a single flat registry maintained a mapping
from all names to their owner and resolver addresses. Hierarchical ownership was enforced
through the use of [namehash](/resolution/names#namehash) to calculate IDs for subnames. This has the advantage of simplicity,
but means that ownership rules are enforced by a single, non-upgradeable contract, and
changes in the status of a parent name do not automatically ripple down to affect
subnames.
```mermaid
---
title: ENSv1 Structure
---
flowchart LR
subgraph Registry
direction LR
root["<root> owner: 0x0123..."]
eth["eth owner: 0x1234..."]
montoya["montoya.eth owner: 0x5678... • resolver: 0x6789..."]
inigo["inigo.montoya.eth owner: 0x7890... • resolver: 0x890A..."]
domingo["domingo.montoya.eth owner: 0x90AB... • resolver: 0x0ABC..."]
end
resolvers@{label: "Resolvers", shape: processes}
Registry --> resolvers
```
In ENSv2, registries are hierarchical: each name can have a resolver and a subregistry:
```mermaid
---
title: ENSv2 Structure
---
flowchart TB
root@{label: "<root> owner: 0x0123..."}
eth@{label: "eth owner: 0x1234..."}
montoya@{label: "montoya.eth owner: 0x5678..."}
inigo@{label: "Resolver 2 owner: 0x7890... addr(60): 0x7890...", shape: notch-rect}
domingo@{label: "domingo.montoya.eth owner: 90AB..."}
montoyaResolver@{label: "Resolver 1 owner: 0x5678... addr(60): 0x5678...", shape: notch-rect}
root-- eth --> eth
eth-- montoya --> montoya
eth-- montoya --> montoyaResolver
montoya-- inigo --> inigo
montoya-- domingo --> domingo
```
Here, registries are shown as rectangles, while resolvers are shown as notched rectangles.
Note that the registry for `.eth` has both a subregistry and a resolver defined for `montoya.eth`.
Note also that there's a resolver defined for `inigo.montoya.eth` but no subregistry, while
`domingo.montoya.eth` has a subregistry but no resolver. A name only needs to have a subregistry
defined if it wants the ability to create subnames, and it only needs a resolver defined if it wants to
define records to resolve for that name or its subnames.
Resolution follows a process that conceptually mirrors the process from ENSv1: first, we find the resolver
responsible for the name being resolved, which is the resolver that covers the longest available suffix
of the name. In the example above, `inigo.montoya.eth` is resolved by Resolver 1, while `domingo.montoya.eth`
and any other subdomains of `montoya.eth` that are not present in the tree are resolved by Resolver 2. After
the resolver responsible for a name is found, it is queried for the desired record.
One consequence of this tree structure is that it becomes possible to delete or reassign entire subtrees in a
single operation. For example, suppose `montoya.eth` is transferred to a new owner, who wants to
configure his own set of subdomains; he can simply replace the subregistry responsible for subnames of
`montoya.eth` with his own new subregistry:
```mermaid
flowchart TB
eth@{label: "eth owner: 0x1234..."}
montoya@{label: " owner: 0x5678..."}
newMontoya@{label: "montoya.eth owner: 0xABCD..."}
inigo@{label: "Resolver 2 owner: 0x7890... addr(60): 0x7890...", shape: notch-rect}
domingo@{label: "domingo.montoya.eth owner: 90AB..."}
montoyaResolver@{label: "Resolver 1 owner: 0x5678... addr(60): 0x5678...", shape: notch-rect}
eth ~~~ montoya
eth-- montoya --> newMontoya
eth-- montoya --> montoyaResolver
montoya-- inigo --> inigo
montoya-- domingo --> domingo
```
All resolvers and subregistries previously associated with `montoya.eth` are thus removed in a single operation!
The new owner will still need to replace the resolver for `montoya.eth` if he wishes to change how the bare
name itself is resolved, however.
This hierarchical structure need not be limited to trees, either; by reusing the same subregistry for more
than one name, entire namespaces can be aliased to each other:
```mermaid
flowchart TB
root@{label: "Registry 1 owner: 0x0123..."}
eth@{label: "Registry 2 owner: 0x1234..."}
montoya@{label: "Registry 3 owner: 0x5678..."}
inigo@{label: "Registry 4 owner: 0x7890... addr(60): 0x7890...", shape: notch-rect}
domingo@{label: "Registry 5 owner: 90AB..."}
montoyaResolver@{label: "Resolver 1 owner: 0x5678... addr(60): 0x5678...", shape: notch-rect}
root-- eth --> eth
eth-- montoya --> montoya
eth-- wallet --> montoya
eth-- montoya --> montoyaResolver
montoya-- inigo --> inigo
montoya-- domingo --> domingo
```
In this example, both `inigo.montoya.eth` and `inigo.wallet.eth` resolve identically, as would any other
subnames with resolvers set. Notably, `domingo.montoya.eth` will resolve using Resolver 1, while
`domingo.wallet.eth` will not resolve at all - there are no resolvers set anywhere in its hierarchy! If we
set a resolver for `domingo` in Registry 3, both names would resolve identially using it, just as they do
for `inigo`.
This example also exposes one other crucial fact about ENSv2: registries have no individual concept of 'their name'.
In earlier diagrams we labelled each registry with a name for convenience, but as these examples demonstrates,
there's no requirement that a registry have exactly one name associated with it - it can have thousands, or none
at all!
#### Token Representation and permissions
Although it's not required by the ENSv2 registry interface specification, typically registries are
implemented as ERC1155 token contracts, and standardized tooling is likely to expect as much. Each registry
has an overall owner, who is responsible for the registry itself, as well as owners for individual subnames,
which are represented as tokens. Because of the hierarchical nature of the registry structure as demonstrated
above, merely owning a subname token on a registry does not guarantee anything in isolation: to be meaningful,
the registry must be referenced by a parent registry, and so on up to the root registry. Client authors must
therefore take care in how they represent names to users, to ensure users are not given a false impression
of what they are looking at.
Standardized registries in ENSv2 use a sophisticated permissions model similar to Open Zeppelin's Roles model.
Each name has a set of roles, such as the ability to set the resolver or subregistry for that name. Each role
has a corresponding 'admin role', which allows granting or revoking that role (as well as the admin role itself).
Roles can also be granted for the registry contract as a whole, and an account may exercise the privileges of
a role if it has the role granted for the specific name or on the contract as a whole. Some roles, such as
creating new subnames, are available only as contract-wide roles.
By selectively revoking roles, all the functionality of the [ENSv1 name wrapper](/wrapper/overview) can be replicated - for example,
the owner of wallet.eth can grant a registrar contract the 'registrar' role on the wallet.eth registry,
while revoking their own contract-wide 'set resolver' and 'set subregistry' roles and admin roles on the same
registry. If they then revoke the 'set subregistry' role and admin role for the 'wallet' subname on the 'eth'
registry, they will no longer be able to modify wallet.eth subnames they don't own - giving the same effect as
['emancipating'](/terminology#emancipated) a name in the ENSv1 name wrapper.
When a subname is transferred to a new owner, any roles that were granted to the previous owner are automatically
transferred to the new owner, but roles granted to other accounts remain unmodified - so it is important that
apps facilitating trading of names verify the set of roles granted to external accounts.
{/* ## Contract Packages
ENSv2 is split into the following logical groups:
| Package | Description |
| ----------------------------------------- | ------------------------------------------------------- |
| [Registries](/contracts/ensv2/registries) | Registries govern ownership of names |
| [Resolvers](/contracts/ensv2/resolvers) | Resolvers control how a name is converted to a resource |
## Upgrade timeline
The team is targeting **Q4 2024** for mainnet deployment, subject to audit and
community review. A detailed upgrade guide will be published here soon. */}
{/* # ENSv2 Registries
This page documents the suite of registry contracts that underpin ENSv2.
:::note
The contracts and interfaces described here are **not yet final** and may change prior to main-net deployment.
:::
## Core Concepts
``` */}
{/* # ENSv2 Resolvers
Resolvers are the heart of ENS – they translate human-readable names into
machine-readable data. */}