Untitled
user_7432713
plain_text
2 years ago
4.1 kB
17
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();
}
// Check if the voter has tokens
if (balanceOf(msg.sender) > 0) {
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;
}
}
} else {
revert NoTokensHeld(); // Revert if the voter has no tokens
}
}
}Editor is loading...
Leave a Comment