package impl import ( "gno.land/r/gov/dao/v3/memberstore" ) var ( law *Law govDAO *GovDAO = NewGovDAO() ) func init() { law = &Law{ Supermajority: 66.66, // Two thirds } } func Render(cur realm, in string) string { // Same-realm: pass cur to govDAO.Render (also crossing, but same realm // so use the literal cur form rather than cross(cur)). return govDAO.Render(cur, cur.PkgPath(), in) } // AddMember allows T1 and T2 members to freely add T3 members using their invitation points. func AddMember(cur realm, addr address) { caller := cur.Previous() if !caller.IsUser() { panic("this function must be called by an EOA through msg call or msg run") } m, t := memberstore.Get(0, cur).GetMember(caller.Address()) if m == nil { panic("caller is not a member") } if t != memberstore.T1 && t != memberstore.T2 { panic("caller is not on T1 or T2. To add members, propose them through proposals") } m.RemoveInvitationPoint() if err := memberstore.Get(0, cur).SetMember(memberstore.T3, addr, memberByTier(memberstore.T3)); err != nil { panic(err.Error()) } } // GetInstance returns the singleton *GovDAO. Only the loader realm may // call it (used during the bootstrap UpdateImpl handoff). The // IsCurrent() check rejects stale or stashed realm values; PkgPath() // after the check is the authentic immediate caller. func GetInstance(_ int, rlm realm) *GovDAO { if !rlm.IsCurrent() { panic("GetInstance: rlm is not the caller's live cur (stale capture or sibling frame)") } if rlm.PkgPath() != "gno.land/r/gov/dao/v3/loader" { panic("not allowed") } return govDAO }