GovernorTimelockAccess.sol 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.20;
  3. import {Governor} from "../Governor.sol";
  4. import {AuthorityUtils} from "../../access/manager/AuthorityUtils.sol";
  5. import {IAccessManager} from "../../access/manager/IAccessManager.sol";
  6. import {Address} from "../../utils/Address.sol";
  7. import {Math} from "../../utils/math/Math.sol";
  8. import {SafeCast} from "../../utils/math/SafeCast.sol";
  9. import {Time} from "../../utils/types/Time.sol";
  10. /**
  11. * @dev This module connects a {Governor} instance to an {AccessManager} instance, allowing the governor to make calls
  12. * that are delay-restricted by the manager using the normal {queue} workflow. An optional base delay is applied to
  13. * operations that are not delayed externally by the manager. Execution of a proposal will be delayed as much as
  14. * necessary to meet the required delays of all of its operations.
  15. *
  16. * This extension allows the governor to hold and use its own assets and permissions, unlike {GovernorTimelockControl}
  17. * and {GovernorTimelockCompound}, where the timelock is a separate contract that must be the one to hold assets and
  18. * permissions. Operations that are delay-restricted by the manager, however, will be executed through the
  19. * {AccessManager-execute} function.
  20. *
  21. * Note that some operations may be cancelable in the {AccessManager} by the admin or a set of guardians, depending on
  22. * the restricted operation being invoked. Since proposals are atomic, the cancellation by a guardian of a single
  23. * operation in a proposal will cause all of it to become unable to execute.
  24. */
  25. abstract contract GovernorTimelockAccess is Governor {
  26. // An execution plan is produced at the moment a proposal is created, in order to fix at that point the exact
  27. // execution semantics of the proposal, namely whether a call will go through {AccessManager-execute}.
  28. struct ExecutionPlan {
  29. uint16 length;
  30. uint32 delay;
  31. // We use mappings instead of arrays because it allows us to pack values in storage more tightly without
  32. // storing the length redundantly.
  33. // We pack 8 operations' data in each bucket. Each uint32 value is set to 1 upon proposal creation if it has
  34. // to be scheduled and executed through the manager. Upon queuing, the value is set to nonce + 1, where the
  35. // nonce is that which we get back from the manager when scheduling the operation.
  36. mapping(uint256 operationBucket => uint32[8]) managerData;
  37. }
  38. mapping(uint256 proposalId => ExecutionPlan) private _executionPlan;
  39. uint32 private _baseDelay;
  40. IAccessManager private immutable _manager;
  41. error GovernorUnmetDelay(uint256 proposalId, uint256 neededTimestamp);
  42. error GovernorMismatchedNonce(uint256 proposalId, uint256 expectedNonce, uint256 actualNonce);
  43. event BaseDelaySet(uint32 oldBaseDelaySeconds, uint32 newBaseDelaySeconds);
  44. /**
  45. * @dev Initialize the governor with an {AccessManager} and initial base delay.
  46. */
  47. constructor(address manager, uint32 initialBaseDelay) {
  48. _manager = IAccessManager(manager);
  49. _setBaseDelaySeconds(initialBaseDelay);
  50. }
  51. /**
  52. * @dev Returns the {AccessManager} instance associated to this governor.
  53. */
  54. function accessManager() public view virtual returns (IAccessManager) {
  55. return _manager;
  56. }
  57. /**
  58. * @dev Base delay that will be applied to all function calls. Some may be further delayed by their associated
  59. * `AccessManager` authority; in this case the final delay will be the maximum of the base delay and the one
  60. * demanded by the authority.
  61. *
  62. * NOTE: Execution delays are processed by the `AccessManager` contracts, and according to that contract are
  63. * expressed in seconds. Therefore, the base delay is also in seconds, regardless of the governor's clock mode.
  64. */
  65. function baseDelaySeconds() public view virtual returns (uint32) {
  66. return _baseDelay;
  67. }
  68. /**
  69. * @dev Change the value of {baseDelaySeconds}. This operation can only be invoked through a governance proposal.
  70. */
  71. function setBaseDelaySeconds(uint32 newBaseDelay) public virtual onlyGovernance {
  72. _setBaseDelaySeconds(newBaseDelay);
  73. }
  74. /**
  75. * @dev Change the value of {baseDelaySeconds}. Internal function without access control.
  76. */
  77. function _setBaseDelaySeconds(uint32 newBaseDelay) internal virtual {
  78. emit BaseDelaySet(_baseDelay, newBaseDelay);
  79. _baseDelay = newBaseDelay;
  80. }
  81. /**
  82. * @dev Public accessor to check the execution plan, including the number of seconds that the proposal will be
  83. * delayed since queuing, and an array indicating which of the proposal actions will be executed indirectly through
  84. * the associated {AccessManager}.
  85. */
  86. function proposalExecutionPlan(uint256 proposalId) public view returns (uint32, bool[] memory) {
  87. ExecutionPlan storage plan = _executionPlan[proposalId];
  88. uint32 delay = plan.delay;
  89. uint32 length = plan.length;
  90. bool[] memory indirect = new bool[](length);
  91. for (uint256 i = 0; i < length; ++i) {
  92. (indirect[i], ) = _getManagerData(plan, i);
  93. }
  94. return (delay, indirect);
  95. }
  96. /**
  97. * @dev See {IGovernor-proposalNeedsQueuing}.
  98. */
  99. function proposalNeedsQueuing(uint256 proposalId) public view virtual override returns (bool) {
  100. return _executionPlan[proposalId].delay > 0;
  101. }
  102. /**
  103. * @dev See {IGovernor-propose}
  104. */
  105. function propose(
  106. address[] memory targets,
  107. uint256[] memory values,
  108. bytes[] memory calldatas,
  109. string memory description
  110. ) public virtual override returns (uint256) {
  111. uint256 proposalId = super.propose(targets, values, calldatas, description);
  112. uint32 neededDelay = baseDelaySeconds();
  113. ExecutionPlan storage plan = _executionPlan[proposalId];
  114. plan.length = SafeCast.toUint16(targets.length);
  115. for (uint256 i = 0; i < targets.length; ++i) {
  116. uint32 delay = _detectExecutionRequirements(targets[i], bytes4(calldatas[i]));
  117. if (delay > 0) {
  118. _setManagerData(plan, i, 0);
  119. }
  120. // downcast is safe because both arguments are uint32
  121. neededDelay = uint32(Math.max(delay, neededDelay));
  122. }
  123. plan.delay = neededDelay;
  124. return proposalId;
  125. }
  126. /**
  127. * @dev Mechanism to queue a proposal, potentially scheduling some of its operations in the AccessManager.
  128. *
  129. * NOTE: The execution delay is chosen based on the delay information retrieved in {propose}. This value may be
  130. * off if the delay was updated since proposal creation. In this case, the proposal needs to be recreated.
  131. */
  132. function _queueOperations(
  133. uint256 proposalId,
  134. address[] memory targets,
  135. uint256[] memory /* values */,
  136. bytes[] memory calldatas,
  137. bytes32 /* descriptionHash */
  138. ) internal virtual override returns (uint48) {
  139. ExecutionPlan storage plan = _executionPlan[proposalId];
  140. uint48 eta = Time.timestamp() + plan.delay;
  141. for (uint256 i = 0; i < targets.length; ++i) {
  142. (bool delayed, ) = _getManagerData(plan, i);
  143. if (delayed) {
  144. (, uint32 nonce) = _manager.schedule(targets[i], calldatas[i], eta);
  145. _setManagerData(plan, i, nonce);
  146. }
  147. }
  148. return eta;
  149. }
  150. /**
  151. * @dev Mechanism to execute a proposal, potentially going through {AccessManager-execute} for delayed operations.
  152. */
  153. function _executeOperations(
  154. uint256 proposalId,
  155. address[] memory targets,
  156. uint256[] memory values,
  157. bytes[] memory calldatas,
  158. bytes32 /* descriptionHash */
  159. ) internal virtual override {
  160. uint48 eta = SafeCast.toUint48(proposalEta(proposalId));
  161. if (block.timestamp < eta) {
  162. revert GovernorUnmetDelay(proposalId, eta);
  163. }
  164. ExecutionPlan storage plan = _executionPlan[proposalId];
  165. for (uint256 i = 0; i < targets.length; ++i) {
  166. (bool delayed, uint32 nonce) = _getManagerData(plan, i);
  167. if (delayed) {
  168. uint32 executedNonce = _manager.execute{value: values[i]}(targets[i], calldatas[i]);
  169. if (executedNonce != nonce) {
  170. revert GovernorMismatchedNonce(proposalId, nonce, executedNonce);
  171. }
  172. } else {
  173. (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
  174. Address.verifyCallResult(success, returndata);
  175. }
  176. }
  177. }
  178. /**
  179. * @dev See {IGovernor-_cancel}
  180. */
  181. function _cancel(
  182. address[] memory targets,
  183. uint256[] memory values,
  184. bytes[] memory calldatas,
  185. bytes32 descriptionHash
  186. ) internal virtual override returns (uint256) {
  187. uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
  188. uint48 eta = SafeCast.toUint48(proposalEta(proposalId));
  189. ExecutionPlan storage plan = _executionPlan[proposalId];
  190. // If the proposal has been scheduled it will have an ETA and we have to externally cancel
  191. if (eta != 0) {
  192. for (uint256 i = 0; i < targets.length; ++i) {
  193. (bool delayed, uint32 nonce) = _getManagerData(plan, i);
  194. if (delayed) {
  195. // Attempt to cancel considering the operation could have been cancelled and rescheduled already
  196. uint32 canceledNonce = _manager.cancel(address(this), targets[i], calldatas[i]);
  197. if (canceledNonce != nonce) {
  198. revert GovernorMismatchedNonce(proposalId, nonce, canceledNonce);
  199. }
  200. }
  201. }
  202. }
  203. return proposalId;
  204. }
  205. /**
  206. * @dev Check if the execution of a call needs to be performed through an AccessManager and what delay should be
  207. * applied to this call.
  208. *
  209. * Returns { manager: address(0), delay: 0 } if:
  210. * - target does not have code
  211. * - target does not implement IAccessManaged
  212. * - calling canCall on the target's manager returns a 0 delay
  213. * - calling canCall on the target's manager reverts
  214. * Otherwise (calling canCall on the target's manager returns a non 0 delay), return the address of the
  215. * AccessManager to use, and the delay for this call.
  216. */
  217. function _detectExecutionRequirements(address target, bytes4 selector) private view returns (uint32 delay) {
  218. (, delay) = AuthorityUtils.canCallWithDelay(address(_manager), address(this), target, selector);
  219. }
  220. /**
  221. * @dev Returns whether the operation at an index is delayed by the manager, and its scheduling nonce once queued.
  222. */
  223. function _getManagerData(ExecutionPlan storage plan, uint256 index) private view returns (bool, uint32) {
  224. (uint256 bucket, uint256 subindex) = _getManagerDataIndices(index);
  225. uint32 nonce = plan.managerData[bucket][subindex];
  226. unchecked {
  227. return nonce > 0 ? (true, nonce - 1) : (false, 0);
  228. }
  229. }
  230. /**
  231. * @dev Marks an operation at an index as delayed by the manager, and sets its scheduling nonce.
  232. */
  233. function _setManagerData(ExecutionPlan storage plan, uint256 index, uint32 nonce) private {
  234. (uint256 bucket, uint256 subindex) = _getManagerDataIndices(index);
  235. plan.managerData[bucket][subindex] = nonce + 1;
  236. }
  237. /**
  238. * @dev Returns bucket and subindex for reading manager data from the packed array mapping.
  239. */
  240. function _getManagerDataIndices(uint256 index) private pure returns (uint256 bucket, uint256 subindex) {
  241. bucket = index >> 3; // index / 8
  242. subindex = index & 7; // index % 8
  243. }
  244. }