ERC20 exercise
user_7432713
plain_text
a year ago
3.9 kB
18
Indexable
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./ERC20.sol"; import "./EnumerableSet.sol"; error TokensClaimed(); error AllTokensClaimed(); error NoTokensHeld(); error QuorumTooHigh(); error AlreadyVoted(); error VotingClosed(); contract WeightedVoting is ERC20 { using EnumerableSet for EnumerableSet.AddressSet; uint256 public maxSupply; uint256 public totalClaimed; struct Issue { EnumerableSet.AddressSet voters; string issueDesc; uint256 votesFor; uint256 votesAgainst; uint256 votesAbstain; uint256 totalVotes; uint256 quorum; bool isPassed; bool isClosed; } struct ReturnableIssue { address[] voters; string issueDesc; uint256 votesFor; uint256 votesAgainst; uint256 votesAbstain; uint256 totalVotes; uint256 quorum; bool isPassed; bool isClosed; } Issue[] issues; enum Votes { AGAINST, FOR, ABSTAIN } constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) { maxSupply = 1000000; issues.push(); } function claim() external { if (totalClaimed == maxSupply) { revert AllTokensClaimed(); } if (balanceOf(msg.sender) >= 100) { revert TokensClaimed(); } _mint(msg.sender, 100); totalClaimed = totalClaimed + 100; } function createIssue(string memory _issueDesc, uint256 _quorum) external returns (uint256) { if (_quorum > totalClaimed) { revert QuorumTooHigh(); } if (balanceOf(msg.sender) == 0) { revert NoTokensHeld(); } uint256 newIssueIndex = issues.length; issues.push(); Issue storage newIssue = issues[newIssueIndex]; newIssue.issueDesc = _issueDesc; newIssue.quorum = _quorum; return newIssueIndex; } function getIssue(uint256 _issueId) external view returns (ReturnableIssue memory) { Issue storage issue = issues[_issueId]; address[] memory issueVoters = new address[](issue.voters.length()); for (uint256 i = 0; i < issue.voters.length(); i++){ issueVoters[i] = issue.voters.at(i); } ReturnableIssue memory result; result.voters = issueVoters; result.issueDesc = issue.issueDesc; result.votesFor = issue.votesFor; result.votesAgainst = issue.votesAgainst; result.votesAbstain = issue.votesAbstain; result.totalVotes = issue.totalVotes; result.quorum = issue.quorum; result.isPassed = issue.isPassed; result.isClosed = issue.isClosed; return result; } function vote(uint256 _issueId, Votes _vote) external { Issue storage issue = issues[_issueId]; if(issue.isClosed) { revert VotingClosed(); } if(issue.voters.contains(msg.sender)) { revert AlreadyVoted(); } uint256 voterBalance = balanceOf(msg.sender); if (_vote == Votes.FOR) { issue.votesFor += voterBalance; } else if (_vote == Votes.AGAINST) { issue.votesAgainst += voterBalance; } else if (_vote == Votes.ABSTAIN) { issue.votesAbstain += voterBalance; } issue.totalVotes += voterBalance; issue.voters.add(msg.sender); if (issue.totalVotes >= issue.quorum) { issue.isClosed = true; if (issue.votesFor > issue.votesAgainst) { issue.isPassed = true; } if (issue.quorum > totalSupply()) revert QuorumTooHigh(); if (balanceOf(msg.sender) == 0) revert NoTokensHeld(); } } }
Editor is loading...
Leave a Comment