proposal.gno
3.99 Kb ยท 190 lines
1package gnopendao1
2
3import (
4 "time"
5 "gno.land/p/nt/commondao"
6 "gno.land/p/nt/ufmt"
7)
8
9const (
10 PROPOSAL_TYPE_APPROVE_COLLECTION = "approve_collection"
11 PROPOSAL_TYPE_REMOVE_COLLECTION = "remove_collection"
12 PROPOSAL_TYPE_UPDATE_FEES = "update_fees"
13
14 VOTING_PERIOD = 7 * 24 * time.Hour // 7 days
15 QUORUM = 30 // 30% of members must vote
16)
17
18// CollectionProposal - Proposal to approve or remove a collection
19type CollectionProposal struct {
20 proposalType string
21 collectionAddr address
22 collectionName string
23 reason string
24 approved bool
25 executed bool
26}
27
28func NewCollectionProposal(propType string, addr address, name string, reason string) *CollectionProposal {
29 return &CollectionProposal{
30 proposalType: propType,
31 collectionAddr: addr,
32 collectionName: name,
33 reason: reason,
34 approved: false,
35 executed: false,
36 }
37}
38
39func (p *CollectionProposal) Title() string {
40 if p.proposalType == PROPOSAL_TYPE_APPROVE_COLLECTION {
41 return "Approve Collection: " + p.collectionName
42 }
43 return "Remove Collection: " + p.collectionName
44}
45
46func (p *CollectionProposal) Body() string {
47 return ufmt.Sprintf(
48 "Type: %s\nCollection: %s\nAddress: %s\nReason: %s\n\nVote YES to approve, NO to reject",
49 p.proposalType,
50 p.collectionName,
51 p.collectionAddr.String(),
52 p.reason,
53 )
54}
55
56func (p *CollectionProposal) VotingPeriod() time.Duration {
57 return VOTING_PERIOD
58}
59
60func (p *CollectionProposal) Tally(
61 votes commondao.ReadonlyVotingRecord,
62 members commondao.MemberSet,
63) (bool, error) {
64 yesVotes := 0
65 noVotes := 0
66 totalVotes := 0
67
68 votes.Iterate(0, votes.Size(), false, func(v commondao.Vote) bool {
69 if string(v.Choice) == "yes" {
70 yesVotes++
71 } else if string(v.Choice) == "no" {
72 noVotes++
73 }
74 totalVotes++
75 return false
76 })
77
78 // Check quorum
79 totalMembers := members.Size()
80 quorumRequired := (totalMembers * QUORUM) / 100
81
82 if totalVotes < quorumRequired {
83 p.approved = false
84 return false, nil
85 }
86
87 // Simple majority
88 p.approved = yesVotes > noVotes
89 return p.approved, nil
90}
91
92func (p *CollectionProposal) IsApproved() bool {
93 return p.approved
94}
95
96func (p *CollectionProposal) IsExecuted() bool {
97 return p.executed
98}
99
100func (p *CollectionProposal) Execute() {
101 p.executed = true
102}
103
104func (p *CollectionProposal) GetCollectionAddr() address {
105 return p.collectionAddr
106}
107
108// FeesProposal - Proposal to update marketplace fees
109type FeesProposal struct {
110 newFee int64
111 reason string
112 approved bool
113 executed bool
114}
115
116func NewFeesProposal(newFee int64, reason string) *FeesProposal {
117 return &FeesProposal{
118 newFee: newFee,
119 reason: reason,
120 approved: false,
121 executed: false,
122 }
123}
124
125func (p *FeesProposal) Title() string {
126 return ufmt.Sprintf("Update Marketplace Fee to %d basis points", p.newFee)
127}
128
129func (p *FeesProposal) Body() string {
130 currentFeePercent := float64(marketplaceFee) / 100.0
131 newFeePercent := float64(p.newFee) / 100.0
132
133 return ufmt.Sprintf(
134 "Current Fee: %.2f%%\nProposed Fee: %.2f%%\nReason: %s\n\nVote YES to approve, NO to reject",
135 currentFeePercent,
136 newFeePercent,
137 p.reason,
138 )
139}
140
141func (p *FeesProposal) VotingPeriod() time.Duration {
142 return VOTING_PERIOD
143}
144
145func (p *FeesProposal) Tally(
146 votes commondao.ReadonlyVotingRecord,
147 members commondao.MemberSet,
148) (bool, error) {
149 yesVotes := 0
150 noVotes := 0
151 totalVotes := 0
152
153 votes.Iterate(0, votes.Size(), false, func(v commondao.Vote) bool {
154 if string(v.Choice) == "yes" {
155 yesVotes++
156 } else if string(v.Choice) == "no" {
157 noVotes++
158 }
159 totalVotes++
160 return false
161 })
162
163 // Check quorum
164 totalMembers := members.Size()
165 quorumRequired := (totalMembers * QUORUM) / 100
166
167 if totalVotes < quorumRequired {
168 p.approved = false
169 return false, nil
170 }
171
172 // Simple majority
173 p.approved = yesVotes > noVotes
174 return p.approved, nil
175}
176
177func (p *FeesProposal) IsApproved() bool {
178 return p.approved
179}
180
181func (p *FeesProposal) IsExecuted() bool {
182 return p.executed
183}
184
185func (p *FeesProposal) Execute() {
186 p.executed = true
187}
188
189func (p *FeesProposal) GetNewFee() int64 {
190 return p.newFee
191}