Untitled
unknown
plain_text
2 years ago
3.4 kB
14
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 {
using EnumerableSet for EnumerableSet.AddressSet;
ERC20 public token;
uint public constant maxSupply = 1000000;
error TokensClaimed();
error AllTokensClaimed();
error NoTokensHeld();
error QuorumTooHigh(uint quorum);
error AlreadyVoted();
error VotingClosed();
struct Issue {
EnumerableSet.AddressSet voters;
string issueDesc;
uint votesFor;
uint votesAgainst;
uint votesAbstain;
uint totalVotes;
uint quorum;
bool passed;
bool closed;
}
Issue[] private issues;
enum Votes { AGAINST, FOR, ABSTAIN }
constructor(address _tokenAddress) {
token = ERC20(_tokenAddress);
issues.push();
token.transferFrom(msg.sender, address(this), maxSupply);
}
function claim() external {
if (token.balanceOf(msg.sender) > 0){
revert TokensClaimed();
}
if (issues[0].totalVotes >= maxSupply) {
revert AllTokensClaimed();
}
token.transfer(msg.sender, 100);
issues[0].totalVotes += 100;
issues[0].voters.add(msg.sender);
}
function createIssue(string memory _issueDesc, uint _quorum) external returns (uint) {
if(token.balanceOf(msg.sender) == 0){
revert NoTokensHeld();
}
if(_quorum >= token.totalSupply()){
revert QuorumTooHigh(_quorum);
}
uint newIssueId = issues.length;
issues.push();
Issue storage newIssue = issues[newIssueId];
newIssue.issueDesc = _issueDesc;
newIssue.quorum = _quorum;
return newIssueId;
}
function getIssue(uint _id) external view returns (string memory, uint, uint, uint, uint, bool, bool) {
if(_id > issues.length){
revert("Issue does not exist");
}
Issue storage issue = issues[_id];
return (issue.issueDesc, issue.votesFor, issue.votesAgainst, issue.votesAbstain, issue.totalVotes, issue.passed, issue.closed);
}
function vote(uint _issueId, Votes _vote) external {
Issue storage issue = issues[_issueId];
if(issue.closed){
revert VotingClosed();
}
if(issue.voters.contains(msg.sender)){
revert AlreadyVoted();
}
uint senderBalance = token.balanceOf(msg.sender);
issue.voters.add(msg.sender);
if (_vote == Votes.FOR) {
issue.votesFor += senderBalance;
} else if (_vote == Votes.AGAINST) {
issue.votesAgainst += senderBalance;
} else if (_vote == Votes.ABSTAIN) {
issue.votesAbstain += senderBalance;
} else {
revert("Invalid vote option");
}
issue.totalVotes += senderBalance;
if (issue.totalVotes >= issue.quorum) {
issue.closed = true;
if (issue.votesFor > issue.votesAgainst) {
issue.passed = true;
}
}
}
}
Editor is loading...
Leave a Comment