Search Apps Documentation Source Content File Folder Download Copy Actions Download

proposal.gno

3.99 Kb ยท 190 lines
  1package gnopendao2
  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}