Search Apps Documentation Source Content File Folder Download Copy Actions Download

public_proposals.gno

3.87 Kb · 168 lines
  1package commondao
  2
  3import (
  4	"chain/runtime"
  5	"strings"
  6	"time"
  7
  8	"gno.land/p/moul/addrset"
  9	"gno.land/p/nt/commondao/v0"
 10)
 11
 12// CreateTextProposal creates a new general text proposal.
 13//
 14// Parameters:
 15// - daoID: ID of the root DAO (required)
 16// - title: Title of the proposal (required)
 17// - body: Body of the proposal (required)
 18// - votingDays: The number of days where proposal accepts votes.
 19//
 20// The default voting period is 7 days.
 21func CreateTextProposal(_ realm, daoID uint64, title, body string, votingDays uint8) uint64 {
 22	dao := mustGetDAO(daoID)
 23	o := getOptions(daoID)
 24	if !o.AllowTextProposals {
 25		panic("forbidden")
 26	}
 27
 28	if votingDays > 30 {
 29		panic("maximum proposal voting period is 30 days")
 30	}
 31
 32	caller := runtime.PreviousRealm().Address()
 33	assertCallerIsMember(caller, dao)
 34
 35	var votingPeriod time.Duration
 36	if votingDays == 0 {
 37		votingPeriod = time.Hour * 24 * 7
 38	} else {
 39		votingPeriod = time.Hour * 24 * time.Duration(votingDays)
 40	}
 41
 42	def := NewTextPropDefinition(title, body, commondao.QuorumOneThird, votingPeriod)
 43	p, err := dao.Propose(caller, def)
 44	if err != nil {
 45		panic(err)
 46	}
 47
 48	return p.ID()
 49}
 50
 51// CreateMembersUpdateProposal creates a new proposal to add and/or remove DAO members.
 52//
 53// Parameters:
 54// - daoID: ID of the root DAO (required)
 55// - newMembers: Comma separated list of addresses to add as members
 56// - removeMembers: Comma separated list of member addresses to remove
 57func CreateMembersUpdateProposal(_ realm, daoID uint64, newMembers, removeMembers string) uint64 {
 58	dao := mustGetDAO(daoID)
 59	o := getOptions(daoID)
 60	if !o.AllowMembersUpdate {
 61		panic("forbidden")
 62	}
 63
 64	caller := runtime.PreviousRealm().Address()
 65	assertCallerIsMember(caller, dao)
 66
 67	toAdd := mustParseStringToAddrset(newMembers)
 68	toRemove := mustParseStringToAddrset(removeMembers)
 69	def := newMembersUpdatePropDefinition(dao, toAdd, toRemove)
 70	p, err := dao.Propose(caller, def)
 71	if err != nil {
 72		panic(err)
 73	}
 74
 75	if err = p.Validate(); err != nil {
 76		panic(err)
 77	}
 78
 79	return p.ID()
 80}
 81
 82// CreateSubDAOProposal creates a new proposal to create a new SubDAO.
 83//
 84// Parameters:
 85// - daoID: ID of the parent DAO (required)
 86// - name: A name for the SubDAO (required)
 87// - members: Comma separated list of addresses to add as members
 88func CreateSubDAOProposal(_ realm, daoID uint64, name, members string) uint64 {
 89	dao := mustGetDAO(daoID)
 90	o := getOptions(daoID)
 91	if !(o.AllowSubDAOProposals && o.AllowChildren) {
 92		panic("forbidden")
 93	}
 94
 95	caller := runtime.PreviousRealm().Address()
 96	assertCallerIsMember(caller, dao)
 97
 98	daoMembers := mustParseStringToAddrset(members)
 99	def := newSubDAOPropDefinition(dao, name, &daoMembers)
100	p, err := dao.Propose(caller, def)
101	if err != nil {
102		panic(err)
103	}
104
105	if err = p.Validate(); err != nil {
106		panic(err)
107	}
108
109	return p.ID()
110}
111
112// CreateDissolutionProposal creates a new proposal to dissolve a DAO or SubDAO.
113//
114// SubDAOs can only be dissolveed by the the parent DAO.
115//
116// Parameters:
117// - daoID: ID of the DAO to dissolve (required)
118func CreateDissolutionProposal(_ realm, daoID uint64) uint64 {
119	// When DAO to dissolve is a SubDAO make sure that proposal is created in the parent DAO
120	dao := mustGetDAO(daoID)
121	dissolveDAO := dao
122	if parent := dao.Parent(); parent != nil {
123		dao = parent
124	}
125
126	o := getOptions(dao.ID())
127	if !o.AllowDissolutionProposals {
128		panic("forbidden")
129	}
130
131	caller := runtime.PreviousRealm().Address()
132	assertCallerIsMember(caller, dao)
133
134	def := newDissolvePropDefinition(dissolveDAO)
135	p, err := dao.Propose(caller, def)
136	if err != nil {
137		panic(err)
138	}
139
140	if err = p.Validate(); err != nil {
141		panic(err)
142	}
143
144	return p.ID()
145}
146
147func mustParseStringToAddrset(s string) (set addrset.Set) {
148	if s == "" {
149		return
150	}
151
152	for _, raw := range strings.Split(s, "\n") {
153		raw = strings.TrimSpace(raw)
154		if raw == "" {
155			continue
156		}
157
158		addr := address(raw)
159		if !addr.IsValid() {
160			panic("invalid address: " + addr.String())
161		}
162
163		if !set.Has(addr) {
164			set.Add(addr)
165		}
166	}
167	return set
168}