123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.19;
- import {Governor} from "../Governor.sol";
- /**
- * @dev Extension of {Governor} that implements storage of proposal details. This modules also provides primitives for
- * the enumerability of proposals.
- *
- * Use cases for this module include:
- * - UIs that explore the proposal state without relying on event indexing.
- * - 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.
- */
- abstract contract GovernorStorage is Governor {
- struct ProposalDetails {
- address[] targets;
- uint256[] values;
- bytes[] calldatas;
- bytes32 descriptionHash;
- }
- uint256[] private _proposalIds;
- mapping(uint256 proposalId => ProposalDetails) private _proposalDetails;
- /**
- * @dev Hook into the proposing mechanism
- */
- function _propose(
- address[] memory targets,
- uint256[] memory values,
- bytes[] memory calldatas,
- string memory description,
- address proposer
- ) internal virtual override returns (uint256) {
- uint256 proposalId = super._propose(targets, values, calldatas, description, proposer);
- // store
- _proposalIds.push(proposalId);
- _proposalDetails[proposalId] = ProposalDetails({
- targets: targets,
- values: values,
- calldatas: calldatas,
- descriptionHash: keccak256(bytes(description))
- });
- return proposalId;
- }
- /**
- * @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument.
- */
- function queue(uint256 proposalId) public virtual {
- // here, using storage is more efficient than memory
- ProposalDetails storage details = _proposalDetails[proposalId];
- queue(details.targets, details.values, details.calldatas, details.descriptionHash);
- }
- /**
- * @dev Version of {IGovernor-execute} with only `proposalId` as an argument.
- */
- function execute(uint256 proposalId) public payable virtual {
- // here, using storage is more efficient than memory
- ProposalDetails storage details = _proposalDetails[proposalId];
- execute(details.targets, details.values, details.calldatas, details.descriptionHash);
- }
- /**
- * @dev ProposalId version of {IGovernor-cancel}.
- */
- function cancel(uint256 proposalId) public virtual {
- // here, using storage is more efficient than memory
- ProposalDetails storage details = _proposalDetails[proposalId];
- cancel(details.targets, details.values, details.calldatas, details.descriptionHash);
- }
- /**
- * @dev Returns the number of stored proposals.
- */
- function proposalCount() public view virtual returns (uint256) {
- return _proposalIds.length;
- }
- /**
- * @dev Returns the details of a proposalId. Reverts if `proposalId` is not a known proposal.
- */
- function proposalDetails(
- uint256 proposalId
- ) public view virtual returns (address[] memory, uint256[] memory, bytes[] memory, bytes32) {
- // here, using memory is more efficient than storage
- ProposalDetails memory details = _proposalDetails[proposalId];
- if (details.descriptionHash == 0) {
- revert GovernorNonexistentProposal(proposalId);
- }
- return (details.targets, details.values, details.calldatas, details.descriptionHash);
- }
- /**
- * @dev Returns the details (including the proposalId) of a proposal given its sequential index.
- */
- function proposalDetailsAt(
- uint256 index
- ) public view virtual returns (uint256, address[] memory, uint256[] memory, bytes[] memory, bytes32) {
- uint256 proposalId = _proposalIds[index];
- (
- address[] memory targets,
- uint256[] memory values,
- bytes[] memory calldatas,
- bytes32 descriptionHash
- ) = proposalDetails(proposalId);
- return (proposalId, targets, values, calldatas, descriptionHash);
- }
- }
|