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:
-
Revoke RootSecurityController from Root
- Call
Root.setController(rootSecurityController, false) - Effect: RootSecurityController loses the ability to manage TLD ownership.
- Call
-
Transfer Base Registrar ownership back to the Timelock
- Call
BaseRegistrar.transferOwnership(ENS_DAO_Timelock) - Effect: RegistrarSecurityController is no longer the registrar owner.
- Call
-
(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.
- Call
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.
- Clone:
git clone https://github.com/blockful/dao-proposals.git - Checkout:
git checkout cf43a94 - 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.

