Search Apps Documentation Source Content File Folder Download Copy Actions Download

proposal.gno

4.40 Kb ยท 202 lines
  1package gnopendao4
  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 = 5 * time.Minute//7 * 24 * time.Hour // 7 days
 15	QUORUM        = 0                 // 0% 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(realm) error {
101    // Do the actual action
102    if p.proposalType == PROPOSAL_TYPE_APPROVE_COLLECTION {
103        approvedCollections.Set(p.collectionAddr.String(), true)
104    } else if p.proposalType == PROPOSAL_TYPE_REMOVE_COLLECTION {
105        approvedCollections.Remove(p.collectionAddr.String())
106    }
107    
108    p.executed = true
109    return nil
110}
111
112func (p *CollectionProposal) GetCollectionAddr() address {
113	return p.collectionAddr
114}
115
116// FeesProposal - Proposal to update marketplace fees
117type FeesProposal struct {
118	newFee   int64
119	reason   string
120	approved bool
121	executed bool
122}
123
124func newFeesProposal(newFee int64, reason string) *FeesProposal {
125	return &FeesProposal{
126		newFee:   newFee,
127		reason:   reason,
128		approved: false,
129		executed: false,
130	}
131}
132
133func (p *FeesProposal) Title() string {
134	return ufmt.Sprintf("Update Marketplace Fee to %d basis points", p.newFee)
135}
136
137func (p *FeesProposal) Body() string {
138	currentFeePercent := float64(marketplaceFee) / 100.0
139	newFeePercent := float64(p.newFee) / 100.0
140
141	return ufmt.Sprintf(
142		"Current Fee: %.2f%%\nProposed Fee: %.2f%%\nReason: %s\n\nVote YES to approve, NO to reject",
143		currentFeePercent,
144		newFeePercent,
145		p.reason,
146	)
147}
148
149func (p *FeesProposal) VotingPeriod() time.Duration {
150	return VOTING_PERIOD
151}
152
153func (p *FeesProposal) Tally(
154	votes commondao.ReadonlyVotingRecord,
155	members commondao.MemberSet,
156) (bool, error) {
157	yesVotes := 0
158	noVotes := 0
159	totalVotes := 0
160
161	votes.Iterate(0, votes.Size(), false, func(v commondao.Vote) bool {
162		if string(v.Choice) == "yes" {
163			yesVotes++
164		} else if string(v.Choice) == "no" {
165			noVotes++
166		}
167		totalVotes++
168		return false
169	})
170
171	// Check quorum
172	totalMembers := members.Size()
173	quorumRequired := (totalMembers * QUORUM) / 100
174
175	if totalVotes < quorumRequired {
176		p.approved = false
177		return false, nil
178	}
179
180	// Simple majority
181	p.approved = yesVotes > noVotes
182	return p.approved, nil
183}
184
185func (p *FeesProposal) IsApproved() bool {
186	return p.approved
187}
188
189func (p *FeesProposal) IsExecuted() bool {
190	return p.executed
191}
192
193func (p *FeesProposal) Execute(realm) error {
194    // Do the actual action
195    marketplaceFee = p.newFee
196
197    p.executed = true
198    return nil
199}
200
201func (p *FeesProposal) GetNewFee() int64 {
202	return p.newFee
203}