voter.gno

1.82 Kb ยท 91 lines
 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}