Realm bounties is a GNOT bounty board that COMPOSES the reusable accounting package gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/feeledger instead of re-implementing balance accounting.
STATE OWNERSHIP (the dependency boundary):
- This realm owns the bounty state machine: bounty records (funder, title, amount, status, winner), the sum of open escrow (openTotal), and per-bounty funder authorization.
- feeledger owns all claimable-balance accounting: per-account balances, the protocol-fee pot, fee rounding, overflow checks, and withdraw arithmetic. This realm never duplicates that logic; it only calls the ledger API and panics on its errors.
LIFECYCLE:
Example
1CreateBounty (EOA + -send) : escrow -> openTotal, status Open
2Award (funder only) : openTotal -> ledger.Deposit(winner,
3 amount, snapshot fee)
4Cancel (funder only) : openTotal -> ledger.Deposit(funder,
5 amount, 0) [no fee on refund]
6Claim / ClaimAll (anyone) : pays out the caller's ledger balance
7WithdrawFees (fee recipient): pays out the fee pot
Awarded and Cancelled are terminal; a bounty transitions exactly once.
FEE MODEL: fee = floor(amount * bps / 10000), rounding favors the recipient, no minimum fee, admin-settable up to the compile-time MaxFeeBps cap, accrued to a pot withdrawable by the fee recipient role. The applicable bps is SNAPSHOTTED INTO THE BOUNTY AT CREATION and charged at Award: the funder commits to the fee they saw, and a later SetFeeBps affects only bounties created afterwards (this closes the admin front-run found in the composition audit). Refunds via Cancel are always fee-free. A failed Award (e.g. ledger overflow) leaves the bounty Open — the funder can retry or Cancel.
COMPOSED ACCOUNTING INVARIANT: let H be ugnot held at this realm's address, B = openTotal (application escrow), U+F the ledger's liabilities, S >= 0 out-of-band surplus. At every transaction boundary:
Example
1H == B + U + F + S
Derivation: CreateBounty raises H and B equally (the IsUserCall + envelope guard is the receipt-guaranteed shape, validated live on pearl-1); Award/Cancel move amount from B into U+F within one transaction, and feeledger guarantees credited + fee == amount; Claim/WithdrawFees debit the ledger before sending the identical amount (checks-effects-interactions), lowering H and U+F equally; any panic aborts the whole transaction; this realm never issues or removes coins. The application invariant B == Σ amount(Open) is maintained in lockstep with every status transition.
ONLY GNOT: CreateBounty rejects any envelope that is not exactly one positive ugnot coin. Foreign denominations force-sent to the realm sit in surplus and are recoverable via SweepDenom (fee recipient only), which never touches B, U, or F.