mirror of
https://github.com/th30d4y/OpenLearnX.git
synced 2026-05-26 19:26:33 +00:00
Fix .gitignore: stop tracking ignored files
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./IAccessControl.sol";
|
||||
import "../utils/Context.sol";
|
||||
import "../utils/Strings.sol";
|
||||
import "../utils/introspection/ERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev 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:
|
||||
*
|
||||
* ```solidity
|
||||
* 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}:
|
||||
*
|
||||
* ```solidity
|
||||
* 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}.
|
||||
*
|
||||
* WARNING: 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.
|
||||
*/
|
||||
abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
struct RoleData {
|
||||
mapping(address => bool) members;
|
||||
bytes32 adminRole;
|
||||
}
|
||||
|
||||
mapping(bytes32 => RoleData) private _roles;
|
||||
|
||||
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
|
||||
|
||||
/**
|
||||
* @dev Modifier that checks that an account has a specific role. Reverts
|
||||
* with a standardized message including the required role.
|
||||
*
|
||||
* The format of the revert reason is given by the following regular expression:
|
||||
*
|
||||
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
|
||||
*
|
||||
* _Available since v4.1._
|
||||
*/
|
||||
modifier onlyRole(bytes32 role) {
|
||||
_checkRole(role);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns `true` if `account` has been granted `role`.
|
||||
*/
|
||||
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
|
||||
return _roles[role].members[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
|
||||
* Overriding this function changes the behavior of the {onlyRole} modifier.
|
||||
*
|
||||
* Format of the revert message is described in {_checkRole}.
|
||||
*
|
||||
* _Available since v4.6._
|
||||
*/
|
||||
function _checkRole(bytes32 role) internal view virtual {
|
||||
_checkRole(role, _msgSender());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Revert with a standard message if `account` is missing `role`.
|
||||
*
|
||||
* The format of the revert reason is given by the following regular expression:
|
||||
*
|
||||
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
|
||||
*/
|
||||
function _checkRole(bytes32 role, address account) internal view virtual {
|
||||
if (!hasRole(role, account)) {
|
||||
revert(
|
||||
string(
|
||||
abi.encodePacked(
|
||||
"AccessControl: account ",
|
||||
Strings.toHexString(account),
|
||||
" is missing role ",
|
||||
Strings.toHexString(uint256(role), 32)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the admin role that controls `role`. See {grantRole} and
|
||||
* {revokeRole}.
|
||||
*
|
||||
* To change a role's admin, use {_setRoleAdmin}.
|
||||
*/
|
||||
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
|
||||
return _roles[role].adminRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
|
||||
_grantRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
|
||||
_revokeRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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 `account`.
|
||||
*
|
||||
* May emit a {RoleRevoked} event.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual override {
|
||||
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
|
||||
|
||||
_revokeRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Grants `role` to `account`.
|
||||
*
|
||||
* If `account` had not been already granted `role`, emits a {RoleGranted}
|
||||
* event. Note that unlike {grantRole}, this function doesn't perform any
|
||||
* checks on the calling account.
|
||||
*
|
||||
* May emit a {RoleGranted} event.
|
||||
*
|
||||
* [WARNING]
|
||||
* ====
|
||||
* This function should only be called from the constructor when setting
|
||||
* up the initial roles for the system.
|
||||
*
|
||||
* Using this function in any other way is effectively circumventing the admin
|
||||
* system imposed by {AccessControl}.
|
||||
* ====
|
||||
*
|
||||
* NOTE: This function is deprecated in favor of {_grantRole}.
|
||||
*/
|
||||
function _setupRole(bytes32 role, address account) internal virtual {
|
||||
_grantRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets `adminRole` as ``role``'s admin role.
|
||||
*
|
||||
* Emits a {RoleAdminChanged} event.
|
||||
*/
|
||||
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
|
||||
bytes32 previousAdminRole = getRoleAdmin(role);
|
||||
_roles[role].adminRole = adminRole;
|
||||
emit RoleAdminChanged(role, previousAdminRole, adminRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Grants `role` to `account`.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*
|
||||
* May emit a {RoleGranted} event.
|
||||
*/
|
||||
function _grantRole(bytes32 role, address account) internal virtual {
|
||||
if (!hasRole(role, account)) {
|
||||
_roles[role].members[account] = true;
|
||||
emit RoleGranted(role, account, _msgSender());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Revokes `role` from `account`.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*
|
||||
* May emit a {RoleRevoked} event.
|
||||
*/
|
||||
function _revokeRole(bytes32 role, address account) internal virtual {
|
||||
if (hasRole(role, account)) {
|
||||
_roles[role].members[account] = false;
|
||||
emit RoleRevoked(role, account, _msgSender());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControlCrossChain.sol)
|
||||
|
||||
pragma solidity ^0.8.4;
|
||||
|
||||
import "./AccessControl.sol";
|
||||
import "../crosschain/CrossChainEnabled.sol";
|
||||
|
||||
/**
|
||||
* @dev An extension to {AccessControl} with support for cross-chain access management.
|
||||
* For each role, is extension implements an equivalent "aliased" role that is used for
|
||||
* restricting calls originating from other chains.
|
||||
*
|
||||
* For example, if a function `myFunction` is protected by `onlyRole(SOME_ROLE)`, and
|
||||
* if an address `x` has role `SOME_ROLE`, it would be able to call `myFunction` directly.
|
||||
* A wallet or contract at the same address on another chain would however not be able
|
||||
* to call this function. In order to do so, it would require to have the role
|
||||
* `_crossChainRoleAlias(SOME_ROLE)`.
|
||||
*
|
||||
* This aliasing is required to protect against multiple contracts living at the same
|
||||
* address on different chains but controlled by conflicting entities.
|
||||
*
|
||||
* _Available since v4.6._
|
||||
*/
|
||||
abstract contract AccessControlCrossChain is AccessControl, CrossChainEnabled {
|
||||
bytes32 public constant CROSSCHAIN_ALIAS = keccak256("CROSSCHAIN_ALIAS");
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-_checkRole}.
|
||||
*/
|
||||
function _checkRole(bytes32 role) internal view virtual override {
|
||||
if (_isCrossChain()) {
|
||||
_checkRole(_crossChainRoleAlias(role), _crossChainSender());
|
||||
} else {
|
||||
super._checkRole(role);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the aliased role corresponding to `role`.
|
||||
*/
|
||||
function _crossChainRoleAlias(bytes32 role) internal pure virtual returns (bytes32) {
|
||||
return role ^ CROSSCHAIN_ALIAS;
|
||||
}
|
||||
}
|
||||
+383
@@ -0,0 +1,383 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControlDefaultAdminRules.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./AccessControl.sol";
|
||||
import "./IAccessControlDefaultAdminRules.sol";
|
||||
import "../utils/math/SafeCast.sol";
|
||||
import "../interfaces/IERC5313.sol";
|
||||
|
||||
/**
|
||||
* @dev 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:
|
||||
*
|
||||
* ```solidity
|
||||
* contract MyToken is AccessControlDefaultAdminRules {
|
||||
* constructor() AccessControlDefaultAdminRules(
|
||||
* 3 days,
|
||||
* msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder
|
||||
* ) {}
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* _Available since v4.9._
|
||||
*/
|
||||
abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl {
|
||||
// pending admin pair read/written together frequently
|
||||
address private _pendingDefaultAdmin;
|
||||
uint48 private _pendingDefaultAdminSchedule; // 0 == unset
|
||||
|
||||
uint48 private _currentDelay;
|
||||
address private _currentDefaultAdmin;
|
||||
|
||||
// pending delay pair read/written together frequently
|
||||
uint48 private _pendingDelay;
|
||||
uint48 private _pendingDelaySchedule; // 0 == unset
|
||||
|
||||
/**
|
||||
* @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.
|
||||
*/
|
||||
constructor(uint48 initialDelay, address initialDefaultAdmin) {
|
||||
require(initialDefaultAdmin != address(0), "AccessControl: 0 default admin");
|
||||
_currentDelay = initialDelay;
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC5313-owner}.
|
||||
*/
|
||||
function owner() public view virtual returns (address) {
|
||||
return defaultAdmin();
|
||||
}
|
||||
|
||||
///
|
||||
/// Override AccessControl role management
|
||||
///
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't directly grant default admin role");
|
||||
super.grantRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't directly revoke default admin role");
|
||||
super.revokeRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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(AccessControl, IAccessControl) {
|
||||
if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
|
||||
(address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();
|
||||
require(
|
||||
newDefaultAdmin == address(0) && _isScheduleSet(schedule) && _hasSchedulePassed(schedule),
|
||||
"AccessControl: only can renounce in two delayed steps"
|
||||
);
|
||||
delete _pendingDefaultAdminSchedule;
|
||||
}
|
||||
super.renounceRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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 {
|
||||
if (role == DEFAULT_ADMIN_ROLE) {
|
||||
require(defaultAdmin() == address(0), "AccessControl: default admin already granted");
|
||||
_currentDefaultAdmin = account;
|
||||
}
|
||||
super._grantRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-_revokeRole}.
|
||||
*/
|
||||
function _revokeRole(bytes32 role, address account) internal virtual override {
|
||||
if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {
|
||||
delete _currentDefaultAdmin;
|
||||
}
|
||||
super._revokeRole(role, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.
|
||||
*/
|
||||
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {
|
||||
require(role != DEFAULT_ADMIN_ROLE, "AccessControl: can't violate default admin rules");
|
||||
super._setRoleAdmin(role, adminRole);
|
||||
}
|
||||
|
||||
///
|
||||
/// AccessControlDefaultAdminRules accessors
|
||||
///
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function defaultAdmin() public view virtual returns (address) {
|
||||
return _currentDefaultAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) {
|
||||
return (_pendingDefaultAdmin, _pendingDefaultAdminSchedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function defaultAdminDelay() public view virtual returns (uint48) {
|
||||
uint48 schedule = _pendingDelaySchedule;
|
||||
return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? _pendingDelay : _currentDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) {
|
||||
schedule = _pendingDelaySchedule;
|
||||
return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? (_pendingDelay, schedule) : (0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) {
|
||||
return 5 days;
|
||||
}
|
||||
|
||||
///
|
||||
/// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin
|
||||
///
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_beginDefaultAdminTransfer(newAdmin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {beginDefaultAdminTransfer}.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _beginDefaultAdminTransfer(address newAdmin) internal virtual {
|
||||
uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay();
|
||||
_setPendingDefaultAdmin(newAdmin, newSchedule);
|
||||
emit DefaultAdminTransferScheduled(newAdmin, newSchedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_cancelDefaultAdminTransfer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {cancelDefaultAdminTransfer}.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _cancelDefaultAdminTransfer() internal virtual {
|
||||
_setPendingDefaultAdmin(address(0), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function acceptDefaultAdminTransfer() public virtual {
|
||||
(address newDefaultAdmin, ) = pendingDefaultAdmin();
|
||||
require(_msgSender() == newDefaultAdmin, "AccessControl: pending admin must accept");
|
||||
_acceptDefaultAdminTransfer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {acceptDefaultAdminTransfer}.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _acceptDefaultAdminTransfer() internal virtual {
|
||||
(address newAdmin, uint48 schedule) = pendingDefaultAdmin();
|
||||
require(_isScheduleSet(schedule) && _hasSchedulePassed(schedule), "AccessControl: transfer delay not passed");
|
||||
_revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());
|
||||
_grantRole(DEFAULT_ADMIN_ROLE, newAdmin);
|
||||
delete _pendingDefaultAdmin;
|
||||
delete _pendingDefaultAdminSchedule;
|
||||
}
|
||||
|
||||
///
|
||||
/// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay
|
||||
///
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_changeDefaultAdminDelay(newDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {changeDefaultAdminDelay}.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _changeDefaultAdminDelay(uint48 newDelay) internal virtual {
|
||||
uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay);
|
||||
_setPendingDelay(newDelay, newSchedule);
|
||||
emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc IAccessControlDefaultAdminRules
|
||||
*/
|
||||
function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {
|
||||
_rollbackDefaultAdminDelay();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {rollbackDefaultAdminDelay}.
|
||||
*
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _rollbackDefaultAdminDelay() internal virtual {
|
||||
_setPendingDelay(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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) {
|
||||
uint48 currentDelay = defaultAdminDelay();
|
||||
|
||||
// When increasing the delay, we schedule the delay change to occur after a period of "new delay" has passed, up
|
||||
// to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day
|
||||
// to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new
|
||||
// delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like
|
||||
// using milliseconds instead of seconds.
|
||||
//
|
||||
// When decreasing the delay, we wait the difference between "current delay" and "new delay". This guarantees
|
||||
// that an admin transfer cannot be made faster than "current delay" at the time the delay change is scheduled.
|
||||
// For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days.
|
||||
return
|
||||
newDelay > currentDelay
|
||||
? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48
|
||||
: currentDelay - newDelay;
|
||||
}
|
||||
|
||||
///
|
||||
/// Private setters
|
||||
///
|
||||
|
||||
/**
|
||||
* @dev Setter of the tuple for pending admin and its schedule.
|
||||
*
|
||||
* May emit a DefaultAdminTransferCanceled event.
|
||||
*/
|
||||
function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private {
|
||||
(, uint48 oldSchedule) = pendingDefaultAdmin();
|
||||
|
||||
_pendingDefaultAdmin = newAdmin;
|
||||
_pendingDefaultAdminSchedule = newSchedule;
|
||||
|
||||
// An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted.
|
||||
if (_isScheduleSet(oldSchedule)) {
|
||||
// Emit for implicit cancellations when another default admin was scheduled.
|
||||
emit DefaultAdminTransferCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Setter of the tuple for pending delay and its schedule.
|
||||
*
|
||||
* May emit a DefaultAdminDelayChangeCanceled event.
|
||||
*/
|
||||
function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private {
|
||||
uint48 oldSchedule = _pendingDelaySchedule;
|
||||
|
||||
if (_isScheduleSet(oldSchedule)) {
|
||||
if (_hasSchedulePassed(oldSchedule)) {
|
||||
// Materialize a virtual delay
|
||||
_currentDelay = _pendingDelay;
|
||||
} else {
|
||||
// Emit for implicit cancellations when another delay was scheduled.
|
||||
emit DefaultAdminDelayChangeCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
_pendingDelay = newDelay;
|
||||
_pendingDelaySchedule = newSchedule;
|
||||
}
|
||||
|
||||
///
|
||||
/// Private helpers
|
||||
///
|
||||
|
||||
/**
|
||||
* @dev Defines if an `schedule` is considered set. For consistency purposes.
|
||||
*/
|
||||
function _isScheduleSet(uint48 schedule) private pure returns (bool) {
|
||||
return schedule != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Defines if an `schedule` is considered passed. For consistency purposes.
|
||||
*/
|
||||
function _hasSchedulePassed(uint48 schedule) private view returns (bool) {
|
||||
return schedule < block.timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./IAccessControlEnumerable.sol";
|
||||
import "./AccessControl.sol";
|
||||
import "../utils/structs/EnumerableSet.sol";
|
||||
|
||||
/**
|
||||
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
|
||||
*/
|
||||
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*
|
||||
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
|
||||
* you perform all queries on the same block. See the following
|
||||
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
|
||||
* for more information.
|
||||
*/
|
||||
function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
|
||||
return _roleMembers[role].at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of accounts that have `role`. Can be used
|
||||
* together with {getRoleMember} to enumerate all bearers of a role.
|
||||
*/
|
||||
function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
|
||||
return _roleMembers[role].length();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overload {_grantRole} to track enumerable memberships
|
||||
*/
|
||||
function _grantRole(bytes32 role, address account) internal virtual override {
|
||||
super._grantRole(role, account);
|
||||
_roleMembers[role].add(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overload {_revokeRole} to track enumerable memberships
|
||||
*/
|
||||
function _revokeRole(bytes32 role, address account) internal virtual override {
|
||||
super._revokeRole(role, account);
|
||||
_roleMembers[role].remove(account);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControl declared to support ERC165 detection.
|
||||
*/
|
||||
interface IAccessControl {
|
||||
/**
|
||||
* @dev 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.
|
||||
*
|
||||
* _Available since v3.1._
|
||||
*/
|
||||
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `account` is granted `role`.
|
||||
*
|
||||
* `sender` is the account that originated the contract call, an admin role
|
||||
* bearer except when using {AccessControl-_setupRole}.
|
||||
*/
|
||||
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
|
||||
|
||||
/**
|
||||
* @dev 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`)
|
||||
*/
|
||||
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
|
||||
|
||||
/**
|
||||
* @dev Returns `true` if `account` has been granted `role`.
|
||||
*/
|
||||
function hasRole(bytes32 role, address account) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Returns the admin role that controls `role`. See {grantRole} and
|
||||
* {revokeRole}.
|
||||
*
|
||||
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
|
||||
*/
|
||||
function getRoleAdmin(bytes32 role) external view returns (bytes32);
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) external;
|
||||
|
||||
/**
|
||||
* @dev Revokes `role` from `account`.
|
||||
*
|
||||
* If `account` had been granted `role`, emits a {RoleRevoked} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - the caller must have ``role``'s admin role.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) external;
|
||||
|
||||
/**
|
||||
* @dev 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 `account`.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) external;
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/IAccessControlDefaultAdminRules.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./IAccessControl.sol";
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControlDefaultAdminRules declared to support ERC165 detection.
|
||||
*
|
||||
* _Available since v4.9._
|
||||
*/
|
||||
interface IAccessControlDefaultAdminRules is IAccessControl {
|
||||
/**
|
||||
* @dev Emitted when a {defaultAdmin} transfer is started, setting `newAdmin` as the next
|
||||
* address to become the {defaultAdmin} by calling {acceptDefaultAdminTransfer} only after `acceptSchedule`
|
||||
* passes.
|
||||
*/
|
||||
event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a {pendingDefaultAdmin} is reset if it was never accepted, regardless of its schedule.
|
||||
*/
|
||||
event DefaultAdminTransferCanceled();
|
||||
|
||||
/**
|
||||
* @dev Emitted when a {defaultAdminDelay} change is started, setting `newDelay` as the next
|
||||
* delay to be applied between default admin transfer after `effectSchedule` has passed.
|
||||
*/
|
||||
event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a {pendingDefaultAdminDelay} is reset if its schedule didn't pass.
|
||||
*/
|
||||
event DefaultAdminDelayChangeCanceled();
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.
|
||||
*/
|
||||
function defaultAdmin() external view returns (address);
|
||||
|
||||
/**
|
||||
* @dev 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() external view returns (address newAdmin, uint48 acceptSchedule);
|
||||
|
||||
/**
|
||||
* @dev 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() external view returns (uint48);
|
||||
|
||||
/**
|
||||
* @dev 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() external view returns (uint48 newDelay, uint48 effectSchedule);
|
||||
|
||||
/**
|
||||
* @dev 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) external;
|
||||
|
||||
/**
|
||||
* @dev 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() external;
|
||||
|
||||
/**
|
||||
* @dev 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() external;
|
||||
|
||||
/**
|
||||
* @dev 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) external;
|
||||
|
||||
/**
|
||||
* @dev Cancels a scheduled {defaultAdminDelay} change.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Only can be called by the current {defaultAdmin}.
|
||||
*
|
||||
* May emit a DefaultAdminDelayChangeCanceled event.
|
||||
*/
|
||||
function rollbackDefaultAdminDelay() external;
|
||||
|
||||
/**
|
||||
* @dev 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() external view returns (uint48);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./IAccessControl.sol";
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
|
||||
*/
|
||||
interface IAccessControlEnumerable is IAccessControl {
|
||||
/**
|
||||
* @dev 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.
|
||||
*
|
||||
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
|
||||
* you perform all queries on the same block. See the following
|
||||
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
|
||||
* for more information.
|
||||
*/
|
||||
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
|
||||
|
||||
/**
|
||||
* @dev Returns the number of accounts that have `role`. Can be used
|
||||
* together with {getRoleMember} to enumerate all bearers of a role.
|
||||
*/
|
||||
function getRoleMemberCount(bytes32 role) external view returns (uint256);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Context.sol";
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*
|
||||
* By default, the owner account will be the one that deploys the contract. 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.
|
||||
*/
|
||||
abstract contract Ownable is Context {
|
||||
address private _owner;
|
||||
|
||||
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
|
||||
|
||||
/**
|
||||
* @dev Initializes the contract setting the deployer as the initial owner.
|
||||
*/
|
||||
constructor() {
|
||||
_transferOwnership(_msgSender());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if called by any account other than the owner.
|
||||
*/
|
||||
modifier onlyOwner() {
|
||||
_checkOwner();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the current owner.
|
||||
*/
|
||||
function owner() public view virtual returns (address) {
|
||||
return _owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if the sender is not the owner.
|
||||
*/
|
||||
function _checkOwner() internal view virtual {
|
||||
require(owner() == _msgSender(), "Ownable: caller is not the owner");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Leaves the contract without owner. It will not be possible to call
|
||||
* `onlyOwner` functions. Can only be called by the current owner.
|
||||
*
|
||||
* NOTE: Renouncing ownership will leave the contract without an owner,
|
||||
* thereby disabling any functionality that is only available to the owner.
|
||||
*/
|
||||
function renounceOwnership() public virtual onlyOwner {
|
||||
_transferOwnership(address(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of the contract to a new account (`newOwner`).
|
||||
* Can only be called by the current owner.
|
||||
*/
|
||||
function transferOwnership(address newOwner) public virtual onlyOwner {
|
||||
require(newOwner != address(0), "Ownable: new owner is the zero address");
|
||||
_transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of the contract to a new account (`newOwner`).
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _transferOwnership(address newOwner) internal virtual {
|
||||
address oldOwner = _owner;
|
||||
_owner = newOwner;
|
||||
emit OwnershipTransferred(oldOwner, newOwner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./Ownable.sol";
|
||||
|
||||
/**
|
||||
* @dev Contract module which provides access control mechanism, where
|
||||
* there is an account (an owner) that can be granted exclusive access to
|
||||
* specific functions.
|
||||
*
|
||||
* By default, the owner account will be the one that deploys the contract. This
|
||||
* can later be changed with {transferOwnership} and {acceptOwnership}.
|
||||
*
|
||||
* This module is used through inheritance. It will make available all functions
|
||||
* from parent (Ownable).
|
||||
*/
|
||||
abstract contract Ownable2Step is Ownable {
|
||||
address private _pendingOwner;
|
||||
|
||||
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the pending owner.
|
||||
*/
|
||||
function pendingOwner() public view virtual returns (address) {
|
||||
return _pendingOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 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.
|
||||
*/
|
||||
function transferOwnership(address newOwner) public virtual override onlyOwner {
|
||||
_pendingOwner = newOwner;
|
||||
emit OwnershipTransferStarted(owner(), newOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
|
||||
* Internal function without access restriction.
|
||||
*/
|
||||
function _transferOwnership(address newOwner) internal virtual override {
|
||||
delete _pendingOwner;
|
||||
super._transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev The new owner accepts the ownership transfer.
|
||||
*/
|
||||
function acceptOwnership() public virtual {
|
||||
address sender = _msgSender();
|
||||
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
|
||||
_transferOwnership(sender);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
= Access Control
|
||||
|
||||
[.readme-notice]
|
||||
NOTE: 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.
|
||||
|
||||
- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
|
||||
- {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.
|
||||
|
||||
== Authorization
|
||||
|
||||
{{Ownable}}
|
||||
|
||||
{{Ownable2Step}}
|
||||
|
||||
{{IAccessControl}}
|
||||
|
||||
{{AccessControl}}
|
||||
|
||||
{{AccessControlCrossChain}}
|
||||
|
||||
{{IAccessControlEnumerable}}
|
||||
|
||||
{{AccessControlEnumerable}}
|
||||
|
||||
{{AccessControlDefaultAdminRules}}
|
||||
Reference in New Issue
Block a user