Access Control
This document is better viewed at https://docs.openzeppelin.com/contracts/api/access |
This directory provides ways to restrict who can access the functions of a contract or when they can do it.
-
AccessManager
is a full-fledged access control solution for smart contract systems. Allows creating and assigning multiple hierarchical roles with execution delays for each account across various contracts. -
AccessManaged
delegates its access control to an authority that dictates the permissions of the managed contract. It’s compatible with an AccessManager as an authority. -
AccessControl
provides a per-contract role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts within the same instance. -
Ownable
is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it.
Core
Ownable
import "@openzeppelin/contracts/access/Ownable.sol";
Contract module which provides a basic access control mechanism, where there is an account (an owner) that can be granted exclusive access to specific functions.
The initial owner is set to the address provided by the deployer. This can
later be changed with transferOwnership
.
This module is used through inheritance. It will make available the modifier
onlyOwner
, which can be applied to your functions to restrict their use to
the owner.
constructor(address initialOwner)
internal
Initializes the contract setting the address provided by the deployer as the initial owner.
renounceOwnership()
public
Leaves the contract without owner. It will not be possible to call
onlyOwner
functions. Can only be called by the current owner.
Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner. |
transferOwnership(address newOwner)
public
Transfers ownership of the contract to a new account (newOwner
).
Can only be called by the current owner.
_transferOwnership(address newOwner)
internal
Transfers ownership of the contract to a new account (newOwner
).
Internal function without access restriction.
Ownable2Step
import "@openzeppelin/contracts/access/Ownable2Step.sol";
Contract module which provides access control mechanism, where there is an account (an owner) that can be granted exclusive access to specific functions.
This extension of the Ownable
contract includes a two-step mechanism to transfer
ownership, where the new owner must call acceptOwnership
in order to replace the
old one. This can help prevent common mistakes, such as transfers of ownership to
incorrect accounts, or to contracts that are unable to interact with the
permission system.
The initial owner is specified at deployment time in the constructor for Ownable
. This
can later be changed with transferOwnership
and acceptOwnership
.
This module is used through inheritance. It will make available all functions from parent (Ownable).
transferOwnership(address newOwner)
public
Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.
Setting newOwner
to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
IAccessControl
import "@openzeppelin/contracts/access/IAccessControl.sol";
External interface of AccessControl declared to support ERC-165 detection.
hasRole(bytes32 role, address account) → bool
external
Returns true
if account
has been granted role
.
getRoleAdmin(bytes32 role) → bytes32
external
Returns the admin role that controls role
. See grantRole
and
revokeRole
.
To change a role’s admin, use AccessControl._setRoleAdmin
.
grantRole(bytes32 role, address account)
external
Grants role
to account
.
If account
had not been already granted role
, emits a RoleGranted
event.
Requirements:
-
the caller must have
role
's admin role.
revokeRole(bytes32 role, address account)
external
Revokes role
from account
.
If account
had been granted role
, emits a RoleRevoked
event.
Requirements:
-
the caller must have
role
's admin role.
renounceRole(bytes32 role, address callerConfirmation)
external
Revokes role
from the calling account.
Roles are often managed via grantRole
and revokeRole
: this function’s
purpose is to provide a mechanism for accounts to lose their privileges
if they are compromised (such as when a trusted device is misplaced).
If the calling account had been granted role
, emits a RoleRevoked
event.
Requirements:
-
the caller must be
callerConfirmation
.
RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole)
event
Emitted when newAdminRole
is set as role
's admin role, replacing previousAdminRole
DEFAULT_ADMIN_ROLE
is the starting admin for all roles, despite
RoleAdminChanged
not being emitted signaling this.
RoleGranted(bytes32 indexed role, address indexed account, address indexed sender)
event
Emitted when account
is granted role
.
sender
is the account that originated the contract call. This account bears the admin role (for the granted role).
Expected in cases where the role was granted using the internal AccessControl._grantRole
.
RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender)
event
Emitted when account
is revoked role
.
sender
is the account that originated the contract call:
- if using revokeRole
, it is the admin role bearer
- if using renounceRole
, it is the role bearer (i.e. account
)
AccessControlUnauthorizedAccount(address account, bytes32 neededRole)
error
The account
is missing a role.
AccessControlBadConfirmation()
error
The caller of a function is not the expected one.
Don’t confuse with AccessControlUnauthorizedAccount .
|
AccessControl
import "@openzeppelin/contracts/access/AccessControl.sol";
Contract module that allows children to implement role-based access
control mechanisms. This is a lightweight version that doesn’t allow enumerating role
members except through off-chain means by accessing the contract event logs. Some
applications may benefit from on-chain enumerability, for those cases see
AccessControlEnumerable
.
Roles are referred to by their bytes32
identifier. These should be exposed
in the external API and be unique. The best way to achieve this is by
using public constant
hash digests:
bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
Roles can be used to represent a set of permissions. To restrict access to a
function call, use hasRole
:
function foo() public {
require(hasRole(MY_ROLE, msg.sender));
...
}
Roles can be granted and revoked dynamically via the grantRole
and
revokeRole
functions. Each role has an associated admin role, and only
accounts that have a role’s admin role can call grantRole
and revokeRole
.
By default, the admin role for all roles is DEFAULT_ADMIN_ROLE
, which means
that only accounts with this role will be able to grant or revoke other
roles. More complex role relationships can be created by using
_setRoleAdmin
.
The DEFAULT_ADMIN_ROLE is also its own admin: it has permission to
grant and revoke this role. Extra precautions should be taken to secure
accounts that have been granted it. We recommend using AccessControlDefaultAdminRules
to enforce additional security measures for this role.
|
onlyRole(bytes32 role)
modifier
Modifier that checks that an account has a specific role. Reverts
with an AccessControlUnauthorizedAccount
error including the required role.
_checkRole(bytes32 role)
internal
Reverts with an AccessControlUnauthorizedAccount
error if _msgSender()
is missing role
. Overriding this function changes the behavior of the onlyRole
modifier.
_checkRole(bytes32 role, address account)
internal
Reverts with an AccessControlUnauthorizedAccount
error if account
is missing role
.
getRoleAdmin(bytes32 role) → bytes32
public
Returns the admin role that controls role
. See grantRole
and
revokeRole
.
To change a role’s admin, use _setRoleAdmin
.
grantRole(bytes32 role, address account)
public
Grants role
to account
.
If account
had not been already granted role
, emits a RoleGranted
event.
Requirements:
-
the caller must have
role
's admin role.
May emit a RoleGranted
event.
revokeRole(bytes32 role, address account)
public
Revokes role
from account
.
If account
had been granted role
, emits a RoleRevoked
event.
Requirements:
-
the caller must have
role
's admin role.
May emit a RoleRevoked
event.
renounceRole(bytes32 role, address callerConfirmation)
public
Revokes role
from the calling account.
Roles are often managed via grantRole
and revokeRole
: this function’s
purpose is to provide a mechanism for accounts to lose their privileges
if they are compromised (such as when a trusted device is misplaced).
If the calling account had been revoked role
, emits a RoleRevoked
event.
Requirements:
-
the caller must be
callerConfirmation
.
May emit a RoleRevoked
event.
_setRoleAdmin(bytes32 role, bytes32 adminRole)
internal
Sets adminRole
as role
's admin role.
Emits a RoleAdminChanged
event.
_grantRole(bytes32 role, address account) → bool
internal
Attempts to grant role
to account
and returns a boolean indicating if role
was granted.
Internal function without access restriction.
May emit a RoleGranted
event.
_revokeRole(bytes32 role, address account) → bool
internal
Attempts to revoke role
to account
and returns a boolean indicating if role
was revoked.
Internal function without access restriction.
May emit a RoleRevoked
event.
Extensions
IAccessControlEnumerable
import "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
External interface of AccessControlEnumerable declared to support ERC-165 detection.
getRoleMember(bytes32 role, uint256 index) → address
external
Returns one of the accounts that have role
. index
must be a
value between 0 and getRoleMemberCount
, non-inclusive.
Role bearers are not sorted in any particular way, and their ordering may change at any point.
When using getRoleMember and getRoleMemberCount , make sure
you perform all queries on the same block. See the following
forum post
for more information.
|
getRoleMemberCount(bytes32 role) → uint256
external
Returns the number of accounts that have role
. Can be used
together with getRoleMember
to enumerate all bearers of a role.
AccessControlEnumerable
import "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";
Extension of AccessControl
that allows enumerating the members of each role.
getRoleMember(bytes32 role, uint256 index) → address
public
Returns one of the accounts that have role
. index
must be a
value between 0 and getRoleMemberCount
, non-inclusive.
Role bearers are not sorted in any particular way, and their ordering may change at any point.
When using getRoleMember and getRoleMemberCount , make sure
you perform all queries on the same block. See the following
forum post
for more information.
|
getRoleMemberCount(bytes32 role) → uint256
public
Returns the number of accounts that have role
. Can be used
together with getRoleMember
to enumerate all bearers of a role.
getRoleMembers(bytes32 role) → address[]
public
Return all accounts that have role
This operation will copy the entire storage to memory, which can be quite expensive. This is designed to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that this function has an unbounded cost, and using it as part of a state-changing function may render the function uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. |
_grantRole(bytes32 role, address account) → bool
internal
Overload AccessControl._grantRole
to track enumerable memberships
_revokeRole(bytes32 role, address account) → bool
internal
Overload AccessControl._revokeRole
to track enumerable memberships
IAccessControlDefaultAdminRules
import "@openzeppelin/contracts/access/extensions/IAccessControlDefaultAdminRules.sol";
External interface of AccessControlDefaultAdminRules declared to support ERC-165 detection.
pendingDefaultAdmin() → address newAdmin, uint48 acceptSchedule
external
Returns a tuple of a newAdmin
and an accept schedule.
After the schedule
passes, the newAdmin
will be able to accept the defaultAdmin
role
by calling acceptDefaultAdminTransfer
, completing the role transfer.
A zero value only in acceptSchedule
indicates no pending admin transfer.
A zero address newAdmin means that defaultAdmin is being renounced.
|
defaultAdminDelay() → uint48
external
Returns the delay required to schedule the acceptance of a defaultAdmin
transfer started.
This delay will be added to the current timestamp when calling beginDefaultAdminTransfer
to set
the acceptance schedule.
If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this
function returns the new delay. See changeDefaultAdminDelay .
|
pendingDefaultAdminDelay() → uint48 newDelay, uint48 effectSchedule
external
Returns a tuple of newDelay
and an effect schedule.
After the schedule
passes, the newDelay
will get into effect immediately for every
new defaultAdmin
transfer started with beginDefaultAdminTransfer
.
A zero value only in effectSchedule
indicates no pending delay change.
A zero value only for newDelay means that the next defaultAdminDelay
will be zero after the effect schedule.
|
beginDefaultAdminTransfer(address newAdmin)
external
Starts a defaultAdmin
transfer by setting a pendingDefaultAdmin
scheduled for acceptance
after the current timestamp plus a defaultAdminDelay
.
Requirements:
-
Only can be called by the current
defaultAdmin
.
Emits a DefaultAdminRoleChangeStarted event.
cancelDefaultAdminTransfer()
external
Cancels a defaultAdmin
transfer previously started with beginDefaultAdminTransfer
.
A pendingDefaultAdmin
not yet accepted can also be cancelled with this function.
Requirements:
-
Only can be called by the current
defaultAdmin
.
May emit a DefaultAdminTransferCanceled event.
acceptDefaultAdminTransfer()
external
Completes a defaultAdmin
transfer previously started with beginDefaultAdminTransfer
.
After calling the function:
-
DEFAULT_ADMIN_ROLE
should be granted to the caller. -
DEFAULT_ADMIN_ROLE
should be revoked from the previous holder. -
pendingDefaultAdmin
should be reset to zero values.
Requirements:
-
Only can be called by the
pendingDefaultAdmin
'snewAdmin
. -
The
pendingDefaultAdmin
'sacceptSchedule
should’ve passed.
changeDefaultAdminDelay(uint48 newDelay)
external
Initiates a defaultAdminDelay
update by setting a pendingDefaultAdminDelay
scheduled for getting
into effect after the current timestamp plus a defaultAdminDelay
.
This function guarantees that any call to beginDefaultAdminTransfer
done between the timestamp this
method is called and the pendingDefaultAdminDelay
effect schedule will use the current defaultAdminDelay
set before calling.
The pendingDefaultAdminDelay
's effect schedule is defined in a way that waiting until the schedule and then
calling beginDefaultAdminTransfer
with the new delay will take at least the same as another defaultAdmin
complete transfer (including acceptance).
The schedule is designed for two scenarios:
-
When the delay is changed for a larger one the schedule is
block.timestamp + newDelay
capped bydefaultAdminDelayIncreaseWait
. -
When the delay is changed for a shorter one, the schedule is
block.timestamp + (current delay - new delay)
.
A pendingDefaultAdminDelay
that never got into effect will be canceled in favor of a new scheduled change.
Requirements:
-
Only can be called by the current
defaultAdmin
.
Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event.
rollbackDefaultAdminDelay()
external
Cancels a scheduled defaultAdminDelay
change.
Requirements:
-
Only can be called by the current
defaultAdmin
.
May emit a DefaultAdminDelayChangeCanceled event.
defaultAdminDelayIncreaseWait() → uint48
external
Maximum time in seconds for an increase to defaultAdminDelay
(that is scheduled using changeDefaultAdminDelay
)
to take effect. Default to 5 days.
When the defaultAdminDelay
is scheduled to be increased, it goes into effect after the new delay has passed with
the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds)
that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can
be overrode for a custom defaultAdminDelay
increase scheduling.
Make sure to add a reasonable amount of time while overriding this value, otherwise, there’s a risk of setting a high new delay that goes into effect almost immediately without the possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds). |
DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule)
event
Emitted when a defaultAdmin
transfer is started, setting newAdmin
as the next
address to become the defaultAdmin
by calling acceptDefaultAdminTransfer
only after acceptSchedule
passes.
DefaultAdminTransferCanceled()
event
Emitted when a pendingDefaultAdmin
is reset if it was never accepted, regardless of its schedule.
DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule)
event
Emitted when a defaultAdminDelay
change is started, setting newDelay
as the next
delay to be applied between default admin transfer after effectSchedule
has passed.
DefaultAdminDelayChangeCanceled()
event
Emitted when a pendingDefaultAdminDelay
is reset if its schedule didn’t pass.
AccessControlInvalidDefaultAdmin(address defaultAdmin)
error
The new default admin is not a valid default admin.
AccessControlDefaultAdminRules
import "@openzeppelin/contracts/access/extensions/AccessControlDefaultAdminRules.sol";
Extension of AccessControl
that allows specifying special rules to manage
the DEFAULT_ADMIN_ROLE
holder, which is a sensitive role with special permissions
over other roles that may potentially have privileged rights in the system.
If a specific role doesn’t have an admin role assigned, the holder of the
DEFAULT_ADMIN_ROLE
will have the ability to grant it and revoke it.
This contract implements the following risk mitigations on top of AccessControl
:
-
Only one account holds the
DEFAULT_ADMIN_ROLE
since deployment until it’s potentially renounced. -
Enforces a 2-step process to transfer the
DEFAULT_ADMIN_ROLE
to another account. -
Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted.
-
The delay can be changed by scheduling, see
changeDefaultAdminDelay
. -
It is not possible to use another role to manage the
DEFAULT_ADMIN_ROLE
.
Example usage:
contract MyToken is AccessControlDefaultAdminRules {
constructor() AccessControlDefaultAdminRules(
3 days,
msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder
) {}
}
constructor(uint48 initialDelay, address initialDefaultAdmin)
internal
Sets the initial values for defaultAdminDelay
and defaultAdmin
address.
owner() → address
public
See IERC5313.owner
.
grantRole(bytes32 role, address account)
public
See AccessControl.grantRole
. Reverts for DEFAULT_ADMIN_ROLE
.
revokeRole(bytes32 role, address account)
public
See AccessControl.revokeRole
. Reverts for DEFAULT_ADMIN_ROLE
.
renounceRole(bytes32 role, address account)
public
For the DEFAULT_ADMIN_ROLE
, it only allows renouncing in two steps by first calling
beginDefaultAdminTransfer
to the address(0)
, so it’s required that the pendingDefaultAdmin
schedule
has also passed when calling this function.
After its execution, it will not be possible to call onlyRole(DEFAULT_ADMIN_ROLE)
functions.
Renouncing DEFAULT_ADMIN_ROLE will leave the contract without a defaultAdmin ,
thereby disabling any functionality that is only available for it, and the possibility of reassigning a
non-administrated role.
|
_grantRole(bytes32 role, address account) → bool
internal
For DEFAULT_ADMIN_ROLE
, it only allows granting if there isn’t already a defaultAdmin
or if the
role has been previously renounced.
Exposing this function through another mechanism may make the DEFAULT_ADMIN_ROLE
assignable again. Make sure to guarantee this is the expected behavior in your implementation.
|
_setRoleAdmin(bytes32 role, bytes32 adminRole)
internal
See AccessControl._setRoleAdmin
. Reverts for DEFAULT_ADMIN_ROLE
.
pendingDefaultAdmin() → address newAdmin, uint48 schedule
public
Returns a tuple of a newAdmin
and an accept schedule.
After the schedule
passes, the newAdmin
will be able to accept the defaultAdmin
role
by calling acceptDefaultAdminTransfer
, completing the role transfer.
A zero value only in acceptSchedule
indicates no pending admin transfer.
A zero address newAdmin means that defaultAdmin is being renounced.
|
defaultAdminDelay() → uint48
public
Returns the delay required to schedule the acceptance of a defaultAdmin
transfer started.
This delay will be added to the current timestamp when calling beginDefaultAdminTransfer
to set
the acceptance schedule.
If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this
function returns the new delay. See changeDefaultAdminDelay .
|
pendingDefaultAdminDelay() → uint48 newDelay, uint48 schedule
public
Returns a tuple of newDelay
and an effect schedule.
After the schedule
passes, the newDelay
will get into effect immediately for every
new defaultAdmin
transfer started with beginDefaultAdminTransfer
.
A zero value only in effectSchedule
indicates no pending delay change.
A zero value only for newDelay means that the next defaultAdminDelay
will be zero after the effect schedule.
|
defaultAdminDelayIncreaseWait() → uint48
public
Maximum time in seconds for an increase to defaultAdminDelay
(that is scheduled using changeDefaultAdminDelay
)
to take effect. Default to 5 days.
When the defaultAdminDelay
is scheduled to be increased, it goes into effect after the new delay has passed with
the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds)
that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can
be overrode for a custom defaultAdminDelay
increase scheduling.
Make sure to add a reasonable amount of time while overriding this value, otherwise, there’s a risk of setting a high new delay that goes into effect almost immediately without the possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds). |
beginDefaultAdminTransfer(address newAdmin)
public
Starts a defaultAdmin
transfer by setting a pendingDefaultAdmin
scheduled for acceptance
after the current timestamp plus a defaultAdminDelay
.
Requirements:
-
Only can be called by the current
defaultAdmin
.
Emits a DefaultAdminRoleChangeStarted event.
cancelDefaultAdminTransfer()
public
Cancels a defaultAdmin
transfer previously started with beginDefaultAdminTransfer
.
A pendingDefaultAdmin
not yet accepted can also be cancelled with this function.
Requirements:
-
Only can be called by the current
defaultAdmin
.
May emit a DefaultAdminTransferCanceled event.
acceptDefaultAdminTransfer()
public
Completes a defaultAdmin
transfer previously started with beginDefaultAdminTransfer
.
After calling the function:
-
DEFAULT_ADMIN_ROLE
should be granted to the caller. -
DEFAULT_ADMIN_ROLE
should be revoked from the previous holder. -
pendingDefaultAdmin
should be reset to zero values.
Requirements:
-
Only can be called by the
pendingDefaultAdmin
'snewAdmin
. -
The
pendingDefaultAdmin
'sacceptSchedule
should’ve passed.
changeDefaultAdminDelay(uint48 newDelay)
public
Initiates a defaultAdminDelay
update by setting a pendingDefaultAdminDelay
scheduled for getting
into effect after the current timestamp plus a defaultAdminDelay
.
This function guarantees that any call to beginDefaultAdminTransfer
done between the timestamp this
method is called and the pendingDefaultAdminDelay
effect schedule will use the current defaultAdminDelay
set before calling.
The pendingDefaultAdminDelay
's effect schedule is defined in a way that waiting until the schedule and then
calling beginDefaultAdminTransfer
with the new delay will take at least the same as another defaultAdmin
complete transfer (including acceptance).
The schedule is designed for two scenarios:
-
When the delay is changed for a larger one the schedule is
block.timestamp + newDelay
capped bydefaultAdminDelayIncreaseWait
. -
When the delay is changed for a shorter one, the schedule is
block.timestamp + (current delay - new delay)
.
A pendingDefaultAdminDelay
that never got into effect will be canceled in favor of a new scheduled change.
Requirements:
-
Only can be called by the current
defaultAdmin
.
Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event.
rollbackDefaultAdminDelay()
public
Cancels a scheduled defaultAdminDelay
change.
Requirements:
-
Only can be called by the current
defaultAdmin
.
May emit a DefaultAdminDelayChangeCanceled event.
_delayChangeWait(uint48 newDelay) → uint48
internal
Returns the amount of seconds to wait after the newDelay
will
become the new defaultAdminDelay
.
The value returned guarantees that if the delay is reduced, it will go into effect after a wait that honors the previously set delay.
AccessManager
IAuthority
import "@openzeppelin/contracts/access/manager/IAuthority.sol";
Standard interface for permissioning originally defined in Dappsys.
IAccessManager
import "@openzeppelin/contracts/access/manager/IAccessManager.sol";
canCall(address caller, address target, bytes4 selector) → bool allowed, uint32 delay
external
Check if an address (caller
) is authorised to call a given function on a given contract directly (with
no restriction). Additionally, it returns the delay needed to perform the call indirectly through the schedule
& execute
workflow.
This function is usually called by the targeted contract to control immediate execution of restricted functions. Therefore we only return true if the call can be performed without any delay. If the call is subject to a previously set delay (not zero), then the function should return false and the caller should schedule the operation for future execution.
If immediate
is true, the delay can be disregarded and the operation can be immediately executed, otherwise
the operation can be executed if and only if delay is greater than 0.
The IAuthority interface does not include the uint32 delay. This is an extension of that interface that
is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail
to identify the indirect workflow, and will consider calls that require a delay to be forbidden.
|
This function does not report the permissions of the admin functions in the manager itself. These are defined by the
AccessManager documentation.
|
expiration() → uint32
external
Expiration delay for scheduled proposals. Defaults to 1 week.
Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately, disabling any scheduling usage. |
minSetback() → uint32
external
Minimum setback for all delay updates, with the exception of execution delays. It
can be increased without setback (and reset via revokeRole
in the case event of an
accidental increase). Defaults to 5 days.
isTargetClosed(address target) → bool
external
Get whether the contract is closed disabling any access. Otherwise role permissions are applied.
When the manager itself is closed, admin functions are still accessible to avoid locking the contract. |
getTargetFunctionRole(address target, bytes4 selector) → uint64
external
Get the role required to call a function.
getTargetAdminDelay(address target) → uint32
external
Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.
getRoleAdmin(uint64 roleId) → uint64
external
Get the id of the role that acts as an admin for the given role.
The admin permission is required to grant the role, revoke the role and update the execution delay to execute an operation that is restricted to this role.
getRoleGuardian(uint64 roleId) → uint64
external
Get the role that acts as a guardian for a given role.
The guardian permission allows canceling operations that have been scheduled under the role.
getRoleGrantDelay(uint64 roleId) → uint32
external
Get the role current grant delay.
Its value may change at any point without an event emitted following a call to setGrantDelay
.
Changes to this value, including effect timepoint are notified in advance by the RoleGrantDelayChanged
event.
getAccess(uint64 roleId, address account) → uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect
external
Get the access details for a given account for a given role. These details include the timepoint at which membership becomes active, and the delay applied to all operation by this user that requires this permission level.
Returns: [0] Timestamp at which the account membership becomes valid. 0 means role is not granted. [1] Current execution delay for the account. [2] Pending execution delay for the account. [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.
hasRole(uint64 roleId, address account) → bool isMember, uint32 executionDelay
external
Check if a given account currently has the permission level corresponding to a given role. Note that this
permission might be associated with an execution delay. getAccess
can provide more details.
labelRole(uint64 roleId, string label)
external
Give a label to a role, for improved role discoverability by UIs.
Requirements:
-
the caller must be a global admin
Emits a RoleLabel
event.
grantRole(uint64 roleId, address account, uint32 executionDelay)
external
Add account
to roleId
, or change its execution delay.
This gives the account the authorization to call any function that is restricted to this role. An optional
execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation
that is restricted to members of this role. The user will only be able to execute the operation after the delay has
passed, before it has expired. During this period, admin and guardians can cancel the operation (see cancel
).
If the account has already been granted this role, the execution delay will be updated. This update is not immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any operation executed in the 3 hours that follows this update was indeed scheduled before this update.
Requirements:
-
the caller must be an admin for the role (see
getRoleAdmin
) -
granted role must not be the
PUBLIC_ROLE
Emits a RoleGranted
event.
revokeRole(uint64 roleId, address account)
external
Remove an account from a role, with immediate effect. If the account does not have the role, this call has no effect.
Requirements:
-
the caller must be an admin for the role (see
getRoleAdmin
) -
revoked role must not be the
PUBLIC_ROLE
Emits a RoleRevoked
event if the account had the role.
renounceRole(uint64 roleId, address callerConfirmation)
external
Renounce role permissions for the calling account with immediate effect. If the sender is not in the role this call has no effect.
Requirements:
-
the caller must be
callerConfirmation
.
Emits a RoleRevoked
event if the account had the role.
setRoleAdmin(uint64 roleId, uint64 admin)
external
Change admin role for a given role.
Requirements:
-
the caller must be a global admin
Emits a RoleAdminChanged
event
setRoleGuardian(uint64 roleId, uint64 guardian)
external
Change guardian role for a given role.
Requirements:
-
the caller must be a global admin
Emits a RoleGuardianChanged
event
setGrantDelay(uint64 roleId, uint32 newDelay)
external
Update the delay for granting a roleId
.
Requirements:
-
the caller must be a global admin
Emits a RoleGrantDelayChanged
event.
setTargetFunctionRole(address target, bytes4[] selectors, uint64 roleId)
external
Set the role required to call functions identified by the selectors
in the target
contract.
Requirements:
-
the caller must be a global admin
Emits a TargetFunctionRoleUpdated
event per selector.
setTargetAdminDelay(address target, uint32 newDelay)
external
Set the delay for changing the configuration of a given target contract.
Requirements:
-
the caller must be a global admin
Emits a TargetAdminDelayUpdated
event.
setTargetClosed(address target, bool closed)
external
Set the closed flag for a contract.
Closing the manager itself won’t disable access to admin methods to avoid locking the contract.
Requirements:
-
the caller must be a global admin
Emits a TargetClosed
event.
getSchedule(bytes32 id) → uint48
external
Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the operation is not yet scheduled, has expired, was executed, or was canceled.
getNonce(bytes32 id) → uint32
external
Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never been scheduled.
schedule(address target, bytes data, uint48 when) → bytes32 operationId, uint32 nonce
external
Schedule a delayed operation for future execution, and return the operation identifier. It is possible to choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays required for the caller. The special value zero will automatically set the earliest possible time.
Returns the operationId
that was scheduled. Since this value is a hash of the parameters, it can reoccur when
the same parameters are used; if this is relevant, the returned nonce
can be used to uniquely identify this
scheduled operation from other occurrences of the same operationId
in invocations of execute
and cancel
.
Emits a OperationScheduled
event.
It is not possible to concurrently schedule more than one operation with the same target and data . If
this is necessary, a random byte can be appended to data to act as a salt that will be ignored by the target
contract if it is using standard Solidity ABI encoding.
|
execute(address target, bytes data) → uint32
external
Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the execution delay is 0.
Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the operation wasn’t previously scheduled (if the caller doesn’t have an execution delay).
Emits an OperationExecuted
event only if the call was scheduled and delayed.
cancel(address caller, address target, bytes data) → uint32
external
Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled operation that is cancelled.
Requirements:
-
the caller must be the proposer, a guardian of the targeted function, or a global admin
Emits a OperationCanceled
event.
consumeScheduledOp(address caller, bytes data)
external
Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed
(emit an OperationExecuted
event and clean the state). Otherwise, throw an error.
This is useful for contract that want to enforce that calls targeting them were scheduled on the manager, with all the verifications that it implies.
Emit a OperationExecuted
event.
hashOperation(address caller, address target, bytes data) → bytes32
external
Hashing function for delayed operations.
updateAuthority(address target, address newAuthority)
external
Changes the authority of a target managed by this manager instance.
Requirements:
-
the caller must be a global admin
OperationScheduled(bytes32 indexed operationId, uint32 indexed nonce, uint48 schedule, address caller, address target, bytes data)
event
A delayed operation was scheduled.
OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce)
event
A scheduled operation was executed.
OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce)
event
A scheduled operation was canceled.
RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, bool newMember)
event
Emitted when account
is granted roleId
.
The meaning of the since argument depends on the newMember argument.
If the role is granted to a new member, the since argument indicates when the account becomes a member of the role,
otherwise it indicates the execution delay for this account and roleId is updated.
|
RoleRevoked(uint64 indexed roleId, address indexed account)
event
Emitted when account
membership or roleId
is revoked. Unlike granting, revoking is instantaneous.
RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin)
event
Role acting as admin over a given roleId
is updated.
RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian)
event
Role acting as guardian over a given roleId
is updated.
RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since)
event
Grant delay for a given roleId
will be updated to delay
when since
is reached.
TargetClosed(address indexed target, bool closed)
event
Target mode is updated (true = closed, false = open).
TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId)
event
Role required to invoke selector
on target
is updated to roleId
.
TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since)
event
Admin delay for a given target
will be updated to delay
when since
is reached.
AccessManager
import "@openzeppelin/contracts/access/manager/AccessManager.sol";
AccessManager is a central contract to store the permissions of a system.
A smart contract under the control of an AccessManager instance is known as a target, and will inherit from the
AccessManaged
contract, be connected to this contract as its manager and implement the AccessManaged.restricted
modifier on a set of functions selected to be permissioned. Note that any function without this setup won’t be
effectively restricted.
The restriction rules for such functions are defined in terms of "roles" identified by an uint64
and scoped
by target (address
) and function selectors (bytes4
). These roles are stored in this contract and can be
configured by admins (ADMIN_ROLE
members) after a delay (see getTargetAdminDelay
).
For each target contract, admins can configure the following without any delay:
-
The target’s
AccessManaged.authority
viaupdateAuthority
. -
Close or open a target via
setTargetClosed
keeping the permissions intact. -
The roles that are allowed (or disallowed) to call a given function (identified by its selector) through
setTargetFunctionRole
.
By default every address is member of the PUBLIC_ROLE
and every target function is restricted to the ADMIN_ROLE
until configured otherwise.
Additionally, each role has the following configuration options restricted to this manager’s admins:
-
A role’s admin role via
setRoleAdmin
who can grant or revoke roles. -
A role’s guardian role via
setRoleGuardian
who’s allowed to cancel operations. -
A delay in which a role takes effect after being granted through
setGrantDelay
. -
A delay of any target’s admin action via
setTargetAdminDelay
. -
A role label for discoverability purposes with
labelRole
.
Any account can be added and removed into any number of these roles by using the grantRole
and revokeRole
functions
restricted to each role’s admin (see getRoleAdmin
).
Since all the permissions of the managed system can be modified by the admins of this instance, it is expected that they will be highly secured (e.g., a multisig or a well-configured DAO).
This contract implements a form of the IAuthority interface, but canCall has additional return data so it
doesn’t inherit IAuthority . It is however compatible with the IAuthority interface since the first 32 bytes of
the return data are a boolean as expected by that interface.
|
Systems that implement other access control mechanisms (for example using Ownable ) can be paired with an
AccessManager by transferring permissions (ownership in the case of Ownable ) directly to the AccessManager .
Users will be able to interact with these contracts through the execute function, following the access rules
registered in the AccessManager . Keep in mind that in that context, the msg.sender seen by restricted functions
will be AccessManager itself.
|
When granting permissions over an Ownable or AccessControl contract to an AccessManager , be very
mindful of the danger associated with functions such as Ownable.renounceOwnership or
AccessControl.renounceRole .
|
onlyAuthorized()
modifier
Check that the caller is authorized to perform the operation.
See AccessManager
description for a detailed breakdown of the authorization logic.
canCall(address caller, address target, bytes4 selector) → bool immediate, uint32 delay
public
Check if an address (caller
) is authorised to call a given function on a given contract directly (with
no restriction). Additionally, it returns the delay needed to perform the call indirectly through the schedule
& execute
workflow.
This function is usually called by the targeted contract to control immediate execution of restricted functions. Therefore we only return true if the call can be performed without any delay. If the call is subject to a previously set delay (not zero), then the function should return false and the caller should schedule the operation for future execution.
If immediate
is true, the delay can be disregarded and the operation can be immediately executed, otherwise
the operation can be executed if and only if delay is greater than 0.
The IAuthority interface does not include the uint32 delay. This is an extension of that interface that
is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail
to identify the indirect workflow, and will consider calls that require a delay to be forbidden.
|
This function does not report the permissions of the admin functions in the manager itself. These are defined by the
AccessManager documentation.
|
expiration() → uint32
public
Expiration delay for scheduled proposals. Defaults to 1 week.
Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately, disabling any scheduling usage. |
minSetback() → uint32
public
Minimum setback for all delay updates, with the exception of execution delays. It
can be increased without setback (and reset via revokeRole
in the case event of an
accidental increase). Defaults to 5 days.
isTargetClosed(address target) → bool
public
Get whether the contract is closed disabling any access. Otherwise role permissions are applied.
When the manager itself is closed, admin functions are still accessible to avoid locking the contract. |
getTargetFunctionRole(address target, bytes4 selector) → uint64
public
Get the role required to call a function.
getTargetAdminDelay(address target) → uint32
public
Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.
getRoleAdmin(uint64 roleId) → uint64
public
Get the id of the role that acts as an admin for the given role.
The admin permission is required to grant the role, revoke the role and update the execution delay to execute an operation that is restricted to this role.
getRoleGuardian(uint64 roleId) → uint64
public
Get the role that acts as a guardian for a given role.
The guardian permission allows canceling operations that have been scheduled under the role.
getRoleGrantDelay(uint64 roleId) → uint32
public
Get the role current grant delay.
Its value may change at any point without an event emitted following a call to setGrantDelay
.
Changes to this value, including effect timepoint are notified in advance by the RoleGrantDelayChanged
event.
getAccess(uint64 roleId, address account) → uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect
public
Get the access details for a given account for a given role. These details include the timepoint at which membership becomes active, and the delay applied to all operation by this user that requires this permission level.
Returns: [0] Timestamp at which the account membership becomes valid. 0 means role is not granted. [1] Current execution delay for the account. [2] Pending execution delay for the account. [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.
hasRole(uint64 roleId, address account) → bool isMember, uint32 executionDelay
public
Check if a given account currently has the permission level corresponding to a given role. Note that this
permission might be associated with an execution delay. getAccess
can provide more details.
labelRole(uint64 roleId, string label)
public
Give a label to a role, for improved role discoverability by UIs.
Requirements:
-
the caller must be a global admin
Emits a RoleLabel
event.
grantRole(uint64 roleId, address account, uint32 executionDelay)
public
Add account
to roleId
, or change its execution delay.
This gives the account the authorization to call any function that is restricted to this role. An optional
execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation
that is restricted to members of this role. The user will only be able to execute the operation after the delay has
passed, before it has expired. During this period, admin and guardians can cancel the operation (see cancel
).
If the account has already been granted this role, the execution delay will be updated. This update is not immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any operation executed in the 3 hours that follows this update was indeed scheduled before this update.
Requirements:
-
the caller must be an admin for the role (see
getRoleAdmin
) -
granted role must not be the
PUBLIC_ROLE
Emits a RoleGranted
event.
revokeRole(uint64 roleId, address account)
public
Remove an account from a role, with immediate effect. If the account does not have the role, this call has no effect.
Requirements:
-
the caller must be an admin for the role (see
getRoleAdmin
) -
revoked role must not be the
PUBLIC_ROLE
Emits a RoleRevoked
event if the account had the role.
renounceRole(uint64 roleId, address callerConfirmation)
public
Renounce role permissions for the calling account with immediate effect. If the sender is not in the role this call has no effect.
Requirements:
-
the caller must be
callerConfirmation
.
Emits a RoleRevoked
event if the account had the role.
setRoleAdmin(uint64 roleId, uint64 admin)
public
Change admin role for a given role.
Requirements:
-
the caller must be a global admin
Emits a RoleAdminChanged
event
setRoleGuardian(uint64 roleId, uint64 guardian)
public
Change guardian role for a given role.
Requirements:
-
the caller must be a global admin
Emits a RoleGuardianChanged
event
setGrantDelay(uint64 roleId, uint32 newDelay)
public
Update the delay for granting a roleId
.
Requirements:
-
the caller must be a global admin
Emits a RoleGrantDelayChanged
event.
_grantRole(uint64 roleId, address account, uint32 grantDelay, uint32 executionDelay) → bool
internal
Internal version of grantRole
without access control. Returns true if the role was newly granted.
Emits a RoleGranted
event.
_revokeRole(uint64 roleId, address account) → bool
internal
Internal version of revokeRole
without access control. This logic is also used by renounceRole
.
Returns true if the role was previously granted.
Emits a RoleRevoked
event if the account had the role.
_setRoleAdmin(uint64 roleId, uint64 admin)
internal
Internal version of setRoleAdmin
without access control.
Emits a RoleAdminChanged
event.
Setting the admin role as the PUBLIC_ROLE is allowed, but it will effectively allow
anyone to set grant or revoke such role.
|
_setRoleGuardian(uint64 roleId, uint64 guardian)
internal
Internal version of setRoleGuardian
without access control.
Emits a RoleGuardianChanged
event.
Setting the guardian role as the PUBLIC_ROLE is allowed, but it will effectively allow
anyone to cancel any scheduled operation for such role.
|
_setGrantDelay(uint64 roleId, uint32 newDelay)
internal
Internal version of setGrantDelay
without access control.
Emits a RoleGrantDelayChanged
event.
setTargetFunctionRole(address target, bytes4[] selectors, uint64 roleId)
public
Set the role required to call functions identified by the selectors
in the target
contract.
Requirements:
-
the caller must be a global admin
Emits a TargetFunctionRoleUpdated
event per selector.
_setTargetFunctionRole(address target, bytes4 selector, uint64 roleId)
internal
Internal version of setTargetFunctionRole
without access control.
Emits a TargetFunctionRoleUpdated
event.
setTargetAdminDelay(address target, uint32 newDelay)
public
Set the delay for changing the configuration of a given target contract.
Requirements:
-
the caller must be a global admin
Emits a TargetAdminDelayUpdated
event.
_setTargetAdminDelay(address target, uint32 newDelay)
internal
Internal version of setTargetAdminDelay
without access control.
Emits a TargetAdminDelayUpdated
event.
setTargetClosed(address target, bool closed)
public
Set the closed flag for a contract.
Closing the manager itself won’t disable access to admin methods to avoid locking the contract.
Requirements:
-
the caller must be a global admin
Emits a TargetClosed
event.
_setTargetClosed(address target, bool closed)
internal
Set the closed flag for a contract. This is an internal setter with no access restrictions.
Emits a TargetClosed
event.
getSchedule(bytes32 id) → uint48
public
Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the operation is not yet scheduled, has expired, was executed, or was canceled.
getNonce(bytes32 id) → uint32
public
Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never been scheduled.
schedule(address target, bytes data, uint48 when) → bytes32 operationId, uint32 nonce
public
Schedule a delayed operation for future execution, and return the operation identifier. It is possible to choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays required for the caller. The special value zero will automatically set the earliest possible time.
Returns the operationId
that was scheduled. Since this value is a hash of the parameters, it can reoccur when
the same parameters are used; if this is relevant, the returned nonce
can be used to uniquely identify this
scheduled operation from other occurrences of the same operationId
in invocations of execute
and cancel
.
Emits a OperationScheduled
event.
It is not possible to concurrently schedule more than one operation with the same target and data . If
this is necessary, a random byte can be appended to data to act as a salt that will be ignored by the target
contract if it is using standard Solidity ABI encoding.
|
execute(address target, bytes data) → uint32
public
Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the execution delay is 0.
Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the operation wasn’t previously scheduled (if the caller doesn’t have an execution delay).
Emits an OperationExecuted
event only if the call was scheduled and delayed.
cancel(address caller, address target, bytes data) → uint32
public
Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled operation that is cancelled.
Requirements:
-
the caller must be the proposer, a guardian of the targeted function, or a global admin
Emits a OperationCanceled
event.
consumeScheduledOp(address caller, bytes data)
public
Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed
(emit an OperationExecuted
event and clean the state). Otherwise, throw an error.
This is useful for contract that want to enforce that calls targeting them were scheduled on the manager, with all the verifications that it implies.
Emit a OperationExecuted
event.
_consumeScheduledOp(bytes32 operationId) → uint32
internal
Internal variant of consumeScheduledOp
that operates on bytes32 operationId.
Returns the nonce of the scheduled operation that is consumed.
hashOperation(address caller, address target, bytes data) → bytes32
public
Hashing function for delayed operations.
updateAuthority(address target, address newAuthority)
public
Changes the authority of a target managed by this manager instance.
Requirements:
-
the caller must be a global admin
IAccessManaged
import "@openzeppelin/contracts/access/manager/IAccessManaged.sol";
setAuthority(address)
external
Transfers control to a new authority. The caller must be the current authority.
AccessManaged
import "@openzeppelin/contracts/access/manager/AccessManaged.sol";
This contract module makes available a restricted
modifier. Functions decorated with this modifier will be
permissioned according to an "authority": a contract like AccessManager
that follows the IAuthority
interface,
implementing a policy that allows certain callers to access certain functions.
The restricted modifier should never be used on internal functions, judiciously used in public
functions, and ideally only used in external functions. See restricted .
|
restricted()
modifier
Restricts access to a function as defined by the connected Authority for this contract and the caller and selector of the function that entered the contract.
In general, this modifier should only be used on |
Avoid adding this modifier to the The |
constructor(address initialAuthority)
internal
Initializes the contract connected to an initial authority.
setAuthority(address newAuthority)
public
Transfers control to a new authority. The caller must be the current authority.
isConsumingScheduledOp() → bytes4
public
Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs attacker controlled calls.
AuthorityUtils
import "@openzeppelin/contracts/access/manager/AuthorityUtils.sol";
canCallWithDelay(address authority, address caller, address target, bytes4 selector) → bool immediate, uint32 delay
internal
Since AccessManager
implements an extended IAuthority interface, invoking canCall
with backwards compatibility
for the preexisting IAuthority
interface requires special care to avoid reverting on insufficient return data.
This helper function takes care of invoking canCall
in a backwards compatible way without reverting.