Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}