GovernorSequentialProposalId.sol 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.3.0-rc.0) (governance/extensions/GovernorSequentialProposalId.sol)
  3. pragma solidity ^0.8.20;
  4. import {Governor} from "../Governor.sol";
  5. /**
  6. * @dev Extension of {Governor} that changes the numbering of proposal ids from the default hash-based approach to
  7. * sequential ids.
  8. */
  9. abstract contract GovernorSequentialProposalId is Governor {
  10. uint256 private _latestProposalId;
  11. mapping(uint256 proposalHash => uint256 proposalId) private _proposalIds;
  12. /**
  13. * @dev The {latestProposalId} may only be initialized if it hasn't been set yet
  14. * (through initialization or the creation of a proposal).
  15. */
  16. error GovernorAlreadyInitializedLatestProposalId();
  17. /**
  18. * @dev See {IGovernor-getProposalId}.
  19. */
  20. function getProposalId(
  21. address[] memory targets,
  22. uint256[] memory values,
  23. bytes[] memory calldatas,
  24. bytes32 descriptionHash
  25. ) public view virtual override returns (uint256) {
  26. uint256 proposalHash = hashProposal(targets, values, calldatas, descriptionHash);
  27. uint256 storedProposalId = _proposalIds[proposalHash];
  28. if (storedProposalId == 0) {
  29. revert GovernorNonexistentProposal(0);
  30. }
  31. return storedProposalId;
  32. }
  33. /**
  34. * @dev Returns the latest proposal id. A return value of 0 means no proposals have been created yet.
  35. */
  36. function latestProposalId() public view virtual returns (uint256) {
  37. return _latestProposalId;
  38. }
  39. /**
  40. * @dev See {IGovernor-_propose}.
  41. * Hook into the proposing mechanism to increment proposal count.
  42. */
  43. function _propose(
  44. address[] memory targets,
  45. uint256[] memory values,
  46. bytes[] memory calldatas,
  47. string memory description,
  48. address proposer
  49. ) internal virtual override returns (uint256) {
  50. uint256 proposalHash = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
  51. uint256 storedProposalId = _proposalIds[proposalHash];
  52. if (storedProposalId == 0) {
  53. _proposalIds[proposalHash] = ++_latestProposalId;
  54. }
  55. return super._propose(targets, values, calldatas, description, proposer);
  56. }
  57. /**
  58. * @dev Internal function to set the {latestProposalId}. This function is helpful when transitioning
  59. * from another governance system. The next proposal id will be `newLatestProposalId` + 1.
  60. *
  61. * May only call this function if the current value of {latestProposalId} is 0.
  62. */
  63. function _initializeLatestProposalId(uint256 newLatestProposalId) internal virtual {
  64. if (_latestProposalId != 0) {
  65. revert GovernorAlreadyInitializedLatestProposalId();
  66. }
  67. _latestProposalId = newLatestProposalId;
  68. }
  69. }