Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a customizable _execute function in TimelockController #3317

Merged
merged 9 commits into from Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## Unreleased
* `ERC2981`: make `royaltiInfo` public to allow super call in overrides. ([#3305](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3305))
* `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317))

## Unreleased

Expand Down
46 changes: 24 additions & 22 deletions contracts/governance/TimelockController.sol
Expand Up @@ -6,6 +6,7 @@ pragma solidity ^0.8.0;
import "../access/AccessControl.sol";
import "../token/ERC721/IERC721Receiver.sol";
import "../token/ERC1155/IERC1155Receiver.sol";
import "../utils/Address.sol";

/**
* @dev Contract module which acts as a timelocked controller. When set as the
Expand Down Expand Up @@ -288,13 +289,15 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
function execute(
address target,
uint256 value,
bytes calldata data,
bytes calldata payload,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
bytes32 id = hashOperation(target, value, payload, predecessor, salt);

_beforeCall(id, predecessor);
_call(id, 0, target, value, data);
_execute(target, value, payload);
emit CallExecuted(id, 0, target, value, payload);
_afterCall(id);
}

Expand All @@ -318,13 +321,30 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
require(targets.length == payloads.length, "TimelockController: length mismatch");

bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);

_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
_call(id, i, targets[i], values[i], payloads[i]);
address target = targets[i];
uint256 value = values[i];
bytes calldata payload = payloads[i];
_execute(target, value, payload);
emit CallExecuted(id, i, target, value, payload);
}
_afterCall(id);
}

/**
* @dev Execute an operation's call.
*/
function _execute(
address target,
uint256 value,
bytes calldata data
) internal virtual {
(bool success, ) = target.call{value: value}(data);
require(success, "TimelockController: underlying transaction reverted");
}

/**
* @dev Checks before execution of an operation's calls.
*/
Expand All @@ -341,24 +361,6 @@ contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver
_timestamps[id] = _DONE_TIMESTAMP;
}

/**
* @dev Execute an operation's call.
*
* Emits a {CallExecuted} event.
*/
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);
}

/**
* @dev Changes the minimum timelock duration for future operations.
*
Expand Down