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

v0 state

Back to all declarations

maxRenderedRealm

untyped bigint

Attacker-controlled strings are clamped before they reach the sanitizer, so escaping costs a bounded constant rather than scaling with input. Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw concatenation it replaced, and Render is reachable unauthenticated through vm/qrender under maxGasQuery = 3\_000\_000\_000. ExecutorCreationRealm is dispatched through the public dao.Executor interface, so a hostile executor computes it per call while storing almost nothing. Measured on the real render path: a 250KB value costs 2,839,117,770 gas unclamped against 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it (3,008,818,394), and past that the page cannot be rendered at all by anyone. Choosing the larger number costs the attacker nothing, since the value is computed per call and almost nothing is stored. Removing that amplification is the point of this file. It does NOT make the page safe, and nothing here should be read as claiming so. The executor's method body runs inside the same query and is unbounded: an executor that simply burns CPU before returning a short string still renders the proposal page permanently un-queryable, for a few hundred bytes of on-chain storage. That predates this change — Render has always called ExecutorString() and ExecutorCreationRealm() through the public interface — and bounding it needs a gas budget around executor dispatch, not a clamp.

Value

(256 <untyped> bigint)

maxRenderedReason

untyped bigint

Attacker-controlled strings are clamped before they reach the sanitizer, so escaping costs a bounded constant rather than scaling with input. Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw concatenation it replaced, and Render is reachable unauthenticated through vm/qrender under maxGasQuery = 3\_000\_000\_000. ExecutorCreationRealm is dispatched through the public dao.Executor interface, so a hostile executor computes it per call while storing almost nothing. Measured on the real render path: a 250KB value costs 2,839,117,770 gas unclamped against 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it (3,008,818,394), and past that the page cannot be rendered at all by anyone. Choosing the larger number costs the attacker nothing, since the value is computed per call and almost nothing is stored. Removing that amplification is the point of this file. It does NOT make the page safe, and nothing here should be read as claiming so. The executor's method body runs inside the same query and is unbounded: an executor that simply burns CPU before returning a short string still renders the proposal page permanently un-queryable, for a few hundred bytes of on-chain storage. That predates this change — Render has always called ExecutorString() and ExecutorCreationRealm() through the public interface — and bounding it needs a gas budget around executor dispatch, not a clamp.

Value

(1024 <untyped> bigint)

maxRenderedError

untyped bigint

Attacker-controlled strings are clamped before they reach the sanitizer, so escaping costs a bounded constant rather than scaling with input. Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw concatenation it replaced, and Render is reachable unauthenticated through vm/qrender under maxGasQuery = 3\_000\_000\_000. ExecutorCreationRealm is dispatched through the public dao.Executor interface, so a hostile executor computes it per call while storing almost nothing. Measured on the real render path: a 250KB value costs 2,839,117,770 gas unclamped against 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it (3,008,818,394), and past that the page cannot be rendered at all by anyone. Choosing the larger number costs the attacker nothing, since the value is computed per call and almost nothing is stored. Removing that amplification is the point of this file. It does NOT make the page safe, and nothing here should be read as claiming so. The executor's method body runs inside the same query and is unbounded: an executor that simply burns CPU before returning a short string still renders the proposal page permanently un-queryable, for a few hundred bytes of on-chain storage. That predates this change — Render has always called ExecutorString() and ExecutorCreationRealm() through the public interface — and bounding it needs a gas budget around executor dispatch, not a clamp.

Value

(256 <untyped> bigint)

maxRenderedTitle

untyped bigint

Attacker-controlled strings are clamped before they reach the sanitizer, so escaping costs a bounded constant rather than scaling with input. Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw concatenation it replaced, and Render is reachable unauthenticated through vm/qrender under maxGasQuery = 3\_000\_000\_000. ExecutorCreationRealm is dispatched through the public dao.Executor interface, so a hostile executor computes it per call while storing almost nothing. Measured on the real render path: a 250KB value costs 2,839,117,770 gas unclamped against 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it (3,008,818,394), and past that the page cannot be rendered at all by anyone. Choosing the larger number costs the attacker nothing, since the value is computed per call and almost nothing is stored. Removing that amplification is the point of this file. It does NOT make the page safe, and nothing here should be read as claiming so. The executor's method body runs inside the same query and is unbounded: an executor that simply burns CPU before returning a short string still renders the proposal page permanently un-queryable, for a few hundred bytes of on-chain storage. That predates this change — Render has always called ExecutorString() and ExecutorCreationRealm() through the public interface — and bounding it needs a gas budget around executor dispatch, not a clamp.

Value

(512 <untyped> bigint)

maxRenderedPayment

untyped bigint

Attacker-controlled strings are clamped before they reach the sanitizer, so escaping costs a bounded constant rather than scaling with input. Sanitizing runs ~11,310 gas/byte (InlineCode) against ~31 for the raw concatenation it replaced, and Render is reachable unauthenticated through vm/qrender under maxGasQuery = 3\_000\_000\_000. ExecutorCreationRealm is dispatched through the public dao.Executor interface, so a hostile executor computes it per call while storing almost nothing. Measured on the real render path: a 250KB value costs 2,839,117,770 gas unclamped against 18,749,984 clamped. 250KB is just under the cap; about 265KB crosses it (3,008,818,394), and past that the page cannot be rendered at all by anyone. Choosing the larger number costs the attacker nothing, since the value is computed per call and almost nothing is stored. Removing that amplification is the point of this file. It does NOT make the page safe, and nothing here should be read as claiming so. The executor's method body runs inside the same query and is unbounded: an executor that simply burns CPU before returning a short string still renders the proposal page permanently un-queryable, for a few hundred bytes of on-chain storage. That predates this change — Render has always called ExecutorString() and ExecutorCreationRealm() through the public interface — and bounding it needs a gas budget around executor dispatch, not a clamp.

Value

(512 <untyped> bigint)

clampField

func(s string, max int) string

Always clamp first — before escaping, and before any other pass over the value. Trimming used to run before the clamp, which meant it walked every byte the executor returned: 250KB of spaces cost 1,368,719,824 gas to render nothing, and 560KB cost 3,048,904,520, past the query cap. Clamping first bounds that scan and brought the same 560KB down to 16,657,792. Never clamp after escaping either. The escapers size their wrapper from the string they are handed — InlineCode picks a fence long enough to outscan the backticks it can see. Cutting a value that has already been escaped can slice the closing fence off and leave the span hanging open, which is worse than not clamping at all. Both call sites read InlineCode(clampField(...)) for that reason, and the enormous-value case in filetests/executor\_disclosure\_filetest.gno fails if the two are swapped. clampField cuts s to at most max bytes, backing off to a rune boundary so a well-formed multi-byte character is not split, and marks the result so a reader can tell it was cut. Input that is already invalid UTF-8 can still leave a dangling lead byte; the sanitizer tolerates that. The marker avoids markdown punctuation: these values are escaped downstream, and parentheses would come back as "\\(truncated\\)".

Open
OID
01bbad…438b:3
clampField details

Inspect func

FilterByTier

type

Value

v0.FilterByTier

NewFilterByTier

func(tier string) v0.FilterByTier
Open
OID
01bbad…438b:5
NewFilterByTier details

Inspect func

ErrMemberNotFound

*errors.errorString
Open
OID
01bbad…438b:8
ErrMemberNotFound details

Inspect pointer

GovDAO

type

Value

v0.GovDAO

_govdao

*v0.GovDAO

Setting this to a global variable forces attaching the GovDAO struct to this realm. TODO replace with future \`attach()\`.

Open
OID
01bbad…438b:66
_govdao details

Inspect pointer

AddMember

func(addr .uverse.address)

AddMember allows T1 and T2 members to freely add T3 members using their invitation points.

Open
OID
01bbad…438b:38
AddMember details

Inspect func

GetInstance

func(int, rlm .uverse.realm) *v0.GovDAO

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.

Open
OID
01bbad…438b:39
GetInstance details

Inspect func

NewChangeLawRequest

func(newLaw v0.Law) dao.ProposalRequest
Open
OID
01bbad…438b:40
NewChangeLawRequest details

Inspect func

NewUpgradeDaoImplRequest

func(newDao dao.DAO, realmPkg string, reason string) dao.ProposalRequest
Open
OID
01bbad…438b:42
NewUpgradeDaoImplRequest details

Inspect func

NewAddMemberRequest

func(addr .uverse.address, tier string, portfolio string) dao.ProposalRequest
Open
OID
01bbad…438b:43
NewAddMemberRequest details

Inspect func

NewWithdrawMemberRequest

func(addr .uverse.address, reason string) dao.ProposalRequest
Open
OID
01bbad…438b:44
NewWithdrawMemberRequest details

Inspect func

NewPromoteMemberRequest

func(addr .uverse.address, fromTier string, toTier string) dao.ProposalRequest
Open
OID
01bbad…438b:45
NewPromoteMemberRequest details

Inspect func

NewTreasuryPaymentRequest

func(payment v0.Payment, reason string) dao.ProposalRequest
Open
OID
01bbad…438b:46
NewTreasuryPaymentRequest details

Inspect func

NewTreasuryGRC20TokensUpdate

func(newTokenKeys []string) dao.ProposalRequest

NewTreasuryGRC20TokensUpdate creates a proposal request to update the list of GRC20 tokens registry keys used by the treasury. The new list, if voted and accepted, will overwrite the current one.

Open
OID
01bbad…438b:47
NewTreasuryGRC20TokensUpdate details

Inspect func

memberByTier

func(tier string) *v0.Member
Open
OID
01bbad…438b:48
memberByTier details

Inspect func

render

type

Value

v0.render

NewRender

func(d *v0.GovDAO) *v0.render
Open
OID
01bbad…438b:49
NewRender details

Inspect func

isPropActive

func(ps *v0.proposalStatus) bool
Open
OID
01bbad…438b:51
isPropActive details

Inspect func

getPropStatus

func(ps *v0.proposalStatus) string
Open
OID
01bbad…438b:52
getPropStatus details

Inspect func

renderActionBar

func(sPid string) string
Open
OID
01bbad…438b:53
renderActionBar details

Inspect func

tryResolveAddr

func(addr .uverse.address) string

tryResolveAddr renders the author/voter as a username link. RenderLink interpolates the username raw into "\[@name](/u/name)" (r/sys/users), so this is markdown-safe ONLY because r/sys/users validateName restricts names to ^\[a-z]\[a-z0-9]\*(\[\_-]\[a-z0-9]+)\*$ (max 64) — no markdown/HTML metachar. If that charset ever loosens, this line and writeVotes in types.gno need escaping.

Open
OID
01bbad…438b:54
tryResolveAddr details

Inspect func

Law

type

Value

v0.Law

NewLaw

func(supermajority float64) v0.Law
Open
OID
01bbad…438b:55
NewLaw details

Inspect func

ProposalsStatuses

type

ProposalsStatuses contains the status of all the proposals indexed by the proposal ID.

Value

v0.ProposalsStatuses

NewProposalsStatuses

func() v0.ProposalsStatuses
Open
OID
01bbad…438b:57
NewProposalsStatuses details

Inspect func

proposalStatus

type

Value

v0.proposalStatus

getMembers

func() v0.MembersByTier
Open
OID
01bbad…438b:58
getMembers details

Inspect func

newEmptyVoteStore

func() v0.MembersByTier
Open
OID
01bbad…438b:59
newEmptyVoteStore details

Inspect func

newProposalStatus

func(allowedToVote []string) *v0.proposalStatus
Open
OID
01bbad…438b:60
newProposalStatus details

Inspect func

StringifyVotes

func(int, rlm .uverse.realm, ps *v0.proposalStatus) string
Open
OID
01bbad…438b:61
StringifyVotes details

Inspect func

writeVotes

func(int, rlm .uverse.realm, sb *strings.Builder, t v0.MembersByTier, title string)
Open
OID
01bbad…438b:62
writeVotes details

Inspect func

StringifyProposal

func(p *dao.Proposal) string
Open
OID
01bbad…438b:63
StringifyProposal details

Inspect func
maxRenderedRealm : untyped bigint =(256 <untyped> bigint)
maxRenderedReason : untyped bigint =(1024 <untyped> bigint)
maxRenderedError : untyped bigint =(256 <untyped> bigint)
maxRenderedTitle : untyped bigint =(512 <untyped> bigint)
maxRenderedPayment : untyped bigint =(512 <untyped> bigint)
clampField : func(s string, max int) string Inspect
FilterByTier : type =v0.FilterByTier
NewFilterByTier : func(tier string) v0.FilterByTier Inspect
ErrMemberNotFound : *errors.errorString Inspect
GovDAO : type =v0.GovDAO
NewGovDAO : func() *v0.GovDAO Inspect
_govdao : *v0.GovDAO Inspect
law : *v0.Law Inspect
govDAO : *v0.GovDAO Inspect
init.14 : func() Inspect
Render : func(in string) string Inspect
AddMember : func(addr .uverse.address) Inspect
GetInstance : func(int, rlm .uverse.realm) *v0.GovDAO Inspect
NewChangeLawRequest : func(newLaw v0.Law) dao.ProposalRequest Inspect
NewUpgradeDaoImplRequest : func(newDao dao.DAO, realmPkg string, reason string) dao.ProposalRequest Inspect
NewAddMemberRequest : func(addr .uverse.address, tier string, portfolio string) dao.ProposalRequest Inspect
NewWithdrawMemberRequest : func(addr .uverse.address, reason string) dao.ProposalRequest Inspect
NewPromoteMemberRequest : func(addr .uverse.address, fromTier string, toTier string) dao.ProposalRequest Inspect
NewTreasuryPaymentRequest : func(payment v0.Payment, reason string) dao.ProposalRequest Inspect
NewTreasuryGRC20TokensUpdate : func(newTokenKeys []string) dao.ProposalRequest Inspect
memberByTier : func(tier string) *v0.Member Inspect
render : type =v0.render
NewRender : func(d *v0.GovDAO) *v0.render Inspect
isPropActive : func(ps *v0.proposalStatus) bool Inspect
getPropStatus : func(ps *v0.proposalStatus) string Inspect
renderActionBar : func(sPid string) string Inspect
tryResolveAddr : func(addr .uverse.address) string Inspect
Law : type =v0.Law
NewLaw : func(supermajority float64) v0.Law Inspect
ProposalsStatuses : type =v0.ProposalsStatuses
NewProposalsStatuses : func() v0.ProposalsStatuses Inspect
proposalStatus : type =v0.proposalStatus
getMembers : func() v0.MembersByTier Inspect
newEmptyVoteStore : func() v0.MembersByTier Inspect
newProposalStatus : func(allowedToVote []string) *v0.proposalStatus Inspect
StringifyVotes : func(int, rlm .uverse.realm, ps *v0.proposalStatus) string Inspect
writeVotes : func(int, rlm .uverse.realm, sb *strings.Builder, t v0.MembersByTier, title string) Inspect
StringifyProposal : func(p *dao.Proposal) string Inspect