Untitled
unknown
plain_text
a year ago
3.4 kB
8
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