Untitled
user_7432713
plain_text
2 years ago
3.4 kB
22
Indexable
// 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;
}
}
}Editor is loading...
Leave a Comment