We verified the vote script and all sixteen DelegationContracts on-chain before voting:
nine oracle seats, six DSM guardians, and the depositor bot’s contract, which takes over
TOP_UP_ROLE in the same script. Everything matches the published plan and the custody
policy. Thanks for the level of preparation here: the published tables, the operator
checklists and the verification guide made this vote unusually easy to check. The
question below is not about the implementation but about one part of the model that we
may be missing.
It concerns the case where what is compromised is not a hot key but the owner multisig
itself. TheDZhon made the point earlier in this thread that terminate() lets a
participant cut itself off rather than having the protocol pause components around a
party it no longer trusts. We agree, and our question is about the narrower case where
the owner is no longer in a position to make that call. terminate() is invoked by the
owner, as are revokeDelegate() and nominateDelegate(). While a single signer is
compromised this works, because the remaining honest quorum still controls the Safe.
Once the threshold itself is taken, the operator can do nothing, and §6.2 of the policy
no longer covers the case.
From there governance has to act. The LIP-37 specification describes the cooldown in
exactly those terms: a hostile nomination is visible on-chain for the whole window, so
monitoring and governance can react before the swap takes effect. The custody policy in
§3.6 calls the same window the owner’s only window to react, which is noticeably more
modest.
We tried to work out what governance can actually do within those 48 hours, and so far
the answer seems to be nothing. We checked the roles on the four HashConsensus contracts:
- MANAGE_MEMBERS_AND_QUORUM_ROLE is held only by the Aragon Agent
- DISABLE_CONSENSUS_ROLE has no holders at all, zero on all four committees
- MANAGE_FRAME_CONFIG_ROLE is empty as well
CircuitBreaker covers the Withdrawal Queue, VEBO, TWG, VaultHub and Predeposit Guarantee,
but not the HashConsensus contracts or the Accounting Oracle. Emergency Brakes holds
PAUSE_ROLE over Easy Track. The Dual Governance emergency committees are scoped to
vulnerabilities in the DG contracts themselves, not to changing committee membership.
That leaves a full Aragon vote through the Agent plus the Dual Governance timelock,
roughly ten days. This is the same figure LIP-37 names in its motivation as the problem
EDF was created to solve. So the window lasts 48 hours while the fastest available
response is five times longer.
There is also a faster version of the same problem. An attacker holding owner multisigs
does not need to nominate anything: revokeDelegate() and terminate() both take effect
immediately. Five disabled oracle seats leave four signers against a quorum of five, and
because each operator’s contract sits in all four committees, consensus stops in all of
them at once. Here there is no 48-hour window at all. Restoring service means either
lowering the quorum or replacing members, both of which run through
MANAGE_MEMBERS_AND_QUORUM_ROLE and therefore through a full vote; with terminate() it
also means deploying a new contract per seat. Even a single terminated seat is
unrecoverable without a vote.
These are two different failure modes and they need two different primitives. Against a
hostile majority, disableConsensus() freezes the committee by raising the quorum out of
reach. But DISABLE_CONSENSUS_ROLE is held by nobody, and granting it goes through the
Agent, which means a vote again. It becomes a fast brake only if it sits in advance with
a committee that can act within hours. Against disabled seats it does not help at all,
since consensus has already stopped and freezing it further changes nothing. Recovery
needs removeMember or setQuorum, a far more sensitive role to hand to a fast-moving
committee.
DSM guardians do not have this problem, since any honest guardian can halt deposits with
a single signature, and that is built into the design as protection against collusion.
For oracle seats we could not find an equivalent emergency path. Are we right that until
removal through governance, the only containment mechanism at the HashConsensus level is
the 5-of-9 quorum? We do take downstream limits such as the OracleReportSanityChecker
into account, but they bound what a report may contain rather than allow a compromised
committee member to be removed or disabled.
We deliberately do not go into how an owner multisig might be compromised. The method
does not matter here: custody requirements raise the cost but do not guarantee it will
not happen.
None of these questions changes our support for the vote. Holding a protocol permission
directly on a hot key that cannot be replaced quickly without governance is worse on
every one of these counts. We are not proposing to redesign anything. We would like the
response path for a threshold compromise of an owner multisig to be defined in advance:
who neutralises a compromised oracle seat, and by what mechanism, when the owner is
already lost and the normal governance process does not fit inside the 48-hour cooldown.