GovernorStorage.sol 4.0 KB

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