Access

Outdated Version

You're viewing an older version (v3.x) The latest documentation is available for the current version. Click here to visit latest version.

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.
  • TimelockController is used in combination with one of the above two mechanisms. By assigning a role to an instance of the TimelockController contract, the access to the functions controlled by that role will be delayed by some amount of time.

Authorization

Ownable

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.

Modifiers

Functions

Events

onlyOwner() *modifier*

Throws if called by any account other than the owner.

constructor() *internal*

Initializes the contract setting the deployer as the initial owner.

owner() → address *public*

Returns the address of the current owner.

renounceOwnership() *public*

Leaves the contract without owner. It will not be possible to call onlyOwner functions anymore. Can only be called by the current owner.

Renouncing ownership will leave the contract without an owner, thereby removing 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.

OwnershipTransferred(address previousOwner, address newOwner) *event*

AccessControl

Contract module that allows children to implement role-based access control mechanisms.

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.

Functions

Events

hasRole(bytes32 role, address account) → bool *public*

Returns true if account has been granted role.

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.

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.

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.

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.

renounceRole(bytes32 role, address account) *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 granted role, emits a RoleRevoked event.

Requirements:

  • the caller must be account.

_setupRole(bytes32 role, address account) *internal*

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.

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.

_setRoleAdmin(bytes32 role, bytes32 adminRole) *internal*

Sets adminRole as ``role`’s admin role.

Emits a RoleAdminChanged event.

RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 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.

Available since v3.1.

RoleGranted(bytes32 role, address account, address sender) *event*

Emitted when account is granted role.

sender is the account that originated the contract call, an admin role bearer except when using _setupRole.

RoleRevoked(bytes32 role, address account, address 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)

Timelock

TimelockController

Contract module which acts as a timelocked controller. When set as the owner of an Ownable smart contract, it enforces a timelock on all onlyOwner maintenance operations. This gives time for users of the controlled contract to exit before a potentially dangerous maintenance operation is applied.

By default, this contract is self administered, meaning administration tasks have to go through the timelock process. The proposer (resp executor) role is in charge of proposing (resp executing) operations. A common use case is to position this TimelockController as the owner of a smart contract, with a multisig or a DAO as the sole proposer.

Available since v3.3.

Modifiers

Functions

AccessControl

Events

AccessControl

onlyRole(bytes32 role) *modifier*

Modifier to make a function callable only by a certain role. In addition to checking the sender’s role, address(0) 's role is also considered. Granting a role to address(0) is equivalent to enabling this role for everyone.

constructor(uint256 minDelay, address[] proposers, address[] executors) *public*

Initializes the contract with a given minDelay.

receive() *external*

Contract might receive/hold ETH as part of the maintenance process.

isOperation(bytes32 id) → bool pending *public*

Returns whether an id correspond to a registered operation. This includes both Pending, Ready and Done operations.

isOperationPending(bytes32 id) → bool pending *public*

Returns whether an operation is pending or not.

isOperationReady(bytes32 id) → bool ready *public*

Returns whether an operation is ready or not.

isOperationDone(bytes32 id) → bool done *public*

Returns whether an operation is done or not.

getTimestamp(bytes32 id) → uint256 timestamp *public*

Returns the timestamp at with an operation becomes ready (0 for unset operations, 1 for done operations).

getMinDelay() → uint256 duration *public*

Returns the minimum delay for an operation to become valid.

This value can be changed by executing an operation that calls updateDelay.

hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) → bytes32 hash *public*

Returns the identifier of an operation containing a single transaction.

hashOperationBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) → bytes32 hash *public*

Returns the identifier of an operation containing a batch of transactions.

`schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) public

Schedule an operation containing a single transaction.

Emits a CallScheduled event.

Requirements:

*` the caller must have the 'proposer' role.

`scheduleBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt, uint256 delay) public

Schedule an operation containing a batch of transactions.

Emits one CallScheduled event per transaction in the batch.

Requirements:

*` the caller must have the 'proposer' role.

`cancel(bytes32 id) public

Cancel an operation.

Requirements:

*` the caller must have the 'proposer' role.

`execute(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) public

Execute an (ready) operation containing a single transaction.

Emits a CallExecuted event.

Requirements:

*` the caller must have the 'executor' role.

`executeBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) public

Execute an (ready) operation containing a batch of transactions.

Emits one CallExecuted event per transaction in the batch.

Requirements:

*` the caller must have the 'executor' role.

`updateDelay(uint256 newDelay) external

Changes the minimum timelock duration for future operations.

Emits a MinDelayChange event.

Requirements:

*` the caller must be the timelock itself. This can only be achieved by scheduling and later executing an operation where the timelock is the target and the data is the ABI-encoded call to this function.

CallScheduled(bytes32 id, uint256 index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) *event*

Emitted when a call is scheduled as part of operation id.

CallExecuted(bytes32 id, uint256 index, address target, uint256 value, bytes data) *event*

Emitted when a call is performed as part of operation id.

Cancelled(bytes32 id) *event*

Emitted when operation id is cancelled.

`MinDelayChange(uint256 oldDuration, uint256 newDuration) event

Emitted when the minimum delay for future operations is modified.

Terminology

  • Operation: A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see operation lifecycle). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
  • Operation status:
    • Unset: An operation that is not part of the timelock mechanism.
    • Pending: An operation that has been scheduled, before the timer expires.
    • Ready: An operation that has been scheduled, after the timer expires.
    • Done: An operation that has been executed.
  • Predecessor: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations.
  • Role:
    • Proposer: An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations.
    • Executor:` An address (smart contract or EOA) that is in charge of executing operations.

Operation structure

Operation executed by the TimelockControler can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations.

Both operations contain:

  • Target, the address of the smart contract that the timelock should operate on.
  • Value, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction.
  • Data, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role ROLE to ACCOUNT can be encode using web3js as follows:
const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI()
  • Predecessor, that specifies a dependency between operations. This dependency is optional. Use bytes32(0) if the operation does not have any dependency.
  • Salt, used to disambiguate two otherwise identical operations. This can be any random value.

In the case of batched operations, target, value and data are specified as arrays, which must be of the same length.

Operation lifecycle

Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle:

Unset -> Pending -> Pending + Ready -> Done

  • By calling schedule (or scheduleBatch), a proposer moves the operation from the Unset to the Pending state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the getTimestamp method.
  • Once the timer expires, the operation automatically gets the Ready state. At this point, it can be executed.
  • By calling execute (or executeBatch), an executor triggers the operation’s underlying transactions and moves it to the Done state. If the operation has a predecessor, it has to be in the Done state for this transition to succeed.
  • cancel allows proposers to cancel any Pending operation. This resets the operation to the Unset state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled.

Operations status can be queried using the functions:

Roles

Admin

The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, both the timelock and the deployer have this role. After further configuration and testing, the deployer can renounce this role such that all further maintenance operations have to go through the timelock process.

This role is identified by the TIMELOCK_ADMIN_ROLE value: 0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5

Proposer

The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO.

Proposer fight: Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers.

This role is identified by the PROPOSER_ROLE value: 0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1

Executor

The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executor can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers.

This role is identified by the EXECUTOR_ROLE value: 0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63

A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the AccessControl documentation to learn more about role management.

On this page

AuthorizationOwnableonlyOwner() *modifier*constructor() *internal*owner() → address *public*renounceOwnership() *public*transferOwnership(address newOwner) *public*OwnershipTransferred(address previousOwner, address newOwner) *event*AccessControlhasRole(bytes32 role, address account) → bool *public*getRoleMemberCount(bytes32 role) → uint256 *public*getRoleMember(bytes32 role, uint256 index) → address *public*getRoleAdmin(bytes32 role) → bytes32 *public*grantRole(bytes32 role, address account) *public*revokeRole(bytes32 role, address account) *public*renounceRole(bytes32 role, address account) *public*_setupRole(bytes32 role, address account) *internal*_setRoleAdmin(bytes32 role, bytes32 adminRole) *internal*RoleAdminChanged(bytes32 role, bytes32 previousAdminRole, bytes32 newAdminRole) *event*RoleGranted(bytes32 role, address account, address sender) *event*RoleRevoked(bytes32 role, address account, address sender) *event*TimelockTimelockControlleronlyRole(bytes32 role) *modifier*constructor(uint256 minDelay, address[] proposers, address[] executors) *public*receive() *external*isOperation(bytes32 id) → bool pending *public*isOperationPending(bytes32 id) → bool pending *public*isOperationReady(bytes32 id) → bool ready *public*isOperationDone(bytes32 id) → bool done *public*getTimestamp(bytes32 id) → uint256 timestamp *public*getMinDelay() → uint256 duration *public*hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) → bytes32 hash *public*hashOperationBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) → bytes32 hash *public*`schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) public`scheduleBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt, uint256 delay) public`cancel(bytes32 id) public`execute(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) public`executeBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) public`updateDelay(uint256 newDelay) externalCallScheduled(bytes32 id, uint256 index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay) *event*CallExecuted(bytes32 id, uint256 index, address target, uint256 value, bytes data) *event*Cancelled(bytes32 id) *event*`MinDelayChange(uint256 oldDuration, uint256 newDuration) eventTerminologyOperation structureOperation lifecycleRolesAdminProposerExecutor