Tokenized RWAs OFT distributes roles across four contract boundaries: the Nexus OApp, the external modules, the token (NexusERC20), and the guard (NexusERC20Guard). All role management uses AccessControl2StepUpgradeable with two-step admin transfer.
Nexus
| Role | Source | Used For |
|---|
DEFAULT_ADMIN_ROLE | AccessControl2StepUpgradeable | setPeer, setEnforcedOptions, setMsgInspector, setFeeDeposit, setPauseModule, setFeeConfigModule, setRateLimiterModule, delegate operations |
TOKEN_REGISTRAR_ROLE | OFTRegistryRBACUpgradeable | registerToken, deregisterToken |
Module roles (FEE_CONFIG_MANAGER_ROLE, PAUSER_ROLE, UNPAUSER_ROLE, RATE_LIMITER_MANAGER_ROLE) are also granted on Nexus but consumed by the modules via onlyNexusRole / _checkRole.
DEFAULT_ADMIN_ROLE is synchronized with delegate. The setDelegate function always reverts.
NexusOFT
No roles. Access is restricted by the onlyNexus modifier — only the Nexus contract can call nexusReceive.
Nexus Fee Config Module
| Role | Source | Used For |
|---|
FEE_CONFIG_MANAGER_ROLE | Declared locally, checked on Nexus via onlyNexusRole | setFeeBps |
Nexus Pause Module
| Role | Source | Used For |
|---|
PAUSER_ROLE | Declared locally, checked on Nexus via _checkRole | setPaused (when pausing or strengthening a pause config) |
UNPAUSER_ROLE | Declared locally, checked on Nexus via _checkRole | setPaused (when unpausing, weakening, or no-op) |
Nexus Rate Limiter Module
| Role | Source | Used For |
|---|
RATE_LIMITER_MANAGER_ROLE | Declared locally, checked on Nexus via onlyNexusRole | setRateLimitGlobalConfig, setRateLimitConfigs, setRateLimitStates, setRateLimitAddressExemptions, checkpointRateLimits, setScales |
NexusERC20
| Role | Source | Used For |
|---|
DEFAULT_ADMIN_ROLE | AccessControl2StepUpgradeable | setGuard, recoverFunds |
MINTER_ROLE | Declared locally | mint |
BURNER_ROLE | Declared locally | burn |
NexusERC20Guard
| Role | Source | Used For |
|---|
DEFAULT_ADMIN_ROLE | AccessControl2StepUpgradeable | Admin transfer, set allowlist mode |
BLACKLISTER_ROLE | AllowlistRBACUpgradeable | Blacklist addresses |
WHITELISTER_ROLE | AllowlistRBACUpgradeable | Whitelist addresses |
PAUSER_ROLE | PauseByIDRBACUpgradeable | setDefaultPaused (when pausing), setPaused (when effectively pausing by token address as ID) |
UNPAUSER_ROLE | PauseByIDRBACUpgradeable | setDefaultPaused (when unpausing), setPaused (when effectively unpausing or no-op) |
Role Separation Principles
- Module swapping vs module configuration — Only
DEFAULT_ADMIN_ROLE can change which module contract is active. Module-specific roles (FEE_CONFIG_MANAGER_ROLE, PAUSER_ROLE, etc.) can only configure the current module.
- Pause / Unpause — Split across two roles. A compromised pauser key can halt transfers (disruptive, but funds remain safe) but cannot re-enable them.
- Token registration — Separate from admin.
TOKEN_REGISTRAR_ROLE cannot change module addresses or grant other roles.
- Nexus roles vs guard roles — Module roles live on the Nexus contract. Guard roles (allowlist, token-level pause) live on the guard contract. These are independent access control hierarchies.
- Fee configuration vs fee collection —
FEE_CONFIG_MANAGER_ROLE sets BPS rates. Fees are pushed to feeDeposit automatically — there is no withdrawal function.
Next Steps