From 0ec7f4c25d60437e0ae5bb72cb4549a58e53a387 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Tue, 24 Aug 2021 16:09:39 -0300 Subject: [PATCH] Add additional isOperationReady check in TimelockController (cherry picked from commit cec4f2ef57495d8b1742d62846da212515d99dd5) --- CHANGELOG.md | 4 ++++ contracts/governance/TimelockController.sol | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b3d458026..7407e25ac0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 4.3.1 + + * `TimelockController`: Add additional isOperationReady check. + ## 4.3.0 (2021-08-17) * `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754)) diff --git a/contracts/governance/TimelockController.sol b/contracts/governance/TimelockController.sol index 10aeb4ee490..e52cb0d3f5a 100644 --- a/contracts/governance/TimelockController.sol +++ b/contracts/governance/TimelockController.sol @@ -268,7 +268,7 @@ contract TimelockController is AccessControl { bytes32 salt ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { bytes32 id = hashOperation(target, value, data, predecessor, salt); - _beforeCall(predecessor); + _beforeCall(id, predecessor); _call(id, 0, target, value, data); _afterCall(id); } @@ -293,7 +293,7 @@ contract TimelockController is AccessControl { require(targets.length == datas.length, "TimelockController: length mismatch"); bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt); - _beforeCall(predecessor); + _beforeCall(id, predecessor); for (uint256 i = 0; i < targets.length; ++i) { _call(id, i, targets[i], values[i], datas[i]); } @@ -303,7 +303,8 @@ contract TimelockController is AccessControl { /** * @dev Checks before execution of an operation's calls. */ - function _beforeCall(bytes32 predecessor) private view { + 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"); }