RealmPath
untyped stringRealmPath is this realm's own path, used to build Render links.
Value
"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/budgets"
Denom
untyped stringDenom is the only asset this realm holds.
Value
"ugnot"
MaxFeeBps
int64MaxFeeBps 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
int64DrawFeeBps 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.addressFeeCollector 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
int64MinFunding keeps dust pools out: 1 GNOT per Fund call.
Value
1000000
MinPerPeriod
int64MinPerPeriod 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
int64MinPeriodBlocks 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 bigintMaxLiveGrants 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
int64MaxGrantsPerOwner 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 bigintMaxLabelLen bounds the grant's free-text label, which is sanitized before reaching markdown.
Value
(64 <untyped> bigint)
MaxRenderRows
untyped bigintMaxRenderRows bounds the grant list on the index page.
Value
(20 <untyped> bigint)
grant
typeValue
budgets.grant
self
.uverse.addressValue
<gnolang.StringValue>
grants
*v0.Tree// padID(id) -> \*grant
- OID
- 0e45f2…b0a2:5
grants details
nextID
int64Value
4
pools
*v0.Tree- OID
- 0e45f2…b0a2:9
pools details
openByOwner
*v0.Tree- OID
- 0e45f2…b0a2:12
openByOwner details
totalPooled
int64Value
0
lifetimeFunded
int64Value
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
ledger
*feeledger.Ledger- OID
- 0e45f2…b0a2:20
ledger details
book
*spendbook.Book- OID
- 0e45f2…b0a2:25
book details
init.25
func()- OID
- 0e45f2…b0a2:29
init.25 details
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).
- OID
- 0e45f2…b0a2:31
rejectStraySend details
Fund
func() int64Fund 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.
- OID
- 0e45f2…b0a2:32
Fund details
WithdrawPool
func(amount int64) int64WithdrawPool 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.
- OID
- 0e45f2…b0a2:33
WithdrawPool details
WithdrawPoolAll
func() int64WithdrawPoolAll 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.
- OID
- 0e45f2…b0a2:34
WithdrawPoolAll details
payOutPool
func(owner .uverse.address, amount int64) int64payOutPool 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).
- OID
- 0e45f2…b0a2:35
payOutPool details
Grant
func(spender .uverse.address, label string, perPeriod int64, periodLength int64, total int64, expiresAt int64) int64Grant 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.
- OID
- 0e45f2…b0a2:36
Grant details
Amend
func(id int64, perPeriod int64, total int64, expiresAt int64) boolAmend 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.
- OID
- 0e45f2…b0a2:37
Amend details
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.
- OID
- 0e45f2…b0a2:38
Revoke details
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.
- OID
- 0e45f2…b0a2:39
Reap details
Draw
func(id int64, amount int64) int64Draw 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.
- OID
- 0e45f2…b0a2:40
Draw details
Claim
func() int64Claim 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.
- OID
- 0e45f2…b0a2:41
Claim details
WithdrawFees
func() int64WithdrawFees 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.
- OID
- 0e45f2…b0a2:42
WithdrawFees details
SweepSurplus
func(denom string) int64SweepSurplus 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.
- OID
- 0e45f2…b0a2:43
SweepSurplus details
GrantInfo
func(id int64) (owner .uverse.address, spender .uverse.address, perPeriod int64, periodLength int64, total int64, expiresAt int64, anchor int64, createdAt int64, feeBps int64)- OID
- 0e45f2…b0a2:44
GrantInfo details
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.
- OID
- 0e45f2…b0a2:45
GrantUsage details
GrantLabel
func(id int64) stringGrantLabel returns a grant's raw label (unsanitized: callers rendering it into markdown must sanitize, as this realm's Render does).
- OID
- 0e45f2…b0a2:46
GrantLabel details
Remaining
func(id int64) int64Remaining is the AUTHORITY figure: what the grant's terms permit right now, ignoring whether the owner's pool can cover it.
- OID
- 0e45f2…b0a2:47
Remaining details
Drawable
func(id int64) int64Drawable 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.
- OID
- 0e45f2…b0a2:48
Drawable details
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.
- OID
- 0e45f2…b0a2:49
PendingTerms details
IsExpired
func(id int64) boolIsExpired reports whether a grant's authority has lapsed, which is also the condition under which anyone may Reap it.
- OID
- 0e45f2…b0a2:50
IsExpired details
PoolOf
func(addr .uverse.address) int64PoolOf returns an owner's unspent pool.
- OID
- 0e45f2…b0a2:51
PoolOf details
CreditOf
func(addr .uverse.address) int64CreditOf returns a delegate's drawn-but-unclaimed credit.
- OID
- 0e45f2…b0a2:52
CreditOf details
GrantsOf
func(addr .uverse.address) int64GrantsOf returns how many live grants an owner currently holds.
- OID
- 0e45f2…b0a2:53
GrantsOf details
NumGrants
func() int64NumGrants returns how many grants have ever been created. Ids are never reused, so this only grows.
- OID
- 0e45f2…b0a2:54
NumGrants details
LiveGrants
func() int64LiveGrants returns how many grants are currently live, from the primitive's own count.
- OID
- 0e45f2…b0a2:55
LiveGrants details
TotalPooled
func() int64TotalPooled returns the P term: unspent owner funds.
- OID
- 0e45f2…b0a2:56
TotalPooled details
UnclaimedCredit
func() int64UnclaimedCredit returns the delegates' share of the L term.
- OID
- 0e45f2…b0a2:57
UnclaimedCredit details
FeesAccrued
func() int64FeesAccrued returns the fee pot: charged, not yet withdrawn.
- OID
- 0e45f2…b0a2:58
FeesAccrued details
Liabilities
func() int64Liabilities returns P + L — everything this realm owes.
- OID
- 0e45f2…b0a2:59
Liabilities details
Held
func() int64Held returns H: the ugnot actually at this realm's address.
- OID
- 0e45f2…b0a2:60
Held details
Surplus
func() int64Surplus returns H - (P + L) — out-of-band coins, sweepable.
- OID
- 0e45f2…b0a2:61
Surplus details
Address
func() .uverse.address- OID
- 0e45f2…b0a2:62
Address details
Height
func() int64Height returns the current chain height: the clock every window and expiry is measured against, and the one no caller can choose.
- OID
- 0e45f2…b0a2:63
Height details
Render
func(path string) stringRender shows the realm at "" and a grant page at "\<id>". Labels are free text and pass through the ecosystem sanitizer before hitting markdown.
- OID
- 0e45f2…b0a2:64
Render details
renderGrant
func(path string) string- OID
- 0e45f2…b0a2:65
renderGrant details
mustGet
func(id int64) *budgets.grant- OID
- 0e45f2…b0a2:66
mustGet details
mustAllowance
func(g *budgets.grant) spendbook.AllowancemustAllowance 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".
- OID
- 0e45f2…b0a2:67
mustAllowance details
windowAt
func(a spendbook.Allowance, now int64) int64windowAt 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.
- OID
- 0e45f2…b0a2:68
windowAt details
spentInWindow
func(a spendbook.Allowance, now int64) int64- OID
- 0e45f2…b0a2:69
spentInWindow details
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.
- OID
- 0e45f2…b0a2:70
drop details
labelOr
func(g *budgets.grant) string- OID
- 0e45f2…b0a2:71
labelOr details
poolOf
func(key string) int64- OID
- 0e45f2…b0a2:72
poolOf details
setPool
func(key string, n int64)- OID
- 0e45f2…b0a2:73
setPool details
ownerOpen
func(key string) int64- OID
- 0e45f2…b0a2:74
ownerOpen details
setOwnerOpen
func(key string, n int64)- OID
- 0e45f2…b0a2:75
setOwnerOpen details
decOwnerOpen
func(key string)- OID
- 0e45f2…b0a2:76
decOwnerOpen details
itoa
func(n int64) string- OID
- 0e45f2…b0a2:77
itoa details
boolstr
func(b bool) string- OID
- 0e45f2…b0a2:78
boolstr details
bps
func(n int64) stringbps renders a basis-point figure as a human percentage, exactly.
- OID
- 0e45f2…b0a2:79
bps details
padID
func(id int64) stringpadID encodes an id so avl's lexical order matches numeric order.
- OID
- 0e45f2…b0a2:80
padID details
zeros
untyped stringValue
"00000000000000000000"
checkedAdd
func(a int64, b int64) (int64, bool)checkedAdd returns a+b and reports whether the addition did not overflow int64.
- OID
- 0e45f2…b0a2:81