GovernorStorage.sol 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.20;
  3. import {Governor} from "../Governor.sol";
  4. /**
  5. * @dev Extension of {Governor} that implements storage of proposal details. This modules also provides primitives for
  6. * the enumerability of proposals.
  7. *
  8. * Use cases for this module include:
  9. * - UIs that explore the proposal state without relying on event indexing.
  10. * - Using only the proposalId as an argument in the {Governor-queue} and {Governor-execute} functions for L2 chains
  11. * where storage is cheap compared to calldata.
  12. */
  13. abstract contract GovernorStorage is Governor {
  14. struct ProposalDetails {
  15. address[] targets;
  16. uint256[] values;
  17. bytes[] calldatas;
  18. bytes32 descriptionHash;
  19. }
  20. uint256[] private _proposalIds;
  21. mapping(uint256 proposalId => ProposalDetails) private _proposalDetails;
  22. /**
  23. * @dev Hook into the proposing mechanism
  24. */
  25. function _propose(
  26. address[] memory targets,
  27. uint256[] memory values,
  28. bytes[] memory calldatas,
  29. string memory description,
  30. address proposer
  31. ) internal virtual override returns (uint256) {
  32. uint256 proposalId = super._propose(targets, values, calldatas, description, proposer);
  33. // store
  34. _proposalIds.push(proposalId);
  35. _proposalDetails[proposalId] = ProposalDetails({
  36. targets: targets,
  37. values: values,
  38. calldatas: calldatas,
  39. descriptionHash: keccak256(bytes(description))
  40. });
  41. return proposalId;
  42. }
  43. /**
  44. * @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument.
  45. */
  46. function queue(uint256 proposalId) public virtual {
  47. // here, using storage is more efficient than memory
  48. ProposalDetails storage details = _proposalDetails[proposalId];
  49. queue(details.targets, details.values, details.calldatas, details.descriptionHash);
  50. }
  51. /**
  52. * @dev Version of {IGovernor-execute} with only `proposalId` as an argument.
  53. */
  54. function execute(uint256 proposalId) public payable virtual {
  55. // here, using storage is more efficient than memory
  56. ProposalDetails storage details = _proposalDetails[proposalId];
  57. execute(details.targets, details.values, details.calldatas, details.descriptionHash);
  58. }
  59. /**
  60. * @dev ProposalId version of {IGovernor-cancel}.
  61. */
  62. function cancel(uint256 proposalId) public virtual {
  63. // here, using storage is more efficient than memory
  64. ProposalDetails storage details = _proposalDetails[proposalId];
  65. cancel(details.targets, details.values, details.calldatas, details.descriptionHash);
  66. }
  67. /**
  68. * @dev Returns the number of stored proposals.
  69. */
  70. function proposalCount() public view virtual returns (uint256) {
  71. return _proposalIds.length;
  72. }
  73. /**
  74. * @dev Returns the details of a proposalId. Reverts if `proposalId` is not a known proposal.
  75. */
  76. function proposalDetails(
  77. uint256 proposalId
  78. ) public view virtual returns (address[] memory, uint256[] memory, bytes[] memory, bytes32) {
  79. // here, using memory is more efficient than storage
  80. ProposalDetails memory details = _proposalDetails[proposalId];
  81. if (details.descriptionHash == 0) {
  82. revert GovernorNonexistentProposal(proposalId);
  83. }
  84. return (details.targets, details.values, details.calldatas, details.descriptionHash);
  85. }
  86. /**
  87. * @dev Returns the details (including the proposalId) of a proposal given its sequential index.
  88. */
  89. function proposalDetailsAt(
  90. uint256 index
  91. ) public view virtual returns (uint256, address[] memory, uint256[] memory, bytes[] memory, bytes32) {
  92. uint256 proposalId = _proposalIds[index];
  93. (
  94. address[] memory targets,
  95. uint256[] memory values,
  96. bytes[] memory calldatas,
  97. bytes32 descriptionHash
  98. ) = proposalDetails(proposalId);
  99. return (proposalId, targets, values, calldatas, descriptionHash);
  100. }
  101. }