[RFC] A Programmable Fast-Path for TLD Assignment

The Status Quo re: Assigning TLDs

Currently, every new ENS TLD requires a full governance proposal, a DAO vote, and a one-off setSubnodeOwner call. That’s secure, but it doesn’t scale. With ~1,500 ICANN TLDs, it’s an undue burden to ask delegates to repeatedly go through the full governance process for each one.

Importantly, however, DNS can’t become an authority over ENS.

So the question is: can we make TLD onboarding programmable without giving up sovereignty?

Not “DNS assigns ENS,” but:

DNS proposes, ENS programmatically executes under DAO-defined law.

Programmable TLD Assignment Model

With Fusaka, bridging to ‘real-world’ cryptography has become economically feasible and practical at protocol scale. Let’s use this opportunity to build a turnkey solution for TLD operators that is cryptographically grounded, programmable by policy, and governed by the DAO.

A programmable TLD assignment model would move ENS from one-off governance actions to a standing, programmable process, while preserving root sovereignty and constitutional control.

This direction follows Article V of the ENS Constitution, which commits ENS to integrating with the global DNS namespace while preserving decentralization.

With this in mind, I’ve been exploring a concrete implementation of this model: the TLD Oracle.

How the TLD Oracle Would Work

Building off the recent integration of EIP-7951, I’ve developed a mock TLD oracle on Sepolia that demonstrates how this could work in practice.

Our system enforces strict separation across five layers:

Layer Contract Responsibility
DNS Verification DNSSECOracle Verifies DNSSEC cryptographic chains and returns authenticated DNS records.
Policy Enforcement TLDMinter Parses _ens.nic.tld TXT records for ownership claims, enforces DAO policy (timelock delays, rate limits, veto mechanisms), and calls Root to execute TLD assignment.
Veto Authority DAO Timelock / Security Council Can veto pending claims during the timelock window. Security Council veto expires and can be revoked; DAO retains permanent veto power.
Root Authority ENS Root Privileged gatekeeper that can write TLDs to the ENS Registry. Only authorized controllers (like TLDMinter) can call it.
State Storage ENS Registry Holds the canonical ownership state (node → owner mappings).

Execution Flow

submitClaim() ──► DNSSECOracle.verifyRRSet()
                      │
                      ▼
              TLDMinter stores pending request
                      │
                      ▼
            ┌─────────────────────┐
            │   TIMELOCK WINDOW   │◄─── veto() by DAO or Security Council
            └─────────────────────┘
                      │
                      ▼ (if not vetoed)
  execute() ──► Root.setSubnodeOwner()
                      │
                      ▼
              Registry.setSubnodeOwner(0x0, label, owner)
                      │
                      ▼
              Ownership recorded ✓

Demo: TLD Oracle

I’ve developed a live demo on Sepolia with testnet contracts that shows this model working end-to-end: EIP-7951 DNSSEC Solutions

The demo verifies _ens.nic.tld TXT records via DNSSEC using the P-256 precompile, then executes DNS-verified TLD assignment through a four-layer architecture:

Layer Role
DNSSECOracle Verifies DNSSEC cryptographic chains
TLDMinter Enforces DAO policy (timelock, rate limits, veto window)
ENS Root Gatekeeper that authorizes writes to the registry
ENS Registry Stores canonical TLD ownership

Example execution: https://sepolia.etherscan.io/tx/0xdbf45d11ae5e9e844b1aa8d554c3809d6a99eb4d52c6bac800fbdd7506b9cc47

This separation ensures DNS registries can claim their TLDs trustlessly while preserving ENS DAO sovereignty through veto mechanisms and timelocked execution.

Note: for this demo, we deployed mock ENS Root and Registry contracts on Sepolia to safely simulate root-level behavior.

Request for Red-teaming

I’m calling on the DAO to offer adversarial feedback on this model, both technically and operationally. Particularly interested in stress-testing:

  • Whether the separation between DNS as evidence and the DAO as authority is airtight
  • Failure modes around DNS compromise, oracle bugs, or policy misconfiguration
  • Whether the timelock, veto, and revocation mechanisms are sufficient
  • Any ways this design could unintentionally weaken ENS root sovereignty

The goal is to stimulate a collaborative environment where we can collectively find a scalable approach to TLD assignment ahead of the upcoming gTLD round, so the DAO has sufficient bandwidth to handle demand without compromising governance or sovereignty.

→ Repository: dnssec-solutions/TLD-oracle at master · eurekaetcetera/dnssec-solutions · GitHub

We actually used a model like this to start with - but were informed by DNS professionals that nic.tld is not globally reserved. It’s reserved for new-style gTLDs, but legacy ones (.com/.net/.org and others) and ccTLDs don’t have the same guarantee - meaning a third party could register nic.tld and take ownership of the entire TLD in ENS.

We could still use this system for new style gTLDs, but it would require an allowlist of TLDs we know adhere to the pattern of reserving nic for the operator.

2 Likes

News to me! Thank you for clarifying this, and I think it actually strengthens the scope of this programmable TLD assignment model.

It only makes sense where nic is structurally bound to the registry operator (i.e. in new-style gTLDs where it’s reserved for the registry operator). For new-style gTLDs, that’s a valid and enforceable invariant. For legacy gTLDs and ccTLDs, it clearly is not.

So we could tighten the scope and frame this as a programmable fast-path for TLDs that satisfy a known DNS policy profile (like reserved nic , or any future emergent invariants), with everything else à défaut continuing to go through explicit governance, as is done today with TLDs like .locker .

Absolutely — and that allowlist could be maintained via DAO governance, potentially as its own DNS governance registry, encoding which TLDs satisfy the invariants required for safe, automated onboarding (e.g., reserved nic , operator-controlled, DNSSEC-enforced).

Thinking ahead, this also aligns nicely with the upcoming gTLD application cycle. We can treat this as infra readiness for “reveal day”: once the new gTLD strings are published, the DAO can make a data-driven decision based on how many actually emerge that are relevant to ENS and its broader long-term goals (web3, crypto, identity, AI, etc.), and how many satisfy the invariants needed for automation.

If that number is meaningful, having a programmable TLD assignment model ready lets us avoid turning each compliant TLD into a bespoke governance event, while still keeping the DAO firmly in control of where automation is appropriate.

If this makes sense, it’d be helpful to sanity-check what the minimal DNS policy profile should look like (e.g. reserved nic , operator control, DNSSEC requirements) and whether others agree that this approach is best positioned as scoped infra readiness for the upcoming gTLD round.

1 Like

Update: I’ve built out the allowlist approach Nick described, framing it as a programmable fast-path for TLDs that will satisfy known DNS policy invariants.

TLDMinter v2 introduces a DAO-controlled allowlist encoding only TLDs where nic.tld is structurally reserved for the registry operator are eligible for automated onboarding.

New Execution Flow

submitClaim() ──► allowedTLDs[labelHash]?
                  │
                  ├── NO ──► revert TLDNotAllowed() ✗
                  │
                  ▼ YES
          DNSSECOracle.verifyRRSet()
                  │
                  ▼
          TLDMinter stores pending request
                  │
                  ▼
        ┌─────────────────────┐
        │   TIMELOCK WINDOW   │◄── veto() by DAO or Security Council
        └─────────────────────┘
                  │
                  ▼ (if not vetoed)
execute() ──► Root.setSubnodeOwner()
                  │
                  ▼
          Registry.setSubnodeOwner(0x0, label, owner)
                  │
                  ▼
          Ownership recorded ✓

How it works

The allowlist is seeded at deployment with 1,166 post-2012 ICANN New gTLD Program strings — sourced from the IANA root zone database, filtered to remove all 2-letter ccTLDs and 22 pre-2012 legacy gTLDs where the nic reservation doesn’t hold.

The check is the first thing that happens in submitClaim(), before DNSSEC verification — so non-qualifying TLDs fail fast without burning gas on proof verification:

// Step 1: Extract label hash and check allowlist (cheap, fail fast)

bytes32 labelHash = _extractLabelHash(name);

if (!allowedTLDs[labelHash]) revert TLDNotAllowed(labelHash);

// Step 2: Only then verify DNSSEC proof via oracle

(bytes memory data, uint32 inception) = oracle.verifyRRSet(proof);

Everything else goes through governance, as it does today

Legacy gTLDs and ccTLDs aren’t locked out — they follow the same governance path they would anyway. Adding a TLD like .com or .uk to the allowlist requires a DAO governance proposal. The oracle doesn’t replace governance for these cases; it just removes the bottleneck for the ~1,200 TLDs where automation is safe.

This maps to the DNS governance registry idea from the earlier discussion — the allowlist is effectively encoding which TLDs satisfy the minimal DNS policy profile (reserved nic, operator-controlled, DNSSEC-enforced) required for safe automated onboarding.

DNS proposes, ENS programmatically executes under DAO-defined law — the allowlist just defines which TLDs qualify for the fast path.

Tested on Sepolia

Test Result
.property claim (allowlisted, valid DNSSEC) Claim submitted successfully
.com claim (pre-2012, not on allowlist) Correctly rejected — TLDNotAllowed
.xyz (allowlisted, no DNS record yet) Passes allowlist, fails at DNSSEC — registry hasn’t published _ens.nic.xyz

Tested against a mock DNSSEC oracle on Sepolia that verifies real DNSSEC proof chains.

All existing safeguards (timelock, rate limiting, DAO/Security Council veto) remain unchanged.

Upcoming gTLD round

As mentioned earlier in this thread, this also positions us well for the next ICANN application cycle. The allowlist can be extended via batchAddToAllowlist() as new strings are delegated — the DAO decides which ones qualify, and the infrastructure is ready to onboard them without per-TLD governance events.

Asking for feedback

Would greatly appreciate a sanity check on the minimal DNS policy profile — whether reserved nic + DNSSEC-enforced is sufficient, or if there are additional invariants worth encoding.

All are welcome to review the source and stress-test the implementation.

2 Likes

@estmcmxci

Took you up on the stress-testing invite. I went through the full dnssec-solutions repo - TLDMinter v2, the DnssecP256Verifier, DnssecResolver, the Onchain DNS Import oracle, and the dns-claiming contracts.

On the policy side: the allowlist approach is the right call. The TLDMinter v2 itself is well put together - I tried to break the claim flow from several angles (multi-label injection, name comparison spoofing, rate limit boundary abuse, re-submission after veto) and it held up. The single-label enforcement, fail-fast allowlist check, and layered timelock/veto design are solid.

Where I’d focus attention before this gets closer to mainnet is the DNSSEC verification layer sitting underneath the TLDMinter. I found issues in how the DnssecP256Verifier chains proof steps together - specifically around how the answer proof’s signing key relates to the authenticated DNSKEY set. There are also some things worth looking at in the Onchain DNS Import oracle and the dns-claiming contracts.

I’d rather not get into the details on a public thread since some of it touches the proof verification logic pretty directly. I’ve got a writeup with code references and a Foundry PoC ready to go. Happy to share over a private repo, email, or DM whatever’s easiest.

Separately, I’ve been looking at the ens-contracts repo and have a couple of findings on the deployed ChainReverseResolver and L2ReverseRegistrar that are still open (flagged on PR #534). Related infrastructure so worth discussing together if you’re interested.

@nexusweb3dev

Update: After carefully reviewing the implementation, I decided against constructor seeding. Ethereum’s block gas limit was raised to 60M in late 2025 — which opened up room to seed the full allowlist through batch calls in a single onchain proposal, bringing the total gas cost to ~30.7M with ~48% headroom.

The suggested DNS policy profile held up under review. The allowlist check runs before DNSSEC verification — so non-qualifying TLDs fail immediately without touching the oracle. Legacy gTLDs and ccTLDs follow governance as they do today (governance proposal via Timelock).

The invariant holds for all 1,166 post-2012 strings in the initial set. More TLDs can be added to the allowlist via governance at a later time.

In order to stress test the implementation, I created two test suites:

  1. calldataCheck.t.sol — fork test against mainnet state, verifies the exact proposal calldata executes the expected outcome: TLDMinter deploys at a deterministic address, Root authorizes it, all 1,166 TLDs are allowlisted.
  2. ClaimSimulation.t.sol — no fork required. simulates the full post-deployment claim lifecycle using a mock DNSSEC oracle, covering the happy path, DAO veto, Security Council veto, and premature execution.

TLDMinter is deployed via CREATE2, producing a deterministic address that can be verified before the proposal executes. For the full reasoning on deployment structure, gas breakdown, and governance design, see RATIONALE.md

Happy to address any remaining questions on the governance structure or implementation before this moves forward.

Nice work on the test coverage - the calldataCheck fork test against mainnet state is a solid approach, and the ClaimSimulation covers the governance paths well.

The gap I found sits in the layer your tests mock out. ClaimSimulation uses a MockDNSSEC that returns whatever you load into it, which is the right call for testing the TLDMinter policy logic. But the real verification underneath - how DnssecP256Verifier chains the DNSKEY proof to the answer proof - is where the issues are. Your tests would pass fine with a broken verifier because they never exercise the actual proof validation.

Happy to share the details privately whenever works for you. Forum DM, email, private repo - whatever’s easiest.