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/impl/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
gov / dao / impl
Files
25 (gnomod.toml)
Exported functions
17
Module
gno.land/r/gov/dao/impl/v0
gno
0.9

Files (25)

  • gnomod.tomltoml
  • clamp.gnogno
  • filter.gnogno
  • govdao.gnogno
  • impl.gnogno
  • prop_requests.gnogno
  • render.gnogno
  • types.gnogno
  • clamp_test.gnogno
  • denied_reason_test.gnogno
  • executor_disclosure_filetest.gnogno
  • executor_invocation_authority_filetest.gnogno
  • govdao_execute_proposal_00_filetest.gnogno
  • govdao_execute_proposal_01_filetest.gnogno
  • govdao_execute_proposal_02_filetest.gnogno
  • govdao_execute_proposal_03_filetest.gnogno
  • govdao_test.gnogno
  • render_error_paths_filetest.gnogno
  • stringify_proposal_00_filetest.gnogno
  • title_clamp_filetest.gnogno
  • z_addr_validation_test.gnogno
  • z_denied_reason_store_test.gnogno
  • z_treasury_payment_request_test.gnogno
  • z_unknown_proposal_test.gnogno
  • z_upgrade_request_test.gnogno
  • clamp.gnogno
    1package impl23// Attacker-controlled strings are clamped before they reach the sanitizer, so4// escaping costs a bounded constant rather than scaling with input.5//6// Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw7// concatenation it replaced, and Render is reachable unauthenticated through

    Functions

    • AddMember(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}, addr string)

    • GetInstance(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}) *gno.land/r/gov/dao/impl/v0.GovDAO

    • NewAddMemberRequest(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}, addr string, tier string, portfolio string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewChangeLawRequest(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}, newLaw struct{Supermajority float64}) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewFilterByTier(tier string) struct{Tier string}

    • NewGovDAO() *gno.land/r/gov/dao/impl/v0.GovDAO

    • NewLaw(supermajority float64) struct{Supermajority float64}

    • NewPromoteMemberRequest(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}, addr string, fromTier string, toTier string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewProposalsStatuses() struct{BPTree *gno.land/p/nt/bptree/v0.BPTree}

    • NewRender(d *gno.land/r/gov/dao/impl/v0.GovDAO) *gno.land/r/gov/dao/impl/v0.render

    • NewTreasuryGRC20TokensUpdate(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}, newTokenKeys []string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewTreasuryPaymentRequest(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}, payment interface {BankerID func() string; String func() string}, reason string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewUpgradeDaoImplRequest(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}, newDao 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}, realmPkg string, reason string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • NewWithdrawMemberRequest(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}, addr string, reason string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • 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}, in string) string

    • StringifyProposal(p *gno.land/r/gov/dao.Proposal) string

    • StringifyVotes(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}, ps *gno.land/r/gov/dao/impl/v0.proposalStatus) 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.

    8// vm/qrender under maxGasQuery = 3_000_000_000. ExecutorCreationRealm is
    9// dispatched through the public dao.Executor interface, so a hostile executor
    10// computes it per call while storing almost nothing. Measured on the real
    11// render path: a 250KB value costs 2,839,117,770 gas unclamped against
    12// 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it
    13// (3,008,818,394), and past that the page cannot be rendered at all by
    14// anyone. Choosing the larger number costs the attacker nothing, since the
    15// value is computed per call and almost nothing is stored. Removing that
    16// amplification is the point of this file.
    17//
    18// It does NOT make the page safe, and nothing here should be read as claiming
    19// so. The executor's method body runs inside the same query and is unbounded:
    20// an executor that simply burns CPU before returning a short string still
    21// renders the proposal page permanently un-queryable, for a few hundred bytes
    22// of on-chain storage. That predates this change — Render has always called
    23// ExecutorString() and ExecutorCreationRealm() through the public interface —
    24// and bounding it needs a gas budget around executor dispatch, not a clamp.
    25const (
    26 // A realm path. The longest deployable realm path in examples/ is 35 bytes
    27 // (gno.land/r/gov/dao/treasury/test/v0), so this leaves about seven times
    28 // the room anything real needs. A hostile executor returns any length it
    29 // likes, which is the reason to clamp at all. It is headroom, not a
    30 // guarantee: the package-path grammar puts no ceiling on how many segments
    31 // a path may have, so a deeply nested realm could still be cut. That costs
    32 // a truncation marker on the page and nothing else.
    33 maxRenderedRealm = 256
    34 // "execution failed: " plus an executor's error message. Also bounds what
    35 // govdao.gno stores, so the realm never holds a reason it cannot show.
    36 maxRenderedReason = 1024
    37 // A strconv error that echoes the caller's own path segment. Everything in
    38 // it is fixed text except the quoted segment, whose length the caller picks.
    39 maxRenderedError = 256
    40 // A proposal title. The longest in examples/ is about 40 bytes, so this is
    41 // roughly nine times anything real, and long for a heading. Titles are
    42 // escaped on both the proposal page and the list page, and the list page
    43 // escapes one per proposal shown, so this is the bound that keeps a single
    44 // oversized title from pricing the whole list out of the query cap.
    45 maxRenderedTitle = 512
    46 // A Payment's String(). The canonical impls render a coin set or an
    47 // amount plus a token key, then " to " and a bech32 address; a coin set
    48 // is bounded by the number of denoms a proposer cares to list and each
    49 // denom's length is unbounded, which is the reason to clamp at all.
    50 maxRenderedPayment = 512
    51)
    52
    53// Always clamp first — before escaping, and before any other pass over the
    54// value. Trimming used to run before the clamp, which meant it walked every
    55// byte the executor returned: 250KB of spaces cost 1,368,719,824 gas to render
    56// nothing, and 560KB cost 3,048,904,520, past the query cap. Clamping first
    57// bounds that scan and brought the same 560KB down to 16,657,792.
    58//
    59// Never clamp after escaping either. The escapers size their wrapper
    60// from the string they are handed — InlineCode picks a fence long enough to
    61// outscan the backticks it can see. Cutting a value that has already been
    62// escaped can slice the closing fence off and leave the span hanging open,
    63// which is worse than not clamping at all. Both call sites read
    64// InlineCode(clampField(...)) for that reason, and the enormous-value case in
    65// filetests/executor_disclosure_filetest.gno fails if the two are swapped.
    66//
    67// clampField cuts s to at most max bytes, backing off to a rune boundary so a
    68// well-formed multi-byte character is not split, and marks the result so a
    69// reader can tell it was cut. Input that is already invalid UTF-8 can still
    70// leave a dangling lead byte; the sanitizer tolerates that. The marker avoids markdown punctuation:
    71// these values are escaped downstream, and parentheses would come back as
    72// "\(truncated\)".
    73func clampField(s string, max int) string {
    74 if len(s) <= max {
    75 return s
    76 }
    77
    78 end := max
    79 // UTF-8 continuation bytes are 0b10xxxxxx.
    80 for end > 0 && s[end]&0xC0 == 0x80 {
    81 end--
    82 }
    83
    84 return s[:end] + "… truncated"
    85}
    86