Hi kbryan, great question to ask before Final. I replayed it on the deployed contracts at block 26,175,900, then on a fork, with real names as witnesses. Your controllerOf matches the chain, with two edges.
| Wrapped name, who can manage it | setResolver | new subname | transfer |
|---|---|---|---|
owner, or operator via setApprovalForAll |
yes | yes | yes |
approved via approve |
no | no | no |
| anyone after the name was transferred | no | no | no |
Fuses block exactly what they say, and a transfer clears the per-name approval unless CANNOT_APPROVE is burned. Unwrapped names: ENS.owner and the registry operator.
The two edges:
• An unemancipated wrapped subname keeps its owner and setResolver after expiry. “address(0) once expired” holds for emancipated names.
• In the 90-day grace period, controllerOf returns the holder while the NameWrapper refuses all management (canModifyName is false).
ENSv2, measured on a fork with the stage-4 role: an operator can migrate a wrapped name and become its v2 owner, after which controllerOf returns the Graveyard as you expect. Graveyard.clear has no admin and anyone can call it; it reverts on active, in-grace and locked names, and agent subnames under a migrated parent stay manageable until someone clears them.
Calls to rerun: The holder of a role is not always the one who executes it: one measured case
Would it make sense for controllerOf to also require canModifyName, so a name loses trust authority the moment it loses ENS management?