View Source: openzeppelin-solidity/contracts/governance/TimelockController.sol
↗ Extends: AccessControl ↘ Derived Contracts: Delayable
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.
Constants & Variables
//public members
bytes32 public constant TIMELOCK_ADMIN_ROLE;
bytes32 public constant PROPOSER_ROLE;
bytes32 public constant EXECUTOR_ROLE;
//internal members
uint256 internal constant _DONE_TIMESTAMP;
//private members
mapping(bytes32 => uint256) private _timestamps;
uint256 private _minDelay;
Events
event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay);
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
event Cancelled(bytes32 indexed id);
event MinDelayChange(uint256 oldDuration, uint256 newDuration);
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.
modifier onlyRoleOrOpenRole(bytes32 role) internal
Arguments
Name | Type | Description |
---|---|---|
role | bytes32 |
- constructor(uint256 minDelay, address[] proposers, address[] executors)
- constructor()
- isOperation(bytes32 id)
- isOperationPending(bytes32 id)
- isOperationReady(bytes32 id)
- isOperationDone(bytes32 id)
- getTimestamp(bytes32 id)
- getMinDelay()
- hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt)
- hashOperationBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt)
- schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay)
- scheduleBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt, uint256 delay)
- _schedule(bytes32 id, uint256 delay)
- cancel(bytes32 id)
- execute(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt)
- executeBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt)
- _beforeCall(bytes32 id, bytes32 predecessor)
- _afterCall(bytes32 id)
- _call(bytes32 id, uint256 index, address target, uint256 value, bytes data)
- updateDelay(uint256 newDelay)
Initializes the contract with a given minDelay
.
function (uint256 minDelay, address[] proposers, address[] executors) public nonpayable
Arguments
Name | Type | Description |
---|---|---|
minDelay | uint256 | |
proposers | address[] | |
executors | address[] |
Source Code
constructor(
uint256 minDelay,
address[] memory proposers,
address[] memory executors
) {
_setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);
// deployer + self administration
_setupRole(TIMELOCK_ADMIN_ROLE, _msgSender());
_setupRole(TIMELOCK_ADMIN_ROLE, address(this));
// register proposers
for (uint256 i = 0; i < proposers.length; ++i) {
_setupRole(PROPOSER_ROLE, proposers[i]);
}
// register executors
for (uint256 i = 0; i < executors.length; ++i) {
_setupRole(EXECUTOR_ROLE, executors[i]);
}
_minDelay = minDelay;
emit MinDelayChange(0, minDelay);
}
Contract might receive/hold ETH as part of the maintenance process.
function () external payable
Arguments
Name | Type | Description |
---|
Source Code
receive() external payable {}
Returns whether an id correspond to a registered operation. This includes both Pending, Ready and Done operations.
function isOperation(bytes32 id) public view
returns(pending bool)
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function isOperation(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > 0;
}
Returns whether an operation is pending or not.
function isOperationPending(bytes32 id) public view
returns(pending bool)
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function isOperationPending(bytes32 id) public view virtual returns (bool pending) {
return getTimestamp(id) > _DONE_TIMESTAMP;
}
Returns whether an operation is ready or not.
function isOperationReady(bytes32 id) public view
returns(ready bool)
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function isOperationReady(bytes32 id) public view virtual returns (bool ready) {
uint256 timestamp = getTimestamp(id);
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
}
Returns whether an operation is done or not.
function isOperationDone(bytes32 id) public view
returns(done bool)
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function isOperationDone(bytes32 id) public view virtual returns (bool done) {
return getTimestamp(id) == _DONE_TIMESTAMP;
}
Returns the timestamp at with an operation becomes ready (0 for unset operations, 1 for done operations).
function getTimestamp(bytes32 id) public view
returns(timestamp uint256)
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {
return _timestamps[id];
}
Returns the minimum delay for an operation to become valid.
This value can be changed by executing an operation that calls updateDelay
.
function getMinDelay() public view
returns(duration uint256)
Arguments
Name | Type | Description |
---|
Source Code
function getMinDelay() public view virtual returns (uint256 duration) {
return _minDelay;
}
Returns the identifier of an operation containing a single transaction.
function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) public pure
returns(hash bytes32)
Arguments
Name | Type | Description |
---|---|---|
target | address | |
value | uint256 | |
data | bytes | |
predecessor | bytes32 | |
salt | bytes32 |
Source Code
function hashOperation(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(target, value, data, predecessor, salt));
}
Returns the identifier of an operation containing a batch of transactions.
function hashOperationBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) public pure
returns(hash bytes32)
Arguments
Name | Type | Description |
---|---|---|
targets | address[] | |
values | uint256[] | |
datas | bytes[] | |
predecessor | bytes32 | |
salt | bytes32 |
Source Code
function hashOperationBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32 hash) {
return keccak256(abi.encode(targets, values, datas, predecessor, salt));
}
Schedule an operation containing a single transaction. Emits a {CallScheduled} event. Requirements:
- the caller must have the 'proposer' role.
function schedule(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt, uint256 delay) public nonpayable onlyRole
Arguments
Name | Type | Description |
---|---|---|
target | address | |
value | uint256 | |
data | bytes | |
predecessor | bytes32 | |
salt | bytes32 | |
delay | uint256 |
Source Code
function schedule(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_schedule(id, delay);
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
}
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.
function scheduleBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt, uint256 delay) public nonpayable onlyRole
Arguments
Name | Type | Description |
---|---|---|
targets | address[] | |
values | uint256[] | |
datas | bytes[] | |
predecessor | bytes32 | |
salt | bytes32 | |
delay | uint256 |
Source Code
function scheduleBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_schedule(id, delay);
for (uint256 i = 0; i < targets.length; ++i) {
emit CallScheduled(id, i, targets[i], values[i], datas[i], predecessor, delay);
}
}
Schedule an operation that is to becomes valid after a given delay.
function _schedule(bytes32 id, uint256 delay) private nonpayable
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 | |
delay | uint256 |
Source Code
function _schedule(bytes32 id, uint256 delay) private {
require(!isOperation(id), "TimelockController: operation already scheduled");
require(delay >= getMinDelay(), "TimelockController: insufficient delay");
_timestamps[id] = block.timestamp + delay;
}
Cancel an operation. Requirements:
- the caller must have the 'proposer' role.
function cancel(bytes32 id) public nonpayable onlyRole
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function cancel(bytes32 id) public virtual onlyRole(PROPOSER_ROLE) {
require(isOperationPending(id), "TimelockController: operation cannot be cancelled");
delete _timestamps[id];
emit Cancelled(id);
}
Execute an (ready) operation containing a single transaction. Emits a {CallExecuted} event. Requirements:
- the caller must have the 'executor' role.
function execute(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) public payable onlyRoleOrOpenRole
Arguments
Name | Type | Description |
---|---|---|
target | address | |
value | uint256 | |
data | bytes | |
predecessor | bytes32 | |
salt | bytes32 |
Source Code
function execute(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_beforeCall(id, predecessor);
_call(id, 0, target, value, data);
_afterCall(id);
}
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.
function executeBatch(address[] targets, uint256[] values, bytes[] datas, bytes32 predecessor, bytes32 salt) public payable onlyRoleOrOpenRole
Arguments
Name | Type | Description |
---|---|---|
targets | address[] | |
values | uint256[] | |
datas | bytes[] | |
predecessor | bytes32 | |
salt | bytes32 |
Source Code
function executeBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata datas,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
require(targets.length == values.length, "TimelockController: length mismatch");
require(targets.length == datas.length, "TimelockController: length mismatch");
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], datas[i]);
}
_afterCall(id);
}
Checks before execution of an operation's calls.
function _beforeCall(bytes32 id, bytes32 predecessor) private view
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 | |
predecessor | bytes32 |
Source Code
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
require(isOperationReady(id), "TimelockController: operation is not ready");
require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
}
Checks after execution of an operation's calls.
function _afterCall(bytes32 id) private nonpayable
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 |
Source Code
function _afterCall(bytes32 id) private {
require(isOperationReady(id), "TimelockController: operation is not ready");
_timestamps[id] = _DONE_TIMESTAMP;
}
Execute an operation's call. Emits a {CallExecuted} event.
function _call(bytes32 id, uint256 index, address target, uint256 value, bytes data) private nonpayable
Arguments
Name | Type | Description |
---|---|---|
id | bytes32 | |
index | uint256 | |
target | address | |
value | uint256 | |
data | bytes |
Source Code
function _call(
bytes32 id,
uint256 index,
address target,
uint256 value,
bytes calldata data
) private {
(bool success, ) = target.call{value: value}(data);
require(success, "TimelockController: underlying transaction reverted");
emit CallExecuted(id, index, target, value, data);
}
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.
function updateDelay(uint256 newDelay) external nonpayable
Arguments
Name | Type | Description |
---|---|---|
newDelay | uint256 |
Source Code
function updateDelay(uint256 newDelay) external virtual {
require(msg.sender == address(this), "TimelockController: caller must be timelock");
emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay;
}
- AaveStrategy
- AccessControl
- AccessControlLibV1
- Address
- BaseLibV1
- BokkyPooBahsDateTimeLibrary
- BondPool
- BondPoolBase
- BondPoolLibV1
- CompoundStrategy
- console
- Context
- Cover
- CoverBase
- CoverLibV1
- CoverProvision
- CoverReassurance
- CoverStake
- CoverUtilV1
- cxToken
- cxTokenFactory
- cxTokenFactoryLibV1
- Delayable
- Destroyable
- ERC165
- ERC20
- FakeAaveLendingPool
- FakeCompoundDaiDelegator
- FakeRecoverable
- FakeStore
- FakeToken
- FakeUniswapPair
- FakeUniswapV2FactoryLike
- FakeUniswapV2PairLike
- FakeUniswapV2RouterLike
- FaultyAaveLendingPool
- FaultyCompoundDaiDelegator
- Finalization
- ForceEther
- Governance
- GovernanceUtilV1
- IAaveV2LendingPoolLike
- IAccessControl
- IBondPool
- IClaimsProcessor
- ICompoundERC20DelegatorLike
- ICover
- ICoverProvision
- ICoverReassurance
- ICoverStake
- ICxToken
- ICxTokenFactory
- IERC165
- IERC20
- IERC20Detailed
- IERC20Metadata
- IERC3156FlashBorrower
- IERC3156FlashLender
- IFinalization
- IGovernance
- ILendingStrategy
- ILiquidityEngine
- IMember
- InvalidStrategy
- IPausable
- IPolicy
- IPolicyAdmin
- IPriceDiscovery
- IProtocol
- IRecoverable
- IReporter
- IResolution
- IResolvable
- IStakingPools
- IStore
- IUniswapV2FactoryLike
- IUniswapV2PairLike
- IUniswapV2RouterLike
- IUnstakable
- IVault
- IVaultDelegate
- IVaultFactory
- IWitness
- LiquidityEngine
- MaliciousToken
- MockCxToken
- MockCxTokenPolicy
- MockCxTokenStore
- MockFlashBorrower
- MockProcessorStore
- MockProcessorStoreLib
- MockProtocol
- MockStore
- MockVault
- NPM
- NTransferUtilV2
- NTransferUtilV2Intermediate
- Ownable
- Pausable
- Policy
- PolicyAdmin
- PolicyHelperV1
- PoorMansERC20
- PriceDiscovery
- PriceLibV1
- Processor
- ProtoBase
- Protocol
- ProtoUtilV1
- Recoverable
- ReentrancyGuard
- RegistryLibV1
- Reporter
- Resolution
- Resolvable
- RoutineInvokerLibV1
- SafeERC20
- StakingPoolBase
- StakingPoolCoreLibV1
- StakingPoolInfo
- StakingPoolLibV1
- StakingPoolReward
- StakingPools
- Store
- StoreBase
- StoreKeyUtil
- StrategyLibV1
- Strings
- TimelockController
- Unstakable
- ValidationLibV1
- Vault
- VaultBase
- VaultDelegate
- VaultDelegateBase
- VaultDelegateWithFlashLoan
- VaultFactory
- VaultFactoryLibV1
- VaultLibV1
- VaultLiquidity
- VaultStrategy
- WithFlashLoan
- WithPausability
- WithRecovery
- Witness