1package govdao
2
3import (
4 "std"
5
6 "gno.land/p/demo/ufmt"
7)
8
9const (
10 yay = "YES"
11 nay = "NO"
12
13 msgNoMoreVotesAllowed = "no more votes allowed"
14 msgAlreadyVoted = "caller already voted"
15 msgWrongVotingValue = "voting values must be YES or NO"
16)
17
18func NewPercentageVoter(percent int) *PercentageVoter {
19 if percent < 0 || percent > 100 {
20 panic("percent value must be between 0 and 100")
21 }
22
23 return &PercentageVoter{
24 percentage: percent,
25 }
26}
27
28// PercentageVoter is a system based on the amount of received votes.
29// When the specified treshold is reached, the voting process finishes.
30type PercentageVoter struct {
31 percentage int
32
33 voters []std.Address
34 yes int
35 no int
36}
37
38func (pv *PercentageVoter) IsAccepted(voters []std.Address) bool {
39 if len(voters) == 0 {
40 return true // special case
41 }
42
43 return pv.percent(voters) >= pv.percentage
44}
45
46func (pv *PercentageVoter) IsFinished(voters []std.Address) bool {
47 return pv.yes+pv.no >= len(voters)
48}
49
50func (pv *PercentageVoter) Status(voters []std.Address) string {
51 return ufmt.Sprintf("YES: %d, NO: %d, percent: %d, members: %d", pv.yes, pv.no, pv.percent(voters), len(voters))
52}
53
54func (pv *PercentageVoter) Vote(voters []std.Address, caller std.Address, flag string) {
55 if pv.IsFinished(voters) {
56 panic(msgNoMoreVotesAllowed)
57 }
58
59 if pv.alreadyVoted(caller) {
60 panic(msgAlreadyVoted)
61 }
62
63 switch flag {
64 case yay:
65 pv.yes++
66 pv.voters = append(pv.voters, caller)
67 case nay:
68 pv.no++
69 pv.voters = append(pv.voters, caller)
70 default:
71 panic(msgWrongVotingValue)
72 }
73}
74
75func (pv *PercentageVoter) percent(voters []std.Address) int {
76 if len(voters) == 0 {
77 return 0
78 }
79
80 return int((float32(pv.yes) / float32(len(voters))) * 100)
81}
82
83func (pv *PercentageVoter) alreadyVoted(addr std.Address) bool {
84 for _, v := range pv.voters {
85 if v == addr {
86 return true
87 }
88 }
89
90 return false
91}
voter.gno
1.82 Kb ยท 91 lines