Search Apps Documentation Source Content File Folder Download Copy Actions Download

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)