AccessControlDefaultAdminRulesUpgradeable
Inherits: Initializable, IAccessControlDefaultAdminRules, IERC5313, AccessControlUpgradeable
*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}.
Role transfers must wait at least one block after scheduling before it can be accepted.
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
) {}
}
```*
## State Variables
### AccessControlDefaultAdminRulesStorageLocation
```solidity
bytes32 private constant AccessControlDefaultAdminRulesStorageLocation =
0xeef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400;
Functions
_getAccessControlDefaultAdminRulesStorage
function _getAccessControlDefaultAdminRulesStorage()
private
pure
returns (AccessControlDefaultAdminRulesStorage storage $);
__AccessControlDefaultAdminRules_init
Sets the initial values for defaultAdminDelay and {defaultAdmin} address.
function __AccessControlDefaultAdminRules_init(uint48 initialDelay, address initialDefaultAdmin)
internal
onlyInitializing;
__AccessControlDefaultAdminRules_init_unchained
function __AccessControlDefaultAdminRules_init_unchained(uint48 initialDelay, address initialDefaultAdmin)
internal
onlyInitializing;
supportsInterface
Query if a contract implements an interface
Interface identification is specified in ERC-165. This function uses less than 30,000 gas.
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool);
Parameters
Name | Type | Description |
---|---|---|
interfaceId | bytes4 |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | true if the contract implements interfaceID and interfaceID is not 0xffffffff, false otherwise |
owner
Gets the address of the owner.
function owner() public view virtual returns (address);
grantRole
Override AccessControl role management
See AccessControl-grantRole. Reverts for DEFAULT_ADMIN_ROLE
.
function grantRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl);
revokeRole
See AccessControl-revokeRole. Reverts for DEFAULT_ADMIN_ROLE
.
function revokeRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl);
renounceRole
See AccessControl-renounceRole.
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.
NOTE: 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.
function renounceRole(bytes32 role, address account)
public
virtual
override(AccessControlUpgradeable, IAccessControl);
_grantRole
See AccessControl-_grantRole.
For DEFAULT_ADMIN_ROLE
, it only allows granting if there isn't already a {defaultAdmin} or if the
role has been previously renounced.
NOTE: 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.
function _grantRole(bytes32 role, address account) internal virtual override returns (bool);
_revokeRole
Attempts to revoke role
from account
and returns a boolean indicating if role
was revoked.
Internal function without access restriction.
May emit a {RoleRevoked} event.
function _revokeRole(bytes32 role, address account) internal virtual override returns (bool);
_setRoleAdmin
See AccessControl-_setRoleAdmin. Reverts for DEFAULT_ADMIN_ROLE
.
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override;
defaultAdmin
AccessControlDefaultAdminRules accessors
Returns the address of the current DEFAULT_ADMIN_ROLE
holder.
function defaultAdmin() public view virtual returns (address);
pendingDefaultAdmin
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.
NOTE: A zero address newAdmin
means that {defaultAdmin} is being renounced.
function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule);
defaultAdminDelay
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. NOTE: 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}.
function defaultAdminDelay() public view virtual returns (uint48);
pendingDefaultAdminDelay
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.
NOTE: A zero value only for newDelay
means that the next {defaultAdminDelay}
will be zero after the effect schedule.
function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule);
defaultAdminDelayIncreaseWait
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. IMPORTANT: 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).
function defaultAdminDelayIncreaseWait() public view virtual returns (uint48);
beginDefaultAdminTransfer
AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin
*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.*
function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE);
_beginDefaultAdminTransfer
See beginDefaultAdminTransfer. Internal function without access restriction.
function _beginDefaultAdminTransfer(address newAdmin) internal virtual;
cancelDefaultAdminTransfer
*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.*
function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE);
_cancelDefaultAdminTransfer
See cancelDefaultAdminTransfer. Internal function without access restriction.
function _cancelDefaultAdminTransfer() internal virtual;
acceptDefaultAdminTransfer
*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}'s
newAdmin
. - The {pendingDefaultAdmin}'s
acceptSchedule
should've passed.*
function acceptDefaultAdminTransfer() public virtual;
_acceptDefaultAdminTransfer
See acceptDefaultAdminTransfer. Internal function without access restriction.
function _acceptDefaultAdminTransfer() internal virtual;
changeDefaultAdminDelay
AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay
*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 by {defaultAdminDelayIncreaseWait}. - 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.*
function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE);
_changeDefaultAdminDelay
See changeDefaultAdminDelay. Internal function without access restriction.
function _changeDefaultAdminDelay(uint48 newDelay) internal virtual;
rollbackDefaultAdminDelay
*Cancels a scheduled {defaultAdminDelay} change. Requirements:
- Only can be called by the current {defaultAdmin}. May emit a DefaultAdminDelayChangeCanceled event.*
function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE);
_rollbackDefaultAdminDelay
See rollbackDefaultAdminDelay. Internal function without access restriction.
function _rollbackDefaultAdminDelay() internal virtual;
_delayChangeWait
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.
See {defaultAdminDelayIncreaseWait}.
function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48);
_setPendingDefaultAdmin
Private setters
Setter of the tuple for pending admin and its schedule. May emit a DefaultAdminTransferCanceled event.
function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private;
_setPendingDelay
Setter of the tuple for pending delay and its schedule. May emit a DefaultAdminDelayChangeCanceled event.
function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private;
_isScheduleSet
Private helpers
Defines if an schedule
is considered set. For consistency purposes.
function _isScheduleSet(uint48 schedule) private pure returns (bool);
_hasSchedulePassed
Defines if an schedule
is considered passed. For consistency purposes.
function _hasSchedulePassed(uint48 schedule) private view returns (bool);
Structs
AccessControlDefaultAdminRulesStorage
Note: storage-location: erc7201:openzeppelin.storage.AccessControlDefaultAdminRules
struct AccessControlDefaultAdminRulesStorage {
address _pendingDefaultAdmin;
uint48 _pendingDefaultAdminSchedule;
uint48 _currentDelay;
address _currentDefaultAdmin;
uint48 _pendingDelay;
uint48 _pendingDelaySchedule;
}