-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestnetbase
More file actions
115 lines (98 loc) · 2.95 KB
/
testnetbase
File metadata and controls
115 lines (98 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract Submission is ERC20 {
using EnumerableSet for EnumerableSet.AddressSet;
struct Issue {
EnumerableSet.AddressSet voters;
string issueDesc;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
uint256 totalVotes;
uint256 quorum;
bool passed;
bool closed;
}
struct ReturnableIssue {
address[] voters;
string issueDesc;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
uint256 totalVotes;
uint256 quorum;
bool passed;
bool closed;
}
enum Vote {
AGAINST,
FOR,
ABSTAIN
}
mapping(address => bool) private hasClaimed;
Issue[] private issues;
error TokensClaimed();
error NoTokensHeld();
error AlreadyVoted();
constructor() ERC20("VoteToken", "VTK") {}
function claim() external {
if (hasClaimed[msg.sender]) {
revert TokensClaimed();
}
hasClaimed[msg.sender] = true;
_mint(msg.sender, 100);
}
function createIssue(
string memory _issueDesc,
uint256 _quorum
) external returns (uint256) {
if (balanceOf(msg.sender) == 0) {
revert NoTokensHeld();
}
Issue storage newIssue = issues.push();
newIssue.issueDesc = _issueDesc;
newIssue.quorum = _quorum;
return issues.length - 1;
}
function getIssue(
uint256 _id
) external view returns (ReturnableIssue memory) {
Issue storage issue = issues[_id];
return
ReturnableIssue(
issue.voters.values(),
issue.issueDesc,
issue.votesFor,
issue.votesAgainst,
issue.votesAbstain,
issue.totalVotes,
issue.quorum,
issue.passed,
issue.closed
);
}
function vote(uint256 _issueId, Vote _vote) external {
Issue storage issueToVote = issues[_issueId];
if (issueToVote.voters.contains(msg.sender)) {
revert AlreadyVoted();
}
uint256 voteWeight = balanceOf(msg.sender);
issueToVote.voters.add(msg.sender);
if (_vote == Vote.FOR) {
issueToVote.votesFor += voteWeight;
} else if (_vote == Vote.AGAINST) {
issueToVote.votesAgainst += voteWeight;
} else {
issueToVote.votesAbstain += voteWeight;
}
issueToVote.totalVotes += voteWeight;
if (issueToVote.totalVotes >= issueToVote.quorum) {
issueToVote.closed = true;
if (issueToVote.votesFor > issueToVote.votesAgainst) {
issueToVote.passed = true;
}
}
}
}