[Executable] Enable Root and Registrar Security Controllers

Contracts were verified and tested, achieving the intended outcome. Here is some documentation to help understanding better this change and next steps to test the calldata.


What Changes in Practice

  • Before: only the DAO timelock can remove registrar controllers or change
    root controller status, requiring a full proposal cycle.

  • After: the security council can immediately disable a compromised
    registrar controller or TLD, while the DAO retains full governance control
    over long-term configuration.

Some visual documentation, as suggested above by @Premm.eth.

Scope of Authority

RootSecurityController (owned by Security Council Multisig)

Enables emergency TLD shutdown:

  • disableTLD(label) — takes ownership of a TLD and clears its resolver

This allows the security council to rapidly disable compromised or vulnerable
TLDs without waiting for a full DAO vote.

RegistrarSecurityController (owned by ENS DAO Timelock)

Preserves DAO governance over .eth while enabling emergency controller shutdown:

DAO (Owner)

  • addRegistrarController(address)
  • removeRegistrarController(address)
  • setRegistrarResolver(address)
  • transferRegistrarOwnership(address)

Security Council (Controller)

  • disableRegistrarController(address) — emergency removal only

Rollback Plan (Return to “Before” State)

If the DAO decides to revert to the original model, it can
execute the following actions via the ENS DAO Timelock:

  1. Revoke RootSecurityController from Root

    • Call Root.setController(rootSecurityController, false)
    • Effect: RootSecurityController loses the ability to manage TLD ownership.
  2. Transfer Base Registrar ownership back to the Timelock

    • Call BaseRegistrar.transferOwnership(ENS_DAO_Timelock)
    • Effect: RegistrarSecurityController is no longer the registrar owner.
  3. (Optional) Remove Security Council controller permissions

    • Call RegistrarSecurityController.setController(securityCouncilMultisig, false)
    • Effect: Security council can no longer disable registrar controllers.
    • Preference: Step 2 already removes the controller’s authority by restoring
      timelock ownership of the registrar, which avoids accumulating legacy
      permissioned contracts in the execution path.

After these steps, control returns to the pre-proposal state where only the DAO
timelock can manage registrar controllers and root permissions.

Verifying locally

Source code available here.

  1. Clone: git clone https://github.com/blockful/dao-proposals.git
  2. Checkout: git checkout cf43a94
  3. Run: forge test --match-path "src/ens/proposals/ep-enable-security-controllers/*" -vv

Next steps

As we don’t have the contract addresses of RegistrarSecurityController and RootSecurityController, we could not create a Tally draft, neither recommend a calldata. Once the draft is ready, we’ll proceed to check the calldata.

2 Likes