Untitled
user_7432713
plain_text
2 years ago
3.5 kB
26
Indexable
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
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;
mapping(address => bool) private hasClaimed;
enum Votes { AGAINST, FOR, ABSTAIN }
constructor() ERC20("WeightedVotingToken", "WVT") {
_mint(address(this), maxSupply);
_burn(address(this), maxSupply);
}
function claim() public {
require(!hasClaimed[msg.sender], "TokensClaimed");
require(totalSupply() < maxSupply, "AllTokensClaimed");
_mint(msg.sender, 100);
hasClaimed[msg.sender] = true;
}
function createIssue(string memory _issueDesc, uint _quorum) external returns(uint) {
require(balanceOf(msg.sender) > 0, "NoTokensHeld");
require(_quorum <= totalSupply(), "QuorumTooHigh");
Issue storage newIssue = issues[issues.length];
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