Tokenholders decide. The system waits. Execution happens only after the timelock window.
Nine signers coordinate offchain, sign through the Safe, and call the UpgradeExecutor directly.
Proposal creation, vote counting, delegated ARB balance lookup, quorum, and timelock control all compose in one governor.
GovernorPreventLateQuorumUpgradeable extends voting if quorum is hit at the deadline. EXCLUDE_ADDRESS keeps locked treasury/Foundation tokens out of quorum math.
contract L2ArbitrumGovernor is GovernorSettingsUpgradeable, GovernorVotesUpgradeable, GovernorTimelockControlUpgradeable, GovernorVotesQuorumFractionUpgradeable, GovernorPreventLateQuorumUpgradeable // quorum denominator excludes non-voting pools getPastCirculatingSupply(blockNumber)
// every normal proposal waits at least this long uint256 private _arbMinDelay; function getMinDelay() public view override returns (uint256 duration) { return _arbMinDelay; }
Users get time to inspect scheduled changes and exit if they disagree with the governance outcome.
During a live exploit, the same delay can leave the protocol watching damage happen while the official fix waits.
updateDelay() is restricted so a malicious proposal cannot simply compress the delay to zero.
If the executor is on L1, the call can target the L1 UpgradeExecutor directly.
If the executor is on another L2, the call is wrapped as a retryable ticket using the magic address.
The Security Council emergency route does not use this builder. It signs through the Safe and calls the UpgradeExecutor directly.
address constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C; // if target == magic address: // package calldata as bridge retryable ticket // if inbox == address(0): // execute on L1 directly
perform() calls inbox().pause(). It freezes new L1-to-L2 submissions without moving funds.
ProxyAdmin.upgrade() points a proxy at new logic while preserving state.
A signed payload can bundle multiple operations into one atomic intervention when a pause is not enough.
getOwners() // all 12 members getThreshold() // 9 in production isModuleEnabled(module) addOwnerWithThreshold(owner, threshold) removeOwner(prevOwner, owner, threshold) execTransactionFromModule(to, value, data, op)
Anyone can start the election window and contenders register with EIP-712 signatures.
nomineeVetter can exclude or include nominees for compliance and safety.
SecurityCouncilManager replaces six members at a time.
Membership updates travel through the standard route, not the emergency bypass.
SecurityCouncilMemberSyncAction reconciles owners and preserves the threshold.
The council path can pause, patch, or dispatch custom execution while normal DAO governance would still be waiting.
Elections, member sync, quorum math, and timelocks keep emergency authority connected to DAO process.
Human keys, Foundation vetting, legal pressure, and role compromise become part of the protocol's attack surface.