Antler by Autoflux

Auth

Defines roles, access-control hierarchy, and permission gates across all modules.

Path: auth

Third-party documentation. This is independently authored analysis of the public Aurum Protocol codebase — not the official docs, and not reviewed or endorsed by the Aurum Protocol team.

Auth Module

Aurum uses a role-based access control (RBAC) model built on OpenZeppelin's AccessControl. Roles are defined once in the Auth module and imported by every other module via interface.

Role Hierarchy

RoleCapabilitiesAssigned to
DEFAULT_ADMIN_ROLEGrant / revoke all rolesGovernance timelock
OPERATOR_ROLEEmergency pause, param updatesMulti-sig 3-of-5
LIQUIDATOR_ROLEExecute liquidation auctionsWhitelisted keepers
ORACLE_UPDATER_ROLEPush off-chain price dataTrusted data providers

Pausing

Any address holding OPERATOR_ROLE can call pause() on any module. Paused modules revert all state-changing calls with a Pausable: paused error. Read-only functions remain accessible.

Upgrades

Proxy upgrades require a two-step process: (1) DEFAULT_ADMIN_ROLE proposes a new implementation, (2) a 48-hour timelock elapses before the upgrade is applied. This prevents unilateral rug-pull attacks.

Examples

Grant the liquidator role to a keeper bot

Grant the liquidator role to a keeper bot
typescript
const LIQUIDATOR_ROLE = await auth.LIQUIDATOR_ROLE();
await auth.grantRole(LIQUIDATOR_ROLE, keeperBotAddress);
console.log("Keeper authorised:", keeperBotAddress);
STATUSexample

Only the DEFAULT_ADMIN_ROLE (governance timelock) can call this.

Emergency pause from multi-sig

Emergency pause from multi-sig
typescript
// Called from the 3-of-5 multi-sig safe
await lendingModule.pause();
await vaultsModule.pause();
console.log("Protocol paused — investigating incident");
STATUSexample

Pause multiple modules simultaneously during a security incident.

Edge Cases

  • Revoking DEFAULT_ADMIN_ROLE from all accounts permanently locks the contract
  • pause() and unpause() are idempotent — calling when already paused does not revert
  • Role checks happen before any state mutation — a compromised non-admin account cannot escalate privileges

Interface

Interface
solidity
interface IAuth {
bytes32 constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 constant LIQUIDATOR_ROLE = keccak256("LIQUIDATOR_ROLE");
bytes32 constant ORACLE_UPDATER_ROLE = keccak256("ORACLE_UPDATER_ROLE");
 
/// @notice Returns true if account holds role
function hasRole(bytes32 role, address account) external view returns (bool);
 
/// @notice Grant role — caller must hold DEFAULT_ADMIN_ROLE
function grantRole(bytes32 role, address account) external;
 
/// @notice Revoke role — caller must hold DEFAULT_ADMIN_ROLE
function revokeRole(bytes32 role, address account) external;
 
/// @notice Pause all state-changing operations on this module
function pause() external; // requires OPERATOR_ROLE
 
/// @notice Resume operations after a pause
function unpause() external; // requires OPERATOR_ROLE
}
 
STATUSinterface