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}