voting.gno
4.09 Kb ยท 169 lines
1package gnopendao3
2
3import (
4 "chain/runtime"
5 "gno.land/p/nt/commondao"
6 "gno.land/p/nt/ufmt"
7)
8
9// ProposeApproveCollection - Create a proposal to approve a new collection
10func ProposeApproveCollection(_ realm, collectionAddr address, collectionName string, reason string) uint64 {
11 caller := runtime.PreviousRealm().Address()
12
13 if !IsDAOMember(caller) {
14 panic("only DAO members can create proposals")
15 }
16
17 propDef := newCollectionProposal(PROPOSAL_TYPE_APPROVE_COLLECTION, collectionAddr, collectionName, reason)
18
19 proposal, err := marketplaceDAO.Propose(caller, propDef)
20 if err != nil {
21 panic("failed to create proposal: " + err.Error())
22 }
23
24 return proposal.ID()
25}
26
27// ProposeRemoveCollection - Create a proposal to remove a collection
28func ProposeRemoveCollection(_ realm, collectionAddr address, collectionName string, reason string) uint64 {
29 caller := runtime.PreviousRealm().Address()
30
31 if !IsDAOMember(caller) {
32 panic("only DAO members can create proposals")
33 }
34
35 propDef := newCollectionProposal(PROPOSAL_TYPE_REMOVE_COLLECTION, collectionAddr, collectionName, reason)
36
37 proposal, err := marketplaceDAO.Propose(caller, propDef)
38 if err != nil {
39 panic("failed to create proposal: " + err.Error())
40 }
41
42 return proposal.ID()
43}
44
45// ProposeUpdateFees - Create a proposal to update marketplace fees
46func ProposeUpdateFees(_ realm, newFeeBasisPoints int64, reason string) uint64 {
47 caller := runtime.PreviousRealm().Address()
48
49 if !IsDAOMember(caller) {
50 panic("only DAO members can create proposals")
51 }
52
53 if newFeeBasisPoints < 0 || newFeeBasisPoints > 1000 {
54 panic("fees must be between 0 and 1000 basis points (0-10%)")
55 }
56
57 propDef := newFeesProposal(newFeeBasisPoints, reason)
58
59 proposal, err := marketplaceDAO.Propose(caller, propDef)
60 if err != nil {
61 panic("failed to create proposal: " + err.Error())
62 }
63
64 return proposal.ID()
65}
66
67// Vote - Vote on a proposal (yes or no)
68func Vote(_ realm, proposalID uint64, choice string) string {
69 caller := runtime.PreviousRealm().Address()
70
71 if !IsDAOMember(caller) {
72 panic("only DAO members can vote")
73 }
74
75 if choice != "yes" && choice != "no" {
76 panic("choice must be 'yes' or 'no'")
77 }
78
79 proposal := marketplaceDAO.ActiveProposals().Get(proposalID)
80 if proposal == nil {
81 panic("proposal not found")
82 }
83
84 if proposal.HasVotingDeadlinePassed() {
85 panic("voting period has ended")
86 }
87
88 vote := commondao.Vote{
89 Address: caller,
90 Choice: commondao.VoteChoice(choice),
91 Reason: "",
92 Context: nil,
93 }
94
95 proposal.VotingRecord().AddVote(vote)
96
97 return "Vote recorded: " + choice
98}
99
100func TallyProposal(_ realm, proposalID uint64) string {
101 caller := runtime.PreviousRealm().Address()
102
103 if caller != daoAdmin {
104 panic("only admin can execute proposals")
105 }
106
107 err := marketplaceDAO.Execute(proposalID)
108 if err != nil {
109 panic("execution failed: " + err.Error())
110 }
111
112 return ufmt.Sprintf("Proposal %d executed successfully", proposalID)
113}
114
115// GetProposalInfo - Get information about a proposal
116func GetProposalInfo(proposalID uint64) string {
117 proposal := marketplaceDAO.ActiveProposals().Get(proposalID)
118 if proposal == nil {
119 return "Proposal not found"
120 }
121
122 yesVotes := 0
123 noVotes := 0
124
125 proposal.VotingRecord().Iterate(0, proposal.VotingRecord().Size(), false, func(v commondao.Vote) bool {
126 if string(v.Choice) == "yes" {
127 yesVotes++
128 } else if string(v.Choice) == "no" {
129 noVotes++
130 }
131 return false
132 })
133
134 output := ufmt.Sprintf(`Proposal #%d
135Title: %s
136Body: %s
137Yes Votes: %d
138No Votes: %d
139Total Votes: %d
140Voting Ended: %t`,
141 proposalID,
142 proposal.Definition().Title(),
143 proposal.Definition().Body(),
144 yesVotes,
145 noVotes,
146 yesVotes+noVotes,
147 proposal.HasVotingDeadlinePassed(),
148 )
149
150 return output
151}
152
153// GetAllActiveProposals - Get all active proposals
154func GetAllActiveProposals() string {
155 proposals := marketplaceDAO.ActiveProposals()
156
157 if proposals.Size() == 0 {
158 return "No active proposals"
159 }
160
161 output := "=== Active Proposals ===\n\n"
162
163 // Fix: use *commondao.Proposal instead of commondao.Proposal
164 proposals.Iterate(0, proposals.Size(), false, func(p *commondao.Proposal) bool {
165 output += ufmt.Sprintf("ID: %d | %s\n", p.ID(), p.Definition().Title())
166 return false
167 })
168
169 return output
170}