This repository contains code for minting and managing ENS subdomains on the Base network as base.eth
subdomains.
It supports:
- Registering base.eth subdomains on Base natively
- Managing the name with a public resolver, allowing an owner or operator to set address records, text records, dns records, etc.
- ERC721 subdomain tokens (Opensea)
Basenames are a core onchain building block that enables anyone to establish their identity on Base by registering human-readable names for their address(es). They are a fully onchain solution which leverages ENS infrastructure deployed on Base.
Contract | Address |
---|---|
L1Resolver | 0xde9049636F4a1dfE0a64d1bFe3155C0A14C54F31 |
Contract | Address |
---|---|
Registry | 0xb94704422c2a1e396835a571837aa5ae53285a95 |
BaseRegistrar | 0x03c4738ee98ae44591e1a4a4f3cab6641d95dd9a |
RegistrarController | 0x4cCb0BB02FCABA27e82a56646E81d8c5bC4119a5 |
Launch Price Oracle | 0xd53b558e1f07289acedf028d226974abba258312 |
Price Oracle | 0x508CFE43aa84b8048cB6d39037cE0dc96d8aDc75 |
ReverseRegistrar | 0x79ea96012eea67a83431f1701b3dff7e37f9e282 |
L2Resolver | 0xC6d566A56A1aFf6508b41f6c90ff131615583BCD |
Contract | Address |
---|---|
L1Resolver | 0x084D10C07EfEecD9fFc73DEb38ecb72f9eEb65aB |
Contract | Address |
---|---|
Registry | 0x1493b2567056c2181630115660963E13A8E32735 |
BaseRegistrar | 0x03c4738ee98ae44591e1a4a4f3cab6641d95dd9a |
RegistrarController | 0x49ae3cc2e3aa768b1e5654f5d3c6002144a59581 |
Launch Price Oracle | 0x2B73408052825e17e0Fe464f92De85e8c7723231 |
Price Oracle | NOT YET DEPLOYED |
ReverseRegistrar | 0xa0A8401ECF248a9375a0a71C4dedc263dA18dCd7 |
L2Resolver | 0x6533C94869D28fAA8dF77cc63f9e2b2D6Cf77eBA |
The system architecture can be functionally organized into three categories:
- An L1 resolver enabling cross-chain resolution for the
base.eth
2LD. - An ENS-like registry/registrar/resolver system deployed on Base enabling
*.base.eth
subdomains to be registered and managed. - An off-chain gateway for serving CCIP requests required to comply with ENSIP-10.
The core functionality of Base Usernames should look familiar to anyone that's looked under the hood at the ENS contracts. We implement a slimmed down fork of the ENS contracts here.
Contract | Role | ENS Implementation | Base Usernames Implementation |
---|---|---|---|
Registry | Stores Records of subdomains in a flat structure | ENSRegistry.sol | Registry.sol |
BaseRegistrar | Tokenizes names, manages ownership and stores expiry | BaseRegistrarImplementation.sol | BaseRegistrar.sol |
ReverseRegistrar | Manages the reverse lookup to allow the setting of "primary" names for an address | ReverseRegistrar.sol | ReverseRegistrar.sol |
L1 Resolver | Enables cross-chain, wildcard resolution from L1 | OffchainResolver.sol | L1Resolver.sol |
L2 Resolver | A standard public resolver for storing records associated with namespaces | PublicResolver.sol | L2Resolver.sol |
Registrar Controller | A permissioned contract which manages registration payment | ETHRegistrarController.sol | RegistrarController.sol |
Stable Price Oracle | The source of pricing based on name length and duration of registration | StablePriceOracle.sol | StablePriceOracle.sol |
Exponential Premium Oracle | A Dutch auction pricing mechanism for fairly pricing names after expiry | ExponentialPremiumPricingOracle.sol | ExponentialPremiumPricingOracle.sol |
In addition to replicating the base behavior of the ENS protocol, we are offering a series of promotional discounts associated with various Coinbase product integrations. As such, the Base Usernames Registrar Controller allows users to perform discounted registrations while passing along integration-specific validationData
. Each discount leverages a common interface:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
/// @title Discount Validator Interface
///
/// @notice Common interface which all Discount Validators must implement.
/// The logic specific to each integration must ultimately be consumable as the `bool` returned from
/// `isValidDiscountRegistration`.
interface IDiscountValidator {
/// @notice Required implementation for compatibility with IDiscountValidator.
///
/// @dev Each implementation will have unique requirements for the data necessary to perform
/// a meaningful validation. Implementations must describe here how to pack relevant `validationData`.
/// Ex: `bytes validationData = abi.encode(bytes32 key, bytes32[] proof)`
///
/// @param claimer the discount claimer's address.
/// @param validationData opaque bytes for performing the validation.
///
/// @return `true` if the validation data provided is determined to be valid for the specified claimer, else `false`.
function isValidDiscountRegistration(address claimer, bytes calldata validationData) external returns (bool);
}
The various implementations can be found in this directory.
$ forge build
$ forge test
$ forge fmt
$ forge snapshot
$ forge --help
$ anvil --help
$ cast --help