impl.gno
1.57 Kb · 59 lines
1package impl
2
3import (
4 "gno.land/r/gov/dao/v3/memberstore"
5)
6
7var (
8 law *Law
9 govDAO *GovDAO = NewGovDAO()
10)
11
12func init() {
13 law = &Law{
14 Supermajority: 66.66, // Two thirds
15 }
16}
17
18func Render(cur realm, in string) string {
19 // Same-realm: pass cur to govDAO.Render (also crossing, but same realm
20 // so use the literal cur form rather than cross(cur)).
21 return govDAO.Render(cur, cur.PkgPath(), in)
22}
23
24// AddMember allows T1 and T2 members to freely add T3 members using their invitation points.
25func AddMember(cur realm, addr address) {
26 caller := cur.Previous()
27 if !caller.IsUser() {
28 panic("this function must be called by an EOA through msg call or msg run")
29 }
30 m, t := memberstore.Get(0, cur).GetMember(caller.Address())
31 if m == nil {
32 panic("caller is not a member")
33 }
34
35 if t != memberstore.T1 && t != memberstore.T2 {
36 panic("caller is not on T1 or T2. To add members, propose them through proposals")
37 }
38
39 m.RemoveInvitationPoint()
40
41 if err := memberstore.Get(0, cur).SetMember(memberstore.T3, addr, memberByTier(memberstore.T3)); err != nil {
42 panic(err.Error())
43 }
44}
45
46// GetInstance returns the singleton *GovDAO. Only the loader realm may
47// call it (used during the bootstrap UpdateImpl handoff). The
48// IsCurrent() check rejects stale or stashed realm values; PkgPath()
49// after the check is the authentic immediate caller.
50func GetInstance(_ int, rlm realm) *GovDAO {
51 if !rlm.IsCurrent() {
52 panic("GetInstance: rlm is not the caller's live cur (stale capture or sibling frame)")
53 }
54 if rlm.PkgPath() != "gno.land/r/gov/dao/v3/loader" {
55 panic("not allowed")
56 }
57
58 return govDAO
59}