123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts v4.4.0-rc.0 (governance/extensions/GovernorCountingSimple.sol)
- pragma solidity ^0.8.0;
- import "../Governor.sol";
- /**
- * @dev Extension of {Governor} for simple, 3 options, vote counting.
- *
- * _Available since v4.3._
- */
- abstract contract GovernorCountingSimple is Governor {
- /**
- * @dev Supported vote types. Matches Governor Bravo ordering.
- */
- enum VoteType {
- Against,
- For,
- Abstain
- }
- struct ProposalVote {
- uint256 againstVotes;
- uint256 forVotes;
- uint256 abstainVotes;
- mapping(address => bool) hasVoted;
- }
- mapping(uint256 => ProposalVote) private _proposalVotes;
- /**
- * @dev See {IGovernor-COUNTING_MODE}.
- */
- // solhint-disable-next-line func-name-mixedcase
- function COUNTING_MODE() public pure virtual override returns (string memory) {
- return "support=bravo&quorum=for,abstain";
- }
- /**
- * @dev See {IGovernor-hasVoted}.
- */
- function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
- return _proposalVotes[proposalId].hasVoted[account];
- }
- /**
- * @dev Accessor to the internal vote counts.
- */
- function proposalVotes(uint256 proposalId)
- public
- view
- virtual
- returns (
- uint256 againstVotes,
- uint256 forVotes,
- uint256 abstainVotes
- )
- {
- ProposalVote storage proposalvote = _proposalVotes[proposalId];
- return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes);
- }
- /**
- * @dev See {Governor-_quorumReached}.
- */
- function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
- ProposalVote storage proposalvote = _proposalVotes[proposalId];
- return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes;
- }
- /**
- * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
- */
- function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
- ProposalVote storage proposalvote = _proposalVotes[proposalId];
- return proposalvote.forVotes > proposalvote.againstVotes;
- }
- /**
- * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
- */
- function _countVote(
- uint256 proposalId,
- address account,
- uint8 support,
- uint256 weight
- ) internal virtual override {
- ProposalVote storage proposalvote = _proposalVotes[proposalId];
- require(!proposalvote.hasVoted[account], "GovernorVotingSimple: vote already cast");
- proposalvote.hasVoted[account] = true;
- if (support == uint8(VoteType.Against)) {
- proposalvote.againstVotes += weight;
- } else if (support == uint8(VoteType.For)) {
- proposalvote.forVotes += weight;
- } else if (support == uint8(VoteType.Abstain)) {
- proposalvote.abstainVotes += weight;
- } else {
- revert("GovernorVotingSimple: invalid value for enum VoteType");
- }
- }
- }
|