Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}