Search Apps Documentation Source Content File Folder Download Copy Actions Download

/p/samcrew/daocond/v2

Directory ยท 12 Files
README.md Open

daocond: Stateless Condition Engine for DAO Governance

daocond is a Gnolang package that provides a stateless condition engine for evaluating DAO proposal execution. It serves as the decision-making core of the daokit framework, determining whether proposals should be executed based on configurable governance rules.

Core Interfaces

Condition Interface

 1type Condition interface {
 2    // Eval - checks if the condition is satisfied based on current votes
 3    Eval(ballot Ballot) bool
 4    
 5    // Signal - returns a value from 0.0 to 1.0 indicating progress toward satisfaction
 6    Signal(ballot Ballot) float64
 7    
 8    Render() string // returns a representation of the condition
 9    RenderWithVotes(ballot Ballot) string // returns a representation with vote context
10}

Ballot Interface

1type Ballot interface {
2    Vote(voter string, vote Vote) // allows a user to vote on a proposal
3    Get(voter string) Vote // returns the vote of a specific user
4    
5    Total() int // returns the total number of votes cast
6    
7    Iterate(fn func(voter string, vote Vote) bool) // iterates over all votes
8}

Vote Types

1type Vote int
2
3const (
4    VoteAbstain Vote = iota  // Neutral vote
5    VoteNo                   // Against the proposal
6    VoteYes                  // In favor of the proposal
7)

Built-in Conditions

daocond provides three core condition types for common governance scenarios:

1// MembersThreshold - Requires a fraction of all DAO members to approve
2func MembersThreshold(threshold float64, isMemberFn func(string) bool, membersCountFn func() uint64) Condition
3
4// RoleThreshold - Requires a percentage of role holders to approve  
5func RoleThreshold(threshold float64, role string, hasRoleFn func(string, string) bool, roleCountFn func(string) uint32) Condition
6
7// RoleCount - Requires a minimum number of role holders to approve
8func RoleCount(count uint64, role string, hasRoleFn func(string, string) bool) Condition

Usage Examples:

1// Require 60% of all members
2memberMajority := daocond.MembersThreshold(0.6, store.IsMember, store.MembersCount)
3
4// Require 50% of contributor  
5adminApproval := daocond.RoleThreshold(0.5, "contributor", store.HasRole, store.RoleCount)
6
7// Require at least 2 core-contributor
8treasurerApproval := daocond.RoleCount(2, "core-contributor", store.HasRole)

Logical Composition

Combine conditions using logical operators to create complex governance rules:

1// And - All conditions must be satisfied
2func And(conditions ...Condition) Condition {...}
3
4// Or - At least one condition must be satisfied  
5func Or(conditions ...Condition) Condition {...}

Examples:

 1// Require BOTH admin majority AND treasurer approval
 2strictGovernance := daocond.And(
 3    daocond.RoleThreshold(0.5, "contributor", store.HasRole, store.RoleCount),
 4    daocond.RoleCount(1, "treasurer", store.HasRole),
 5)
 6
 7// Require EITHER treasurer majority OR unanimous core-contributor approval
 8flexibleGovernance := daocond.Or(
 9    daocond.RoleThreshold(0.5, "treasurer", store.HasRole, store.RoleCount),
10    daocond.RoleThreshold(1.0, "core-contributor", store.HasRole, store.RoleCount),
11)

Creating Custom Conditions

Implement the Condition interface to create custom governance rules:

 1type customCondition struct {
 2    // Your custom fields
 3}
 4
 5func (c *customCondition) Eval(ballot daocond.Ballot) bool {
 6    // Implement your evaluation logic
 7    return true
 8}
 9
10func (c *customCondition) Signal(ballot daocond.Ballot) float64 {
11    // Return progress from 0.0 to 1.0
12    return 0.5
13}
14
15func (c *customCondition) Render() string {
16    return "Custom condition description"
17}
18
19func (c *customCondition) RenderWithVotes(ballot daocond.Ballot) string {
20    return "Custom condition with current vote status"
21}

Usage Examples

Basic Usage

 1import "gno.land/p/samcrew/daocond"
 2
 3// Create a simple majority condition
 4condition := daocond.MembersThreshold(0.5, store.IsMember, store.MembersCount)
 5
 6// Evaluate the condition against a ballot
 7if condition.Eval(ballot) {
 8    // Proposal meets the condition requirements
 9    executeProposal()
10}
11
12// Check progress toward satisfaction
13progress := condition.Signal(ballot) // Returns 0.0 to 1.0

Complex Governance Rules

 1// Multi-tier approval system
 2governance := daocond.And(
 3    // Require 30% of all members
 4    daocond.MembersThreshold(0.3, store.IsMember, store.MembersCount),
 5    
 6    // AND at least 2 core-contributor approvals
 7    daocond.RoleCount(2, "core-contributor", store.HasRole),
 8    
 9    // AND either CTO approval OR finance team majority
10    daocond.Or(
11        daocond.RoleCount(1, "CTO", store.HasRole),
12        daocond.RoleThreshold(0.5, "finance", store.HasRole, store.RoleCount),
13    ),
14)

Integration with daokit

daocond is designed to work seamlessly with:

  • daokit: Core DAO framework
  • basedao: Member and role management
  • Custom DAO implementations
 1import (
 2    "gno.land/p/samcrew/daocond"
 3    "gno.land/p/samcrew/daokit"
 4)
 5
 6// Define conditions for different types of proposals
 7treasuryCondition := daocond.And(
 8    daocond.RoleCount(1, "treasurer", store.HasRole),
 9    daocond.MembersThreshold(0.6, store.IsMember, store.MembersCount),
10)
11
12// Use in resource registration
13resource := daokit.Resource{
14    Handler:     treasuryHandler,
15    Condition:   treasuryCondition,
16    DisplayName: "Treasury Management",
17    Description: "Proposals for treasury operations",
18}

For complete examples and interactive demos, see the /r/samcrew/daodemo/custom_condition realms.


Part of the daokit framework for building decentralized autonomous organizations in gnolang.