custom_condition.gno
2.21 Kb · 73 lines
1package custom_condition
2
3import (
4 "gno.land/p/nt/ufmt/v0"
5 "gno.land/p/samcrew/basedao"
6 "gno.land/p/samcrew/daocond"
7
8 "math"
9)
10
11// Implements a custom DAO condition requiring votes from members with no assigned roles
12type noRoleCountCond struct {
13 memberStore *basedao.MembersStore // Access to DAO membership data
14 count uint64 // Required number of yes votes from roleless members
15}
16
17// NoRole creates a new condition requiring votes from members with no roles
18func NoRole(memberStore *basedao.MembersStore, count uint64) daocond.Condition {
19 return &noRoleCountCond{
20 memberStore: memberStore,
21 count: count,
22 }
23}
24
25// Checks if a member has no assigned roles
26func hasNoRole(memberStore *basedao.MembersStore, memberId string) bool {
27 return len(memberStore.GetMemberRoles(memberId)) == 0
28}
29
30// Counts valid "yes" votes from roleless members
31func (c *noRoleCountCond) totalYes(ballot daocond.Ballot) uint64 {
32 totalYes := uint64(0)
33 ballot.Iterate(func(voter string, vote daocond.Vote) bool {
34 if vote != daocond.VoteYes {
35 return false
36 }
37 if !hasNoRole(c.memberStore, voter) {
38 return false
39 }
40 totalYes += 1
41 return false
42 })
43 return totalYes
44}
45
46// Eval evaluates whether the condition is satisfied based on current votes
47// Returns true when at least 'count' roleless members have voted yes
48func (c *noRoleCountCond) Eval(ballot daocond.Ballot) bool {
49 return c.totalYes(ballot) >= c.count
50}
51
52// Signal calculates the completion progress of the condition (0.0 to 1.0)
53// Represents the ratio of actual yes votes to required count, capped at 1.0
54func (c *noRoleCountCond) Signal(ballot daocond.Ballot) float64 {
55 return math.Min(float64(c.totalYes(ballot))/float64(c.count), 1)
56}
57
58// Displays the condition requirements for UI purposes
59func (c *noRoleCountCond) Render() string {
60 return ufmt.Sprintf("%d", c.count)
61}
62
63// Generates a detailed vote status report
64func (c *noRoleCountCond) RenderWithVotes(ballot daocond.Ballot) string {
65 s := ""
66 s += ufmt.Sprintf("%d members with no role must vote yes\n\n", c.count)
67 s += ufmt.Sprintf("Yes: %d/%d\n\n", c.totalYes(ballot), c.count)
68 return s
69}
70
71// Verify the interface compliance
72// Ensures proper implementation
73var _ daocond.Condition = (*noRoleCountCond)(nil)