The Authority component gates every setter on an account (policy setters, metadata setters, pausable manager, and more) through a single chokepoint, assert_authorized. There is currently no way to disable that entire surface in one operation. This issue proposes a global closed flag on Authority so the owner can atomically block all authority-gated procedures, an emergency switch for the account's management surface.
A common access-control pattern is the ability to freeze a contract's whole restricted surface in a single call, regardless of role membership, as an emergency measure. We have no equivalent.
Note that Pausable does not cover this: it only gates the functional execute paths (mint/burn/transfer), not the admin setters. Concretely:
So while paused, a role/owner can still rewrite the mint policy. Pause freezes value flow, it does not freeze configuration. The two are complementary, and the "freeze configuration" half is missing.
Exists:
Authority is the single gate every setter passes through via assert_authorized.
- The value slot is
[authority, 0, 0, 0]
- Owner checks are already in-module (
authority.masm imports ownable2step).
Missing:
- Any way to disable all authority-gated procedures at once.
Design
We can put a flag on Authority: assert_authorized is already the chokepoint, so the check lives there with zero changes to the setters.
Storage becomes
[authority, target_closed, 0, 0]
Runtime (authority.masm):
- At the top of
assert_authorized, panic with a new ERR_AUTHORITY_CLOSED, blocking every gated procedure in all modes before any role/owner dispatch.
- Add
set_target_{closed/opened}) gated directly on ownable2step::assert_sender_is_owner_internal, not routed through assert_authorized.
open flag must bypass the closed check. Otherwise, close → assert_authorized rejects everyone → open is uncallable → account permanently bricked. Gating open/close on the owner check directly guarantees the owner can always reopen.
The scope is for OwnerControlled / RbacControlled (both install Ownable2Step) as AuthControlled has no owner, so the switch is out of scope there.
The
Authoritycomponent gates every setter on an account (policy setters, metadata setters, pausable manager, and more) through a single chokepoint,assert_authorized. There is currently no way to disable that entire surface in one operation. This issue proposes a globalclosedflag onAuthorityso the owner can atomically block all authority-gated procedures, an emergency switch for the account's management surface.A common access-control pattern is the ability to freeze a contract's whole restricted surface in a single call, regardless of role membership, as an emergency measure. We have no equivalent.
Note that
Pausabledoes not cover this: it only gates the functional execute paths (mint/burn/transfer), not the admin setters. Concretely:So while paused, a role/owner can still rewrite the mint policy. Pause freezes value flow, it does not freeze configuration. The two are complementary, and the "freeze configuration" half is missing.
Exists:
Authorityis the single gate every setter passes through viaassert_authorized.[authority, 0, 0, 0]authority.masmimportsownable2step).Missing:
Design
We can put a flag on
Authority:assert_authorizedis already the chokepoint, so the check lives there with zero changes to the setters.Storage becomes
Runtime (
authority.masm):assert_authorized, panic with a newERR_AUTHORITY_CLOSED, blocking every gated procedure in all modes before any role/owner dispatch.set_target_{closed/opened}) gated directly onownable2step::assert_sender_is_owner_internal, not routed throughassert_authorized.openflag must bypass the closed check. Otherwise,close→assert_authorizedrejects everyone →openis uncallable → account permanently bricked. Gatingopen/closeon the owner check directly guarantees the owner can always reopen.The scope is for
OwnerControlled/RbacControlled(both installOwnable2Step) asAuthControlledhas no owner, so the switch is out of scope there.