impl.gno
2.10 Kb · 70 lines
1package impl
2
3import (
4 "gno.land/r/gov/dao/memberstore/v0"
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 // AGENTS.md: check IsCurrent() before cur.Previous() in a crossing function.
27 if !cur.IsCurrent() {
28 panic("AddMember: realm value is not the caller's live cur")
29 }
30 // address args are not VM-validated (the raw MsgCall string is stored), so
31 // reject a non-bech32 addr here — matching InitWithUsers. This keeps the
32 // member store free of unauthenticable keys and of markdown/pipe/HTML
33 // metachars that would otherwise inject into the members render table.
34 if !addr.IsValid() {
35 panic("invalid member address: " + addr.String())
36 }
37 caller := cur.Previous()
38 if !caller.IsUser() {
39 panic("this function must be called by an EOA through msg call or msg run")
40 }
41 m, t := memberstore.Get(0, cur).GetMember(caller.Address())
42 if m == nil {
43 panic("caller is not a member")
44 }
45
46 if t != memberstore.T1 && t != memberstore.T2 {
47 panic("caller is not on T1 or T2. To add members, propose them through proposals")
48 }
49
50 m.RemoveInvitationPoint()
51
52 if err := memberstore.Get(0, cur).SetMember(memberstore.T3, addr, memberByTier(memberstore.T3)); err != nil {
53 panic(err.Error())
54 }
55}
56
57// GetInstance returns the singleton *GovDAO. Only the loader realm may
58// call it (used during the bootstrap UpdateImpl handoff). The
59// IsCurrent() check rejects stale or stashed realm values; PkgPath()
60// after the check is the authentic immediate caller.
61func GetInstance(_ int, rlm realm) *GovDAO {
62 if !rlm.IsCurrent() {
63 panic("GetInstance: rlm is not the caller's live cur (stale capture or sibling frame)")
64 }
65 if rlm.PkgPath() != "gno.land/r/gov/dao/loader/v0" {
66 panic("not allowed")
67 }
68
69 return govDAO
70}