PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gov/dao

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
dao
Namespace
gov
Files
5 (gnomod.toml)
Exported functions
21
Module
gno.land/r/gov/dao
gno
0.9

Files (5)

  • gnomod.tomltoml
  • proxy.gnogno
  • types.gnogno
  • allowlist_test.gnogno
  • proxy_test.gnogno
allowlist_test.gnogno
1package dao23import (4	"testing"56	"gno.land/p/nt/uassert/v0"7	"gno.land/p/nt/urequire/v0"8)910// allowedDAOs is the sole authorization for UpdateImpl, memberstore.Get,11// treasury.Send and treasury.SetTokenKeys, and InAllowedDAOs() fails OPEN when12// it is empty — the bootstrap window that lets the genesis MsgRun seed the13// member set before lockdown.14//15// These tests pin that the transition empty -> non-empty is one-way: once the16// DAO is locked down, UpdateImpl cannot put it back into the fail-open state.17// Both paths below reopened the gate before the guard, because18// NewUpdateRequest copies nil into a NON-nil empty slice and the old test was19// `r.AllowedDAOs != nil`.20//21// These call the real UpdateImpl through a code realm rather than replaying22// its logic, so reverting the guard makes them fail.23func TestUpdateImplIgnoresEmptyAllowedDAOs(cur realm, t *testing.T) {24	savedDAOs, savedDAO := allowedDAOs, dao25	defer func() { allowedDAOs, dao = savedDAOs, savedDAO }()2627	lock := func() {28		allowedDAOs = nil // reopen so the next UpdateImpl is permitted29		testing.SetRealm(testing.NewCodeRealm(v0))30		UpdateImpl(cross(cur), UpdateRequest{DAO: &dummyDao{}, AllowedDAOs: []string{v0}})31		uassert.False(t, InAllowedDAOs(invalid), "precondition: locked down")32	}3334	// Path 1: NewUpdateRequest(d, nil) — "swap the implementation, leave35	// permissions alone", and the form v0/loader uses.36	lock()37	testing.SetRealm(testing.NewCodeRealm(v0))38	UpdateImpl(cross(cur), NewUpdateRequest(&dummyDao{}, nil))39	uassert.False(t, InAllowedDAOs(invalid),40		"a nil AllowedDAOs must not reopen the permission gate")4142	// Path 2: an explicitly empty slice via the struct literal.43	lock()44	testing.SetRealm(testing.NewCodeRealm(v0))45	UpdateImpl(cross(cur), UpdateRequest{DAO: &dummyDao{}, AllowedDAOs: []string{}})46	uassert.False(t, InAllowedDAOs(invalid),47		"an empty AllowedDAOs must not reopen the permission gate")4849	// A legitimate extension of the list must still apply.50	lock()51	testing.SetRealm(testing.NewCodeRealm(v0))52	UpdateImpl(cross(cur), NewUpdateRequest(&dummyDao{}, []string{v0, v1}))53	uassert.True(t, InAllowedDAOs(v1), "a non-empty AllowedDAOs must still be stored")54	uassert.False(t, InAllowedDAOs(invalid), "and must not admit anyone else")55}5657// The bootstrap window itself must survive the guard: with no allowlist58// configured yet, any caller is allowed so the genesis MsgRun can seed the59// member set and then lock down.60func TestBootstrapWindowStillOpen(t *testing.T) {61	saved := allowedDAOs62	defer func() { allowedDAOs = saved }()6364	allowedDAOs = nil65	uassert.True(t, InAllowedDAOs("gno.land/r/gov/dao/loader/v0"),66		"an unset allowlist must stay open for genesis bootstrap")67}6869// len(AllowedDAOs) != 0 is not sufficient on its own. InAllowedDAOs compares by70// exact string and a user realm's PkgPath() is "", so a single "" entry admits71// any caller whose previous frame is a user realm — the same fail-open outcome72// the guard exists to prevent. NewUpgradeDaoImplRequest passes its realmPkg73// argument straight into the list, so an empty one reaches here.74func TestUpdateImplRejectsBlankAllowedDAOEntry(cur realm, t *testing.T) {75	savedDAOs, savedDAO := allowedDAOs, dao76	defer func() { allowedDAOs, dao = savedDAOs, savedDAO }()7778	for _, blank := range []string{"", "   "} {79		allowedDAOs = nil80		testing.SetRealm(testing.NewCodeRealm(v0))81		UpdateImpl(cross(cur), UpdateRequest{DAO: &dummyDao{}, AllowedDAOs: []string{v0}})8283		testing.SetRealm(testing.NewCodeRealm(v0))84		urequire.AbortsWithMessage(t, cur,85			"AllowedDAOs entries must be realm paths; got an empty one",86			func() {87				UpdateImpl(cross(cur), UpdateRequest{88					DAO:         &dummyDao{},89					AllowedDAOs: []string{v0, blank},90				})91			})9293		uassert.False(t, InAllowedDAOs(""),94			"a blank entry must never make it into the allowlist")95		uassert.True(t, InAllowedDAOs(v0),96			"the rejected request must leave the previous allowlist intact")97	}98}99100// A padded entry passes a plain non-blank test but is useless: entries are101// stored exactly as given and InAllowedDAOs compares whole strings, so102// " gno.land/r/x " matches no caller. The list is still non-empty, so the103// bootstrap window is closed. A proposal that padded every entry would lock104// the DAO out of its own allowlist with no way back.105func TestUpdateImplRejectsPaddedAllowedDAOEntry(cur realm, t *testing.T) {106	savedDAOs, savedDAO := allowedDAOs, dao107	defer func() { allowedDAOs, dao = savedDAOs, savedDAO }()108109	for _, padded := range []string{" " + v1, v1 + " ", "\t" + v1} {110		allowedDAOs = nil111		testing.SetRealm(testing.NewCodeRealm(v0))112		UpdateImpl(cross(cur), UpdateRequest{DAO: &dummyDao{}, AllowedDAOs: []string{v0}})113114		testing.SetRealm(testing.NewCodeRealm(v0))115		urequire.AbortsWithMessage(t, cur,116			"AllowedDAOs entries must not have leading or trailing spaces; entry 1",117			func() {118				UpdateImpl(cross(cur), UpdateRequest{119					DAO:         &dummyDao{},120					AllowedDAOs: []string{v0, padded},121				})122			})123124		uassert.False(t, InAllowedDAOs(padded),125			"a padded entry must never make it into the allowlist")126		uassert.True(t, InAllowedDAOs(v0),127			"the rejected request must leave the previous allowlist intact")128	}129}130

Functions

  • AllowedDAOs() []string

  • CreateProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, r struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}) (int64, interface {Error func() string})

  • ExecuteOrRejectProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pid int64) bool

  • ExecuteProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pid int64) bool

  • GetProposal(pid int64) (*gno.land/r/gov/dao.Proposal, interface {Error func() string})

  • InAllowedDAOs(pkg string) bool

  • MustCreateProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, r struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}) int64

  • MustGetProposal(pid int64) *gno.land/r/gov/dao.Proposal

  • MustVoteOnProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, r struct{Option gno.land/r/gov/dao.VoteOption; ProposalID gno.land/r/gov/dao.ProposalID; Metadata interface {}})

  • MustVoteOnProposalSimple(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pid int64, option string)

  • NewProposalRequest(title string, description string, executor interface {CreationRealm func() string; Execute func(.uverse.realm) .uverse.error; String func() string}) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

  • NewProposalRequestWithFilter(title string, description string, executor interface {CreationRealm func() string; Execute func(.uverse.realm) .uverse.error; String func() string}, filter interface {}) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

  • NewProposals() *gno.land/r/gov/dao.Proposals

  • NewSafeExecutor(e interface {CreationRealm func() string; Execute func(.uverse.realm) .uverse.error; String func() string}) *gno.land/r/gov/dao.SafeExecutor

  • NewSimpleExecutor(int, rlm interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, callback func(.uverse.realm) .uverse.error, description string) *gno.land/r/gov/dao.SimpleExecutor

  • NewUpdateRequest(d interface {ExecuteProposal func(int, .uverse.realm, gno.land/r/gov/dao.ProposalID, gno.land/r/gov/dao.Executor) .uverse.error; PostCreateProposal func(int, .uverse.realm, gno.land/r/gov/dao.ProposalRequest, gno.land/r/gov/dao.ProposalID); PreCreateProposal func(int, .uverse.realm, gno.land/r/gov/dao.ProposalRequest) (.uverse.address, .uverse.error); PreExecuteProposal func(int, .uverse.realm, gno.land/r/gov/dao.ProposalID) (bool, .uverse.error); Render func(.uverse.realm, string, string) string; VoteOnProposal func(int, .uverse.realm, gno.land/r/gov/dao.VoteRequest) .uverse.error}, allowedDAOs []string) struct{DAO gno.land/r/gov/dao.DAO; AllowedDAOs []string}

  • NewVoteRequest(option string, proposalID int64) struct{Option gno.land/r/gov/dao.VoteOption; ProposalID gno.land/r/gov/dao.ProposalID; Metadata interface {}}

  • NewVoteRequestWithMetadata(option string, proposalID int64, metadata interface {}) struct{Option gno.land/r/gov/dao.VoteOption; ProposalID gno.land/r/gov/dao.ProposalID; Metadata interface {}}

  • Render(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, p string) string

  • UpdateImpl(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, r struct{DAO gno.land/r/gov/dao.DAO; AllowedDAOs []string})

  • VoteOnProposal(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, r struct{Option gno.land/r/gov/dao.VoteOption; ProposalID gno.land/r/gov/dao.ProposalID; Metadata interface {}}) interface {Error func() string}

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.