MellowACL
Purpose
MellowACL is a lightweight but extendable access control layer that wraps OpenZeppelin’s AccessControlEnumerableUpgradeable. It introduces automatic tracking and enumeration of active roles to improve governance transparency.
This contract is intended to be inherited by modules that require dynamic role management and storage-isolated initialization.
Responsibilities
Grant and revoke access control roles to addresses
Keep track of all active (i.e., assigned) roles in a dedicated set
Expose enumerable functions for external auditing of granted roles
Emit structured events when roles are added or fully revoked
Storage Layout
struct MellowACLStorage {
EnumerableSet.Bytes32Set supportedRoles;
}supportedRoles: A unique set of role identifiers (bytes32) currently assigned to any addressUses a dedicated storage slot derived from:
SlotLibrary.getSlot("MellowACL", name_, version_)View Functions
supportedRoles() → uint256
supportedRoles() → uint256Returns the number of currently active roles (i.e., roles with at least one member).
supportedRoleAt(index: uint256) → bytes32
supportedRoleAt(index: uint256) → bytes32Returns the role identifier at the specified index from the active role set.
hasSupportedRole(role: bytes32) → bool
hasSupportedRole(role: bytes32) → boolReturns true if the role is currently active (i.e., assigned to at least one account).
Internal Logic
_grantRole(role: bytes32, account: address) → bool
_grantRole(role: bytes32, account: address) → boolGrants the specified role to an account. If the role was not previously active, it is added to supportedRoles, and RoleAdded is emitted.
Inherits from
AccessControlUpgradeable._grantRoleEmits:
event RoleAdded(bytes32 indexed role)
_revokeRole(role: bytes32, account: address) → bool
_revokeRole(role: bytes32, account: address) → boolRevokes the specified role from an account. If the role has no remaining members afterward, it is removed from supportedRoles, and RoleRemoved is emitted.
Inherits from
AccessControlUpgradeable._revokeRoleEmits:
event RoleRemoved(bytes32 indexed role)
Constructor
constructor(string memory name_, uint256 version_)Computes a deterministic storage slot using
SlotLibraryDisables initializer to prevent accidental direct deployment
Should be initialized later via proxy-aware module constructor
Events
event RoleAdded(bytes32 indexed role)Emitted when a new role is introduced into the system
event RoleRemoved(bytes32 indexed role)Emitted when the last holder of a role is revoked and the role becomes inactive