Skip to main content
Governance owns the controller. Protocol-admin changes are scheduled as typed AdminOperation values and executed after the timelock delay.

Roles

Entry points

Immediate (non-timelocked) entrypoints

These bypass the delay because they can only make the protocol safer, or because they repair governance itself:
revoke_role_immediate is not a general break-glass. It is owner-gated and can only strip GUARDIAN or ORACLE. You cannot use it to remove a PROPOSER, EXECUTOR, or CANCELLER — those go through RevokeGovRole on the timelock.

How executor works

execute, execute_self, and execute_canceller_reset all take executor: Option<Address>:
  • Some(address) — that address must authorize the call and hold EXECUTOR.
  • None — no executor check runs, so execution is open to anyone.
The operation still has to be ready and unexpired either way. None widens who may press the button, never what the button does.

AdminOperation variants

Controller-targeted: Governance-self, executed through execute_self: UpgradeGov(hash), UpdateGovDelay(ledgers), GrantGovRole, RevokeGovRole, TransferGovOwnership.
There is no token-approval operation, no spoke-deprecation operation (RemoveSpoke sets the deprecation flag), and no pool-template registration — DeployPool and UpgradePool take the Wasm hash directly.

Execution model

Controller-targeted operations run through execute, which forwards the call to the controller and returns its result. Governance-self operations run through execute_self instead. They use typed inline execution because Soroban does not allow a contract to make the generic self-call that execute relies on. Testing-only immediate forwarders are gated behind #[cfg(any(test, feature = "testing"))]. They are not part of the production admin path and are not present in a deployed build.