Untitled
user_7432713
plain_text
7 months ago
3.4 kB
14
Indexable
Never
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract WeightedVoting is ERC20 { uint public constant maxSupply = 1000000; error TokensClaimed(); error AllTokensClaimed(); error NoTokensHeld(); error QuorumTooHigh(uint quorum); error AlreadyVoted(); error VotingClosed(); using EnumerableSet for EnumerableSet.AddressSet; struct Issue { EnumerableSet.AddressSet voters; string issueDesc; uint votesFor; uint votesAgainst; uint votesAbstain; uint totalVotes; uint quorum; bool passed; bool closed; } struct IssueView { string issueDesc; uint votesFor; uint votesAgainst; uint votesAbstain; uint totalVotes; uint quorum; bool passed; bool closed; } Issue[] private issues; mapping(uint => mapping(address => bool)) private hasVoted; mapping(uint => mapping(address => uint)) private voterTokens; enum Votes { AGAINST, FOR, ABSTAIN } constructor() ERC20("WeightedVotingToken", "WVT") {} function claim() public { require(balanceOf(msg.sender) == 0, "TokensClaimed"); require(totalSupply() < maxSupply, "AllTokensClaimed"); _mint(msg.sender, 100); } function createIssue(string memory _issueDesc, uint _quorum) external returns(uint) { require(balanceOf(msg.sender) > 0, "NoTokensHeld"); require(_quorum <= totalSupply(), "QuorumTooHigh"); Issue storage newIssue = issues.push(); newIssue.issueDesc = _issueDesc; newIssue.quorum = _quorum; return issues.length - 1; } function getIssue(uint _id) external view returns (IssueView memory) { Issue storage issue = issues[_id]; return IssueView({ issueDesc: issue.issueDesc, votesFor: issue.votesFor, votesAgainst: issue.votesAgainst, votesAbstain: issue.votesAbstain, totalVotes: issue.totalVotes, quorum: issue.quorum, passed: issue.passed, closed: issue.closed }); } function vote(uint _issueId, Votes _vote) public { require(balanceOf(msg.sender) > 0, "NoTokensHeld"); Issue storage issue = issues[_issueId]; require(!issue.closed, "VotingClosed"); require(!hasVoted[_issueId][msg.sender], "AlreadyVoted"); hasVoted[_issueId][msg.sender] = true; voterTokens[_issueId][msg.sender] = balanceOf(msg.sender); issue.totalVotes += balanceOf(msg.sender); if (_vote == Votes.FOR) { issue.votesFor += balanceOf(msg.sender); } else if (_vote == Votes.AGAINST) { issue.votesAgainst += balanceOf(msg.sender); } else if (_vote == Votes.ABSTAIN) { issue.votesAbstain += balanceOf(msg.sender); } else { revert("Invalid vote option"); } if (issue.totalVotes >= issue.quorum) { issue.closed = true; issue.passed = issue.votesFor > issue.votesAgainst; } } }
Leave a Comment