Held
Held returns H: the ugnot actually at this realm's address.
Command
gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/crowdfund.Held()"
Result
Realm crowdfund is permissionless all-or-nothing crowdfunding in GNOT: a creator opens a campaign with a funding goal and a block deadline, backers pledge real coins that the realm holds, and settlement is conditional — if the goal is reached by the deadline the creator may collect the pot (minus a bounded success fee), and if it is not, every backer reclaims exactly what they pledged, fee-free.
WHY THIS EXISTS (see DISCOVERY.md): at the heights recorded there, nothing on onyx-1 holds backer coins against a goal-and-deadline condition at all, and the one live crowdfunding realm in the wider ecosystem (mainnet r/moul/x/daily/crowdfund, read in full) is explicitly accounting-only — its own doc says "No real coin moves". The one real-coin implementation found anywhere ran on retired pearl-1 under a third-party namespace and is unreachable. This realm's delta is stated at that size and no larger: it is the assurance-contract mechanic — conditional custody with a fee-free refund path — done with this portfolio's live-validated custody discipline, not a new idea.
COMPOSITION: coin movement is delegated to coinio, fee arithmetic and the fee pot to feeledger, settlement timing and exactly-once authorization to duebook, ordered storage to p/nt/avl/v0, and free-text render output to the ecosystem sanitizer p/nt/markdown/sanitize/v0. This realm owns only the campaign state machine and the conservation bookkeeping.
THE SETTLEMENT IS ONE DEFERRAL. Launch schedules exactly one duebook deferral per campaign — owner: the creator, due: the deadline, expiry: the end of the claim window — and every terminal transition is one of the ways that deferral can be consumed:
1CreatorClaim -> book.Claim (due, goal met, creator collects)
2SettleFailed -> book.Claim (due, goal UNMET, anyone; duebook
3 leaves claim policy to its consumer)
4CreatorCancel -> book.Cancel (owner renounces, any time while open)
5Lapse -> book.Expire (anyone, once the claim window is over)
Because duebook consumes a deferral before returning and never reuses an ID, a campaign can settle AT MOST ONCE, structurally — double-claim is not guarded against, it is unrepresentable. The book's open- deferral cap is likewise this realm's cap on open campaigns.
LIFECYCLE (stored state in brackets; "succeeded"/"failed" are derived views of an open campaign after its deadline, not stored states):
1Launch (anyone) : opens [funding]; schedules the deferral.
2Pledge (backer, +send) : while height < deadline. Real coins.
3Unpledge (backer) : full own pledge back, while height <
4 deadline. All-or-nothing holds: nothing
5 is locked until the deadline passes.
6CreatorClaim (creator) : height in [deadline, claimDeadline),
7 raised >= goal -> [paid]. Pays
8 raised - fee to the creator, accrues the
9 fee. The ONLY transition that charges
10 anything.
11SettleFailed (ANYONE) : height >= deadline, raised < goal ->
12 [failed]. Makes the failure terminal and
13 frees the campaign's slots immediately;
14 refunds were already open on this path.
15CreatorCancel (creator) : while the deferral is open -> [cancelled].
16 Refunds open. A creator who cancels after
17 succeeding is renouncing the pot.
18Lapse (ANYONE) : height >= claimDeadline -> [lapsed].
19 Refunds open. The permissionless valve: a
20 creator who never collects cannot strand
21 backer money, and a dead campaign cannot
22 hold its duebook slot forever.
23Refund (backer) : own pledge back, fee-free, whenever the
24 campaign is [cancelled], [lapsed], or open
25 past its deadline with raised < goal.
26Prune (ANYONE) : removes a settled, fully-drained campaign
27 record. The freed storage deposit is
28 refunded by the chain to the CALLER, which
29 is the incentive to call it.
30WithdrawFees (ANYONE) : pays the accrued fee pot to the
31 compile-time FeeCollector. Permissionless
32 because the destination is fixed.
33SweepSurplus (ANYONE) : out-of-band coins to the FeeCollector,
34 never touching tracked liabilities.
REFUNDS NEVER RACE THE CLAIM: while a succeeded campaign is inside its claim window, Refund refuses — the pot is the creator's to collect. The moment the window ends (Lapse) or the creator renounces (Cancel), and at any time after a failed deadline, Refund pays each backer exactly their pledge. There is no partial outcome and no fee on any refund path, so a backer's worst case is their money back.
THE FEE, precisely: feeBps is snapshotted at Launch from the compile-time SuccessFeeBps, so a campaign's terms are fixed when it is created and visible in CampaignInfo from that moment. The fee is charged ONCE, at CreatorClaim, on the raised amount, with feeledger's floor rounding (rounding favors the creator). The ledger is constructed with the compile-time MaxFeeBps cap, so a fee above the cap is refused by the primitive, not by a check in this file. There is no fee on pledges, no fee on refunds, and no fee on failure.
THERE IS NO ADMIN. The fee rate, the fee collector, every bound and every window are compile-time constants; no address can change terms, pause the realm, or touch a campaign it does not own. The deployer has no privilege of any kind after deployment.
MONETARY INVARIANT (conservation): let H be the ugnot held at this realm's address, B the sum of raised amounts across all stored campaigns (tracked O(1) as totalBacked), F the accrued fee pot, and S >= 0 the out-of-band surplus:
1H == B + F + S
Every transition moves value between exactly two terms inside one transaction: Pledge raises H and B together (coinio.Receive is the receipt-guaranteed shape); Unpledge and Refund debit B before the identical amount leaves H (checks-effects-interactions); CreatorClaim moves one campaign's raised out of B, splits it into a creator payout (leaves H) and a fee (enters F); WithdrawFees debits F before the payout; any panic aborts the whole transaction; this realm never issues or removes coins.
ONLY GNOT IS ACCEPTED: Pledge rejects any envelope that is not exactly one positive ugnot coin (coinio.Receive). Every other entrypoint rejects attached coins outright rather than converting them into sweepable surplus.
AUTHORIZATION: every identity is derived from the crossing entrypoint's cur.Previous().Address(). No function takes a caller identity as a parameter, so pledging as another backer, claiming another creator's campaign, or refunding another backer's pledge is impossible by construction.
STORAGE: a backer's pledge entry is paid for by the backer's own transaction deposit; a campaign record by the creator's. CreatorClaim drops the whole pledge table in one assignment, and Prune removes the settled record — both free storage, and the chain refunds freed deposits to the transaction that frees them.
Held returns H: the ugnot actually at this realm's address.
gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/crowdfund.Held()"