Skip to main content

AccessManager

The AccessManager contract (Solidity name NotareumAccessManager) is the single source of role and timelock authority for the Notareum protocol. Every other contract inherits from OpenZeppelin’s AccessManagedUpgradeable and defers role checks to this central manager. Consolidating authority here gives one auditable surface for every privileged operation in the system: who can call what function, on which contract, after which delay. Notareum uses OpenZeppelin’s AccessManager (v5.x API) directly with protocol-specific configuration; no custom forks.

Why a central manager

The older AccessControl pattern distributes role state across every contract. This is operationally costly: granting a cross-contract role change requires coordinated governance proposals on each contract, and changes to timelock semantics require contract-by-contract migration. AccessManager inverts the model:
  1. Every protected function declares a single uint64 roleId required to call it.
  2. AccessManager stores the mapping from (address accountOrContract, roleId) → membership and the mapping from (targetContract, selector) → requiredRoleId.
  3. Per-target delays are stored in the same contract.
  4. A single governance action can change role memberships, function targets, or delays across the entire protocol.

Defined roles

All roles except FEE_MANAGER are intended to be held by timelocked governance executors. FEE_MANAGER is held by the FeeManager contract address.

Delay schedule

Role grants, target function updates, and proxy upgrades all go through delays configured in AccessManager. Default delays: Governance proposals schedule operations through the manager; execution is permissionless after the delay elapses.

Function selector gating

For each protocol function that should be role-gated, AccessManager stores the required role:
The restricted modifier on each protocol function reads the selector and consults AccessManager.hasRole(currentRole(selector), msg.sender).

Integration pattern

A protected function on a downstream contract:
restricted resolves the required role for the current call via AccessManager and checks that msg.sender has it. No local role state is kept.

Governance cycle

The Governor contract is the only address granted all timelocked admin roles in production. Off-chain multisigs can hold subsets during bootstrap.

Emergency pause

A narrow subset of functions is pausable with delay 0 to respond to active incidents:
  • NotaRegistry.pause()
  • VerificationEngine.pause()
  • ValidatorStaking.pause()
Pause is an emergency-brake, not a governance action: it freezes mutations but does not drain or move any funds. Unpausing takes 24 hours via standard delay, which constrains the ability to abuse emergency access.

Reading role state

executionDelay > 0 indicates the account needs to schedule the call in advance rather than executing inline.

SDK helpers

Events

Standard OZ events:
Indexers subscribe to these events to maintain live dashboards of who can do what, pending operations, and delay changes.

Security posture

  1. Single manager, many targets. Compromise of AccessManager compromises the stack. Its upgrade path is gated by itself with a 14-day delay: a malicious upgrade must survive 14 days of observation and governance intervention.
  2. No address-based back doors. No contract holds an owner field bypassing the manager. Every privileged path flows through restricted + AccessManager.
  3. Timelocks are non-negotiable. Delays are part of the role definition; granting a role does not grant instant execution.
  4. Public scheduling. Every scheduled operation is visible on-chain via OperationScheduled events before execution.

Invariants

  1. Every restricted function maps to exactly one role in AccessManager.
  2. Execution of a scheduled operation requires block.timestamp >= schedule.
  3. Proxy upgrades cannot be executed without the UPGRADER role, and the role is held only by timelocked governance.
  4. The manager itself can be upgraded only through the same role and delay it enforces for others.