AccessManagerLib
Title: AccessManagerLib
Author: Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/manager/AccessManager.sol)
Logic for IAccessManager.
Constants
ADMIN_ROLE
uint64 internal constant ADMIN_ROLE = 0;PUBLIC_ROLE
uint64 internal constant PUBLIC_ROLE = type(uint64).max;EXPIRATION
Scheduled operations expire after this many seconds past readyAt.
uint32 internal constant EXPIRATION = 1 weeks;MIN_SETBACK
Minimum setback applied when changing delays.
uint32 internal constant MIN_SETBACK = 5 days;Functions
accessManagerStorage
function accessManagerStorage() internal pure returns (AccessManagerStorage storage $);Returns
| Name | Type | Description |
|---|---|---|
| $ | AccessManagerStorage |
__AccessManager_init
function __AccessManager_init(address initialAdmin) internal;Parameters
| Name | Type | Description |
|---|---|---|
| initialAdmin | address |
registerInterface
function registerInterface() internal;hashOperation
function hashOperation(address caller, address target, bytes calldata data) internal pure returns (bytes32);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bytes32 |
hasRole
function hasRole(uint64 roleId, address account) internal view returns (bool isMember, uint32 executionDelay);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address |
Returns
| Name | Type | Description |
|---|---|---|
| isMember | bool | |
| executionDelay | uint32 |
getAccess
OZ Time.Delay.getFull: a pending execution delay already in force is reported as the current one,
with nothing pending.
function getAccess(uint64 roleId, address account)
internal
view
returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address |
Returns
| Name | Type | Description |
|---|---|---|
| since | uint48 | |
| currentDelay | uint32 | |
| pendingDelay | uint32 | |
| effect | uint48 |
getRoleAdmin
function getRoleAdmin(uint64 roleId) internal view returns (uint64);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint64 |
getRoleGuardian
function getRoleGuardian(uint64 roleId) internal view returns (uint64);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint64 |
getRoleGrantDelay
function getRoleGrantDelay(uint64 roleId) internal view returns (uint32);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint32 |
getRoleMembers
function getRoleMembers(uint64 roleId) internal view returns (address[] memory);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address[] |
getRoleMemberCount
function getRoleMemberCount(uint64 roleId) internal view returns (uint256);Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint256 |
getTargetFunctionRole
function getTargetFunctionRole(address target, bytes4 selector) internal view returns (uint64);Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| selector | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint64 |
getTargetAdminDelay
function getTargetAdminDelay(address target) internal view returns (uint32);Parameters
| Name | Type | Description |
|---|---|---|
| target | address |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint32 |
isTargetClosed
function isTargetClosed(address target) internal view returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| target | address |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
canCall
Whether caller may call selector on target now (immediate) or after scheduling (delay).
The manager itself is an authorized caller only while execute is calling that exact
(target, selector), so a managed target accepts manager-driven calls without any target-side flag.
function canCall(address caller, address target, bytes4 selector)
internal
view
returns (bool immediate, uint32 delay);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| target | address | |
| selector | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| immediate | bool | |
| delay | uint32 |
getSchedule
Returns the timestamp at which operationId becomes (or became) executable.
Returns 0 in three distinct cases:
- The operation was never scheduled (
getNonce(operationId) == 0). - The operation was consumed (executed successfully).
- The operation was scheduled but has since expired (
readyAt + EXPIRATION <= now). Callers that need to distinguish case 1 from cases 2/3 should additionally callgetNonce(operationId): a non-zero nonce means the operation existed at some point.
function getSchedule(bytes32 operationId) internal view returns (uint48);Parameters
| Name | Type | Description |
|---|---|---|
| operationId | bytes32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 |
getNonce
function getNonce(bytes32 operationId) internal view returns (uint32);Parameters
| Name | Type | Description |
|---|---|---|
| operationId | bytes32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint32 |
grantRole
function grantRole(uint64 roleId, address account, uint32 executionDelay) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address | |
| executionDelay | uint32 |
revokeRole
function revokeRole(uint64 roleId, address account) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address |
renounceRole
function renounceRole(uint64 roleId, address callerConfirmation) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| callerConfirmation | address |
setRoleAdmin
function setRoleAdmin(uint64 roleId, uint64 admin) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| admin | uint64 |
setRoleGuardian
function setRoleGuardian(uint64 roleId, uint64 guardian) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| guardian | uint64 |
setGrantDelay
function setGrantDelay(uint64 roleId, uint32 newDelay) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| newDelay | uint32 |
labelRole
function labelRole(uint64 roleId, string calldata label) internal;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| label | string |
setTargetFunctionRole
function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) internal;Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| selectors | bytes4[] | |
| roleId | uint64 |
setTargetAdminDelay
function setTargetAdminDelay(address target, uint32 newDelay) internal;Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| newDelay | uint32 |
setTargetClosed
function setTargetClosed(address target, bool closed) internal;Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| closed | bool |
schedule
function schedule(address target, bytes calldata data, uint48 when)
internal
returns (bytes32 operationId, uint32 nonce);Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| data | bytes | |
| when | uint48 |
Returns
| Name | Type | Description |
|---|---|---|
| operationId | bytes32 | |
| nonce | uint32 |
execute
OZ semantics: a delayed caller spends its matured schedule, and an available schedule is spent even
when no delay is enforced any more. With nothing to spend, it emits no IAccessManager.OperationExecuted
and returns 0. A call to this manager itself is checked by _canCallSelf.
function execute(address target, bytes calldata data) internal returns (uint32 nonce);Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| nonce | uint32 |
cancel
function cancel(address caller, address target, bytes calldata data) internal returns (uint32 nonce);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| nonce | uint32 |
consumeScheduledOp
function consumeScheduledOp(address caller, bytes calldata data) internal;Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| data | bytes |
updateAuthority
Points managed target at newAuthority. Reverts unless the caller holds ADMIN_ROLE (having
scheduled the call when target has an admin delay) and this manager is target's current authority.
As in OZ, the admin delay binds this path only. execute(target, setAuthority(x)) is gated by target's
function role for setAuthority, which defaults to ADMIN_ROLE, so an admin can migrate at once that way.
For the admin delay to guard migration, map target's setAuthority selector to a role nobody holds
(setTargetFunctionRole); changing that mapping back is itself held back by the admin delay.
function updateAuthority(address target, address newAuthority) internal;Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| newAuthority | address |
_hashExecutionId
function _hashExecutionId(address target, bytes4 selector) private pure returns (bytes32);Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| selector | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bytes32 |
_consumeScheduledOp
Spends the scheduled operationId, reverting unless it is scheduled, ready and not expired.
function _consumeScheduledOp(bytes32 operationId) private returns (uint32 nonce);Parameters
| Name | Type | Description |
|---|---|---|
| operationId | bytes32 |
Returns
| Name | Type | Description |
|---|---|---|
| nonce | uint32 |
_isExpired
OZ _isExpired: an operation ready at readyAt expires at readyAt + EXPIRATION, that second included.
function _isExpired(uint48 readyAt) private view returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| readyAt | uint48 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
_effectiveDelay
function _effectiveDelay(Delay storage d) private view returns (uint32);Parameters
| Name | Type | Description |
|---|---|---|
| d | Delay |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint32 |
_updateEffectAt
OZ Time.Delay.withUpdate's effect time: a change from currentDelay to newDelay waits out the
decrease (currentDelay - newDelay, nothing for an increase), and at least minSetback.
function _updateEffectAt(uint32 currentDelay, uint32 newDelay, uint32 minSetback) private view returns (uint48);Parameters
| Name | Type | Description |
|---|---|---|
| currentDelay | uint32 | |
| newDelay | uint32 | |
| minSetback | uint32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint48 |
_grantRoleInternal
OZ _grantRole. A new member joins after the role's grant delay, and the event's since is that time.
An existing member keeps since and gets delay.withUpdate(executionDelay, 0): an increase applies at
once, a decrease after the difference, and the event's since is when the new delay takes effect.
The new value replaces any pending one, measured from the delay in force.
function _grantRoleInternal(uint64 roleId, address account, uint32 executionDelay) private;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address | |
| executionDelay | uint32 |
_revokeRoleInternal
function _revokeRoleInternal(uint64 roleId, address account) private;Parameters
| Name | Type | Description |
|---|---|---|
| roleId | uint64 | |
| account | address |
_checkAuthorized
OZ onlyAuthorized: gates this manager's own restricted functions on the current call (msg.data).
A caller whose required delay (_getAdminRestrictions) is non-zero must have scheduled this exact call
against this manager, and the matured schedule is consumed here. The manager itself passes only while
execute is running this selector. Only the facet entrypoint of the same name may reach a restricted
library function, so that msg.data is the call being authorized.
function _checkAuthorized() private;_getAdminRestrictions
OZ _getAdminRestrictions: whether data calls one of this manager's restricted functions, the role
that may call it, and the operation delay it carries on top of the caller's execution delay. Target
configuration and updateAuthority carry the target's admin delay; grantRole and revokeRole are
restricted to the role's admin. Any other selector falls back to this contract's own target roles.
function _getAdminRestrictions(bytes calldata data)
private
view
returns (bool adminRestricted, uint64 roleId, uint32 operationDelay);Parameters
| Name | Type | Description |
|---|---|---|
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| adminRestricted | bool | |
| roleId | uint64 | |
| operationDelay | uint32 |
_canCallExtended
OZ _canCallExtended: canCall, except that a call to this manager is checked by _canCallSelf.
function _canCallExtended(address caller, address target, bytes calldata data)
private
view
returns (bool immediate, uint32 delay);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| immediate | bool | |
| delay | uint32 |
_canCallSelf
OZ _canCallSelf: canCall for a call to this manager, applying _getAdminRestrictions. The closed
flag binds only selectors that are not admin-restricted, and the required delay is the larger of the
operation delay and the caller's execution delay.
function _canCallSelf(address caller, bytes calldata data) private view returns (bool immediate, uint32 delay);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| immediate | bool | |
| delay | uint32 |
_requiredRole
The role reported when caller may not call data on target at all.
function _requiredRole(address target, bytes calldata data) private view returns (uint64 roleId);Parameters
| Name | Type | Description |
|---|---|---|
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| roleId | uint64 |
_checkCanSchedule
Validates that caller may schedule a call to target with data and returns
the required execution delay. Reverts if the caller has no access at all or has
immediate access (no schedule needed).
function _checkCanSchedule(address caller, address target, bytes calldata data)
private
view
returns (uint32 delay);Parameters
| Name | Type | Description |
|---|---|---|
| caller | address | |
| target | address | |
| data | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| delay | uint32 |
_writeSchedule
Writes the scheduled operation to storage and returns the assigned nonce and the effective (clamped) schedule timestamp.
function _writeSchedule(bytes32 operationId, uint48 when, uint32 delay)
private
returns (uint32 nonce, uint48 effectiveWhen);Parameters
| Name | Type | Description |
|---|---|---|
| operationId | bytes32 | |
| when | uint48 | |
| delay | uint32 |
Returns
| Name | Type | Description |
|---|---|---|
| nonce | uint32 | |
| effectiveWhen | uint48 |