Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

budgets state

Back to all declarations

RealmPath

untyped string

RealmPath is this realm's own path, used to build Render links.

Value

"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/budgets"

Denom

untyped string

Denom is the only asset this realm holds.

Value

"ugnot"

MaxFeeBps

int64

MaxFeeBps is the hard ceiling on any draw fee this realm could ever charge, enforced by the feeledger the realm is constructed with — a feeBps above it is refused by the primitive's own validation, not by a check in this file. 500 bps = 5%.

Value

500

DrawFeeBps

int64

DrawFeeBps is the fee actually snapshotted into every grant: 100 bps = 1%, charged once per draw on the gross amount, floor-rounded in the delegate's favor. The most conservative live fee in this portfolio (fee\_split, crowdfund) is also 1%.

Value

100

FeeCollector

.uverse.address

FeeCollector receives withdrawn fees and swept surplus. Compile-time constant: there is no setter and no transfer path. It is the deploying namespace's address — stated plainly: the operator of this realm.

Value

<gnolang.StringValue>

MinFunding

int64

MinFunding keeps dust pools out: 1 GNOT per Fund call.

Value

1000000

MinPerPeriod

int64

MinPerPeriod is the smallest per-window cap a grant may carry. It exists so a grant cannot be created that no draw could ever satisfy, and it is the ONLY lower bound in the draw path — there is deliberately no minimum Draw amount, because a minimum draw above a grant's PerPeriod would make the grant silently undrawable.

Value

1000

MinPeriodBlocks

int64

MinPeriodBlocks is the shortest rolling window a grant may use. A window of a handful of blocks is a rate, not a budget, and it makes PerPeriod meaningless as a bound on worst-case loss. A periodLength of 0 is still accepted and means ONE LIFETIME WINDOW that never refills (spendbook's own semantics).

Value

100

MaxLiveGrants

untyped bigint

MaxLiveGrants caps simultaneously live grants, via spendbook's own construction bound. Grant is permissionless to anyone with a funded pool, so the cap is exhaustible in principle, and that AVAILABILITY BOUND is documented rather than hidden. It is documented here in its CORRECTED form. An earlier version of this comment claimed the mitigation was "MaxGrantsPerOwner plus the cost of becoming an owner at all (MinFunding per pool), and Reap is permissionless so expired grants cannot accumulate". An adversarial audit (finding Y1, DISCOVERY.md § 9) showed BOTH HALVES were false. A wrong mitigation is worse than an acknowledged bound, because a reader sizes the risk from it and stops looking: - MinFunding is NOT a capital bound. The funded-pool requirement is checked at Grant time only, and WithdrawPool has no lock, so one address funds a pool, opens MaxGrantsPerOwner grants, withdraws the pool in full, and the grants survive holding their slots. TestOwnerCanAlwaysLeave pins exactly that sequence, as intended behavior — the attack is built out of a documented feature. - Reap is inert against it. Reap requires spendbook's IsExpired, which is never true for expiresAt == 0, so an attacker omits the expiry and no third party can remove the grant. What the cost ACTUALLY is: gas for one Fund, MaxGrantsPerOwner Grants and one WithdrawPoolAll per address — about MaxLiveGrants\*17/16 transactions to fill the cap — plus the storage deposit on every grant record, which the chain holds for as long as the grant does and refunds only when it is removed. That is real and unrecoverable while the grief lasts. It is not the locked pool capital the old comment promised, and it is priced in gas and storage rather than in capital. No capital bound was added, because the obvious one does not work. Requiring an owner with live grants to retain MinFunding is defeated for the price of the draw fee: nothing forbids granting to YOURSELF, so the attacker draws its own pool to zero through its own grant and Claims the credit back, recovering all but DrawFeeBps of it while the retention rule still reads as satisfied. Closing THAT would mean bounding Draw below MinFunding — the realm refusing to let a delegate spend the budget, which is the feature. The remaining alternative, a non-refundable per-grant fee, taxes every honest owner to price a grief, and at a fee high enough to deter one it is a tenth of MinFunding per grant. The blast radius is narrow and that is the reason this is disclosed rather than redesigned: a full book blocks NEW grants only. Every existing grant, pool, draw, credit and claim keeps working, no value is at risk, and any owner can free their own slots with Revoke. The figure was 1024 until that audit, and 1024 was conservative rather than measured: nothing in this realm iterates the book (Render is bounded by MaxRenderRows, every write path is a single avl lookup) and a grant record's storage is paid for by whoever creates it. Quadrupling it quadruples the cost of filling the cap and costs an honest owner nothing. spendbook's own MaxLiveLimit is 10000.

Value

(4096 <untyped> bigint)

MaxGrantsPerOwner

int64

MaxGrantsPerOwner bounds how much of the global cap one owner can occupy. spendbook's own package documentation names this as the gap a consuming realm must close — "maxLive is a single global figure, so any owner permitted to Open can exhaust it and lock out the rest … the consuming realm decides who may Open, and a Book shared across mutually untrusting owners needs its own per-owner cap on top of this one." This is that cap. (permission\_registry finding R1 is the same lesson from this portfolio's own history.)

Value

16

MaxLabelLen

untyped bigint

MaxLabelLen bounds the grant's free-text label, which is sanitized before reaching markdown.

Value

(64 <untyped> bigint)

MaxRenderRows

untyped bigint

MaxRenderRows bounds the grant list on the index page.

Value

(20 <untyped> bigint)

grant

type

Value

budgets.grant

self

.uverse.address

Value

<gnolang.StringValue>

nextID

int64

Value

4

totalPooled

int64

Value

0

lifetimeFunded

int64

Value

7000000

lifetimeDrawn

int64

// gross, before the fee

Value

3101099

lifetimeClaimed

int64

// net, paid to delegates

Value

3070089

lifetimeReturned

int64

// unspent pool withdrawn by owners

Value

3898901

rejectStraySend

func()

rejectStraySend aborts when coins are attached to a non-payable call. This realm holds funds, so a stray send would become sweepable surplus, silently converting a user's coins into operator funds. Aborting reverts the transfer instead. Guarded on IsUserCall, not IsUser, because a MsgRun ephemeral can consume the OriginSend envelope before forwarding control; for a realm-routed call the envelope lands at the intermediary, so there is nothing here to reject and the guard deliberately fails open (crowdfund and treasury\_board document the same scope).

Open
OID
0e45f2…b0a2:31
rejectStraySend details

Inspect func

Fund

func() int64

Fund adds the attached coins to the caller's own pool. Direct EOA calls with -send only (the receipt-guaranteed shape); exactly one positive ugnot coin, at least MinFunding. Anyone may fund; funding is what makes an address an owner.

Open
OID
0e45f2…b0a2:32
Fund details

Inspect func

WithdrawPool

func(amount int64) int64

WithdrawPool returns part of the caller's unspent pool and reports the pool REMAINING afterwards. There is no lock and no check against outstanding grants: the money is the owner's, and a delegate's authority is not a claim on it (see the package doc, "the owner can always leave"). Revoke is the clean way to end a grant.

Open
OID
0e45f2…b0a2:33
WithdrawPool details

Inspect func

WithdrawPoolAll

func() int64

WithdrawPoolAll returns the caller's entire unspent pool and reports the amount WITHDRAWN. The return values of the two withdraw entrypoints are deliberately asymmetric, which is worth naming rather than letting a caller discover: each returns the figure its caller does not already have. WithdrawPool was told the amount and wants to know what is left; WithdrawPoolAll knows what is left (nothing) and wants to know what it got. Returning the remainder here would hand every caller a constant 0.

Open
OID
0e45f2…b0a2:34
WithdrawPoolAll details

Inspect func

payOutPool

func(owner .uverse.address, amount int64) int64

payOutPool is the shared debit-then-send path: the pool and the P term are reduced before the identical amount leaves the realm (checks-effects-interactions).

Open
OID
0e45f2…b0a2:35
payOutPool details

Inspect func

Grant

func(spender .uverse.address, label string, perPeriod int64, periodLength int64, total int64, expiresAt int64) int64

Grant opens a standing spending authority for one delegate and returns the grant id. The caller becomes the grant's owner and must already have a funded pool — not because the grant reserves anything (it does not), but because a grant from an address that has never funded anything is a promise with nothing behind it, and this realm declines to record one. Terms, all in the chain's own units: perPeriod the cap per window, at least MinPerPeriod. Required. periodLength blocks per window. 0 means ONE LIFETIME WINDOW that never refills; otherwise at least MinPeriodBlocks. total lifetime cap across every window. 0 means unlimited. expiresAt absolute block height at which authority ends. 0 means no expiry. Every bound above except the two realm minimums is validated and enforced by spendbook, and an invalid combination surfaces as that package's own sentinel error.

Open
OID
0e45f2…b0a2:36
Grant details

Inspect func

Amend

func(id int64, perPeriod int64, total int64, expiresAt int64) bool

Amend changes a grant's terms. Owner only. The returned bool reports whether the new terms are in force NOW (a tighter-or-equal amendment) or queued for the next window boundary (a looser one) — spendbook's one-sided rule, and the distinction worth knowing. periodLength is NOT a parameter. spendbook makes it immutable because moving it would move every future boundary, which is an enlargement vector wearing a different hat; this realm reads the grant's own periodLength and passes it unchanged, so changing it is not merely refused, it is unexpressible.

Open
OID
0e45f2…b0a2:37
Amend details

Inspect func

Revoke

func(id int64)

Revoke ends a grant immediately. Owner only. The id is never reused, so a revoked grant cannot be resurrected and a later Draw against it fails as unknown. Revoking does NOT claw back credit the delegate has already drawn — that is theirs and stays claimable. Revoke ends future authority.

Open
OID
0e45f2…b0a2:38
Revoke details

Inspect func

Reap

func(id int64)

Reap removes a grant whose authority has EXPIRED, freeing its slot and its storage. Anyone may call it, and the reasoning is spendbook's own: an expired allowance can never authorize another draw, so removing it takes nothing from the owner and grants nothing to the caller. The chain refunds the freed storage deposit to the reaping transaction, which is the standing incentive. A grant with no expiry can never be reaped; only its owner can end it.

Open
OID
0e45f2…b0a2:39
Reap details

Inspect func

Draw

func(id int64, amount int64) int64

Draw spends amount from the grant's budget. DELEGATE ONLY: the spender is the calling address, never an argument. Nothing is paid out here — the delegate is credited net of the fee and claims separately. Three things must all hold and they fail in this order, which matters: the caller must be the grant's delegate and the amount must be within every spendbook bound (window cap, lifetime cap, expiry, start); and the owner's pool must cover the GROSS amount. The solvency check runs BEFORE the allowance is consumed, so a draw refused for insolvency leaves the budget untouched rather than burning window capacity on a draw that did not happen.

Open
OID
0e45f2…b0a2:40
Draw details

Inspect func

Claim

func() int64

Claim pays the caller's entire accrued credit out. DELEGATE ONLY: the account is the calling address. Credit from a grant that has since been revoked, expired or reaped is still claimable — it was earned under a live authority and this realm does not revisit that.

Open
OID
0e45f2…b0a2:41
Claim details

Inspect func

WithdrawFees

func() int64

WithdrawFees pays the entire accrued fee pot to the compile-time FeeCollector. Anyone may call it: the destination is fixed, so there is nothing for a caller to steer.

Open
OID
0e45f2…b0a2:42
WithdrawFees details

Inspect func

SweepSurplus

func(denom string) int64

SweepSurplus sends out-of-band coins to the FeeCollector: for the pool denom, everything above tracked liabilities; for any foreign denom, the full balance. Owner pools, delegate credit and the fee pot are untouchable by construction (coinio.Sweep refuses to dip below the reserve). Anyone may call it. With nothing out of band this ABORTS ("coinio: no surplus to sweep for \<denom>") rather than returning 0. That is the primitive's choice and the right one: a sweep is a transfer, and a transfer of nothing that reports success is how a caller comes to believe a balance was moved.

Open
OID
0e45f2…b0a2:43
SweepSurplus details

Inspect func

GrantInfo

func(id int64) (owner .uverse.address, spender .uverse.address, perPeriod int64, periodLength int64, total int64, expiresAt int64, anchor int64, createdAt int64, feeBps int64)
Open
OID
0e45f2…b0a2:44
GrantInfo details

Inspect func

GrantUsage

func(id int64) (spentWindow int64, spentTotal int64, windowIndex int64, draws int64)

GrantUsage returns a grant's consumption AT THE CURRENT HEIGHT: what the window the chain is in right now has spent, the lifetime gross, that window's index, and how many draws there have been. The two window figures are computed rather than read straight off the record, and that is the whole point of windowAt below: a window that has rolled with no draw since leaves Allowance.WindowIndex naming a window the chain has already left, and Allowance.SpentWindow holding the previous window's spend. spentTotal and draws are cumulative and never go stale.

Open
OID
0e45f2…b0a2:45
GrantUsage details

Inspect func

GrantLabel

func(id int64) string

GrantLabel returns a grant's raw label (unsanitized: callers rendering it into markdown must sanitize, as this realm's Render does).

Open
OID
0e45f2…b0a2:46
GrantLabel details

Inspect func

Remaining

func(id int64) int64

Remaining is the AUTHORITY figure: what the grant's terms permit right now, ignoring whether the owner's pool can cover it.

Open
OID
0e45f2…b0a2:47
Remaining details

Inspect func

Drawable

func(id int64) int64

Drawable is the HONEST figure, and the one a delegate should read: the lesser of what the grant authorizes and what the owner's pool holds. This distinction is the realm's own — spendbook bounds permission and says so, never solvency.

Open
OID
0e45f2…b0a2:48
Drawable details

Inspect func

PendingTerms

func(id int64) (perPeriod int64, total int64, expiresAt int64, pending bool)

PendingTerms returns a queued loosening amendment and whether there is one. An amendment is queued only when it would widen the live window, and it takes effect at the next window boundary.

Open
OID
0e45f2…b0a2:49
PendingTerms details

Inspect func

IsExpired

func(id int64) bool

IsExpired reports whether a grant's authority has lapsed, which is also the condition under which anyone may Reap it.

Open
OID
0e45f2…b0a2:50
IsExpired details

Inspect func

PoolOf

func(addr .uverse.address) int64

PoolOf returns an owner's unspent pool.

Open
OID
0e45f2…b0a2:51
PoolOf details

Inspect func

CreditOf

func(addr .uverse.address) int64

CreditOf returns a delegate's drawn-but-unclaimed credit.

Open
OID
0e45f2…b0a2:52
CreditOf details

Inspect func

GrantsOf

func(addr .uverse.address) int64

GrantsOf returns how many live grants an owner currently holds.

Open
OID
0e45f2…b0a2:53
GrantsOf details

Inspect func

NumGrants

func() int64

NumGrants returns how many grants have ever been created. Ids are never reused, so this only grows.

Open
OID
0e45f2…b0a2:54
NumGrants details

Inspect func

LiveGrants

func() int64

LiveGrants returns how many grants are currently live, from the primitive's own count.

Open
OID
0e45f2…b0a2:55
LiveGrants details

Inspect func

TotalPooled

func() int64

TotalPooled returns the P term: unspent owner funds.

Open
OID
0e45f2…b0a2:56
TotalPooled details

Inspect func

UnclaimedCredit

func() int64

UnclaimedCredit returns the delegates' share of the L term.

Open
OID
0e45f2…b0a2:57
UnclaimedCredit details

Inspect func

FeesAccrued

func() int64

FeesAccrued returns the fee pot: charged, not yet withdrawn.

Open
OID
0e45f2…b0a2:58
FeesAccrued details

Inspect func

Liabilities

func() int64

Liabilities returns P + L — everything this realm owes.

Open
OID
0e45f2…b0a2:59
Liabilities details

Inspect func

Held

func() int64

Held returns H: the ugnot actually at this realm's address.

Open
OID
0e45f2…b0a2:60
Held details

Inspect func

Surplus

func() int64

Surplus returns H - (P + L) — out-of-band coins, sweepable.

Open
OID
0e45f2…b0a2:61
Surplus details

Inspect func

Height

func() int64

Height returns the current chain height: the clock every window and expiry is measured against, and the one no caller can choose.

Open
OID
0e45f2…b0a2:63
Height details

Inspect func

Render

func(path string) string

Render shows the realm at "" and a grant page at "\<id>". Labels are free text and pass through the ecosystem sanitizer before hitting markdown.

Open
OID
0e45f2…b0a2:64
Render details

Inspect func

renderGrant

func(path string) string
Open
OID
0e45f2…b0a2:65
renderGrant details

Inspect func

mustGet

func(id int64) *budgets.grant
Open
OID
0e45f2…b0a2:66
mustGet details

Inspect func

mustAllowance

func(g *budgets.grant) spendbook.Allowance

mustAllowance fetches the spendbook allowance behind a grant. The pair is created and removed together, so a missing allowance is a bug in this realm rather than a user error, and it panics rather than reporting a zero value that a reader would take for "no authority".

Open
OID
0e45f2…b0a2:67
mustAllowance details

Inspect func

windowAt

func(a spendbook.Allowance, now int64) int64

windowAt returns the anchored window index containing now, and spentInWindow what that window has spent. These duplicate a line of spendbook, and the duplication is deliberate, bounded, and worth justifying because the primitive's own at() comment warns against exactly this. What is NOT reimplemented is the part that warning is about: which terms are in force after a boundary, and therefore every authority figure this realm reports — Remaining and Drawable both call through to the primitive, and nothing here second- guesses them. What is copied is pure index arithmetic over three EXPORTED fields plus the already-documented fact that the in-window spend RESETS rather than carries. The alternative is worse than the duplication: Allowance's WindowIndex and SpentWindow are the last-WRITTEN pair, so between a boundary and the next draw they describe a window the chain has left, and a Render publishing them would print "spent this window: 100000" immediately above "authorized by the terms: 100000". The two are pinned to the primitive by TestWindowRefillsAtAnchoredBoundary rather than by inspection: it draws after crossing a boundary and asserts spentWindow equals that draw, which can only hold if windowAt agreed with spendbook's own index at the moment of the write.

Open
OID
0e45f2…b0a2:68
windowAt details

Inspect func

spentInWindow

func(a spendbook.Allowance, now int64) int64
Open
OID
0e45f2…b0a2:69
spentInWindow details

Inspect func

drop

func(g *budgets.grant)

drop removes a grant record and decrements its owner's live count. The allowance itself is removed by the spendbook call that precedes every caller of this helper.

Open
OID
0e45f2…b0a2:70
drop details

Inspect func

labelOr

func(g *budgets.grant) string
Open
OID
0e45f2…b0a2:71
labelOr details

Inspect func

setPool

func(key string, n int64)
Open
OID
0e45f2…b0a2:73
setPool details

Inspect func

ownerOpen

func(key string) int64
Open
OID
0e45f2…b0a2:74
ownerOpen details

Inspect func

setOwnerOpen

func(key string, n int64)
Open
OID
0e45f2…b0a2:75
setOwnerOpen details

Inspect func

decOwnerOpen

func(key string)
Open
OID
0e45f2…b0a2:76
decOwnerOpen details

Inspect func

bps

func(n int64) string

bps renders a basis-point figure as a human percentage, exactly.

Open
OID
0e45f2…b0a2:79
bps details

Inspect func

padID

func(id int64) string

padID encodes an id so avl's lexical order matches numeric order.

Open
OID
0e45f2…b0a2:80
padID details

Inspect func

zeros

untyped string

Value

"00000000000000000000"

checkedAdd

func(a int64, b int64) (int64, bool)

checkedAdd returns a+b and reports whether the addition did not overflow int64.

Open
OID
0e45f2…b0a2:81
checkedAdd details

Inspect func
RealmPath : untyped string ="/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/budgets"
Denom : untyped string ="ugnot"
MaxFeeBps : int64 =500
DrawFeeBps : int64 =100
FeeCollector : .uverse.address =<gnolang.StringValue>
MinFunding : int64 =1000000
MinPerPeriod : int64 =1000
MinPeriodBlocks : int64 =100
MaxLiveGrants : untyped bigint =(4096 <untyped> bigint)
MaxGrantsPerOwner : int64 =16
MaxLabelLen : untyped bigint =(64 <untyped> bigint)
MaxRenderRows : untyped bigint =(20 <untyped> bigint)
grant : type =budgets.grant
self : .uverse.address =<gnolang.StringValue>
grants : *v0.Tree Inspect
nextID : int64 =4
pools : *v0.Tree Inspect
openByOwner : *v0.Tree Inspect
totalPooled : int64 =0
lifetimeFunded : int64 =7000000
lifetimeDrawn : int64 =3101099
lifetimeClaimed : int64 =3070089
lifetimeReturned : int64 =3898901
ledger : *feeledger.Ledger Inspect
book : *spendbook.Book Inspect
init.25 : func() Inspect
rejectStraySend : func() Inspect
Fund : func() int64 Inspect
WithdrawPool : func(amount int64) int64 Inspect
WithdrawPoolAll : func() int64 Inspect
payOutPool : func(owner .uverse.address, amount int64) int64 Inspect
Grant : func(spender .uverse.address, label string, perPeriod int64, periodLength int64, total int64, expiresAt int64) int64 Inspect
Amend : func(id int64, perPeriod int64, total int64, expiresAt int64) bool Inspect
Revoke : func(id int64) Inspect
Reap : func(id int64) Inspect
Draw : func(id int64, amount int64) int64 Inspect
Claim : func() int64 Inspect
WithdrawFees : func() int64 Inspect
SweepSurplus : func(denom string) int64 Inspect
GrantInfo : func(id int64) (owner .uverse.address, spender .uverse.address, perPeriod int64, periodLength int64, total int64, expiresAt int64, anchor int64, createdAt int64, feeBps int64) Inspect
GrantUsage : func(id int64) (spentWindow int64, spentTotal int64, windowIndex int64, draws int64) Inspect
GrantLabel : func(id int64) string Inspect
Remaining : func(id int64) int64 Inspect
Drawable : func(id int64) int64 Inspect
PendingTerms : func(id int64) (perPeriod int64, total int64, expiresAt int64, pending bool) Inspect
IsExpired : func(id int64) bool Inspect
PoolOf : func(addr .uverse.address) int64 Inspect
CreditOf : func(addr .uverse.address) int64 Inspect
GrantsOf : func(addr .uverse.address) int64 Inspect
NumGrants : func() int64 Inspect
LiveGrants : func() int64 Inspect
TotalPooled : func() int64 Inspect
UnclaimedCredit : func() int64 Inspect
FeesAccrued : func() int64 Inspect
Liabilities : func() int64 Inspect
Held : func() int64 Inspect
Surplus : func() int64 Inspect
Address : func() .uverse.address Inspect
Height : func() int64 Inspect
Render : func(path string) string Inspect
renderGrant : func(path string) string Inspect
mustGet : func(id int64) *budgets.grant Inspect
mustAllowance : func(g *budgets.grant) spendbook.Allowance Inspect
windowAt : func(a spendbook.Allowance, now int64) int64 Inspect
spentInWindow : func(a spendbook.Allowance, now int64) int64 Inspect
drop : func(g *budgets.grant) Inspect
labelOr : func(g *budgets.grant) string Inspect
poolOf : func(key string) int64 Inspect
setPool : func(key string, n int64) Inspect
ownerOpen : func(key string) int64 Inspect
setOwnerOpen : func(key string, n int64) Inspect
decOwnerOpen : func(key string) Inspect
itoa : func(n int64) string Inspect
boolstr : func(b bool) string Inspect
bps : func(n int64) string Inspect
padID : func(id int64) string Inspect
zeros : untyped string ="00000000000000000000"
checkedAdd : func(a int64, b int64) (int64, bool) Inspect