prop_requests.gno

4.68 Kb ยท 167 lines
  1package impl
  2
  3import (
  4	"std"
  5
  6	"gno.land/p/demo/ufmt"
  7	"gno.land/r/gov/dao"
  8	"gno.land/r/gov/dao/v3/memberstore"
  9)
 10
 11func NewChangeLawRequest(cur realm, newLaw *Law) dao.ProposalRequest {
 12	member, _ := memberstore.Get().GetMember(std.OriginCaller())
 13	if member == nil {
 14		panic("proposer is not a member")
 15	}
 16
 17	cb := func() error {
 18		func(cur realm) {
 19			law = newLaw
 20		}(cross)
 21		return nil
 22	}
 23
 24	e := dao.NewSimpleExecutor(cb, ufmt.Sprintf("A new Law is proposed:\n %v", newLaw))
 25
 26	return dao.NewProposalRequest("Change Law Proposal", "This proposal is looking to change the actual govDAO Law", e)
 27}
 28
 29func NewUpgradeDaoImplRequest(newDao dao.DAO, realmPkg, reason string) dao.ProposalRequest {
 30	member, _ := memberstore.Get().GetMember(std.OriginCaller())
 31	if member == nil {
 32		panic("proposer is not a member")
 33	}
 34
 35	cb := func() error {
 36		// dao.UpdateImpl() must be cross-called from v3/impl but
 37		// what calls this cb function is r/gov/dao.
 38		// therefore we must cross back into v3/impl and then
 39		// cross call dao.UpdateRequest().
 40		func(cur realm) {
 41			dao.UpdateImpl(cross, dao.UpdateRequest{DAO: newDao,
 42				AllowedDAOs: []string{"gno.land/r/gov/dao/v3/impl", realmPkg}, // keeping previous realm just in case something went wrong
 43			})
 44		}(cross)
 45		return nil
 46	}
 47
 48	e := dao.NewSimpleExecutor(cb, "")
 49
 50	return dao.NewProposalRequest("Change DAO implementation", "This proposal is looking to change the actual govDAO implementation. Reason: "+reason, e)
 51}
 52
 53func NewAddMemberRequest(cur realm, addr std.Address, tier string, portfolio string) dao.ProposalRequest {
 54	_, ok := memberstore.Tiers.GetTier(tier)
 55	if !ok {
 56		panic("provided tier does not exists")
 57	}
 58
 59	if tier != memberstore.T1 && tier != memberstore.T2 {
 60		panic("Only T1 and T2 members can be added by proposal. To add a T3 member use AddMember function directly.")
 61	}
 62
 63	if portfolio == "" {
 64		panic("A portfolio for the proposed member is required")
 65	}
 66
 67	member, _ := memberstore.Get().GetMember(std.OriginCaller())
 68	if member == nil {
 69		panic("proposer is not a member")
 70	}
 71
 72	if member.InvitationPoints <= 0 {
 73		panic("proposer does not have enough invitation points for inviting new people to the board")
 74	}
 75
 76	cb := func() error {
 77		err := error(nil)
 78		func(cur realm) {
 79			member.RemoveInvitationPoint()
 80			err = memberstore.Get().SetMember(tier, addr, memberByTier(tier))
 81		}(cross)
 82
 83		return err
 84	}
 85
 86	e := dao.NewSimpleExecutor(cb, ufmt.Sprintf("A new member with address %v is proposed to be on tier %v. Provided Portfolio information:\n\n%v", addr, tier, portfolio))
 87
 88	return dao.NewProposalRequestWithFilter(
 89		"New Member Proposal",
 90		"This proposal is looking to add a new member to the board.",
 91		e,
 92		FilterByTier{Tier: tier},
 93	)
 94}
 95
 96func NewWithdrawMemberRequest(cur realm, addr std.Address, reason string) dao.ProposalRequest {
 97	member, tier := memberstore.Get().GetMember(addr)
 98	if member == nil {
 99		panic("user we want to remove not found")
100	}
101
102	if tier == memberstore.T1 && reason == "" {
103		panic("T1 user removals must contains a reason.")
104	}
105
106	cb := func() error {
107		func(cur realm) {
108			memberstore.Get().RemoveMember(addr)
109		}(cross)
110		return nil
111	}
112
113	e := dao.NewSimpleExecutor(cb, ufmt.Sprintf("Member with address %v will be withdrawn.\n\n REASON: %v.", addr, reason))
114
115	return dao.NewProposalRequest("Member Withdrawn", "This proposal is looking to remove a member from the board.", e)
116}
117
118func NewPromoteMemberRequest(addr std.Address, fromTier string, toTier string) dao.ProposalRequest {
119	cb := func() error {
120		var err error
121		func(cur realm) {
122			prevTier := memberstore.Get().RemoveMember(addr)
123			if prevTier == "" {
124				panic("member not found, so cannot be promoted")
125			}
126
127			if prevTier != fromTier {
128				panic("previous tier changed from the one indicated in the proposal")
129			}
130
131			err = memberstore.Get().SetMember(toTier, addr, memberByTier(toTier))
132		}(cross)
133
134		return err
135	}
136
137	e := dao.NewSimpleExecutor(cb, ufmt.Sprintf("A new member with address %v will be promoted from tier %v to tier %v.", addr, fromTier, toTier))
138
139	return dao.NewProposalRequestWithFilter(
140		"Member Promotion",
141		"This proposal is looking to promote a member to an upper tier.",
142		e,
143		FilterByTier{Tier: toTier},
144	)
145}
146
147func memberByTier(tier string) *memberstore.Member {
148	switch tier {
149	case memberstore.T1:
150		t, _ := memberstore.Tiers.GetTier(memberstore.T1)
151		return &memberstore.Member{
152			InvitationPoints: t.InvitationPoints,
153		}
154	case memberstore.T2:
155		t, _ := memberstore.Tiers.GetTier(memberstore.T2)
156		return &memberstore.Member{
157			InvitationPoints: t.InvitationPoints,
158		}
159	case memberstore.T3:
160		t, _ := memberstore.Tiers.GetTier(memberstore.T3)
161		return &memberstore.Member{
162			InvitationPoints: t.InvitationPoints,
163		}
164	default:
165		panic("member not found by the specified tier")
166	}
167}