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

coindemo.gno

3.54 Kb · 118 lines
  1// Realm coindemo is a deliberately minimal third consumer proving the
  2// extracted primitives compose: coinio handles every coin movement,
  3// feeledger handles every balance. It is an echo-vault: deposit GNOT,
  4// claim it back in full (no fees), owner sweeps out-of-band surplus.
  5//
  6// Conservation: H == U + S (no fee pot, no app escrow), where U is the
  7// ledger's users total and S >= 0 is out-of-band surplus, recoverable
  8// only via the owner's Sweep which reserves U.
  9package coindemo
 10
 11import (
 12	"chain"
 13	"chain/runtime/unsafe"
 14	"strconv"
 15
 16	"gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/coinio"
 17	"gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/feeledger"
 18)
 19
 20// Denom is the only asset this realm accepts.
 21const Denom = "ugnot"
 22
 23var (
 24	owner  address // may sweep surplus
 25	self   address // this realm's address, captured at deploy
 26	ledger = feeledger.MustNew(0) // zero fee cap: pure echo accounting
 27)
 28
 29func init() {
 30	owner = unsafe.OriginCaller()
 31	self = unsafe.CurrentRealm().Address()
 32}
 33
 34// Deposit credits the caller with the attached GNOT, in full.
 35func Deposit(cur realm) {
 36	from, amount := coinio.Receive(0, cur, Denom)
 37	if _, _, err := ledger.Deposit(from.String(), amount, 0); err != nil {
 38		panic(err)
 39	}
 40	chain.Emit("Deposit", "from", from.String(), "amount", fmtInt(amount))
 41}
 42
 43// ClaimAll sends the caller's entire balance back. Fails if empty.
 44func ClaimAll(cur realm) {
 45	caller := cur.Previous().Address()
 46	amount, err := ledger.WithdrawAll(caller.String())
 47	if err != nil {
 48		panic(err)
 49	}
 50	if amount == 0 {
 51		panic("nothing to claim")
 52	}
 53	coinio.Payout(0, cur, caller, Denom, amount)
 54	chain.Emit("Claim", "to", caller.String(), "amount", fmtInt(amount))
 55}
 56
 57// Sweep sends ugnot held above user liabilities to the owner. Owner
 58// only; user balances are reserved by construction.
 59func Sweep(cur realm) {
 60	if cur.Previous().Address() != owner {
 61		panic("owner only")
 62	}
 63	swept := coinio.Sweep(0, cur, owner, Denom, ledger.Liabilities())
 64	chain.Emit("SurplusSwept", "to", owner.String(), "amount", fmtInt(swept))
 65}
 66
 67// TransferOwner hands the sweep role to next. Owner only; zero
 68// address rejected (audit Y3: without rotation, key loss permanently
 69// orphans surplus sweeping).
 70func TransferOwner(cur realm, next address) {
 71	if cur.Previous().Address() != owner {
 72		panic("owner only")
 73	}
 74	var zero address
 75	if next == zero {
 76		panic("empty owner address")
 77	}
 78	owner = next
 79	chain.Emit("OwnerTransferred", "newOwner", next.String())
 80}
 81
 82// --- read-only views ---
 83
 84// Owner returns who may sweep surplus.
 85func Owner() address { return owner }
 86
 87// BalanceOf returns addr's claimable balance.
 88func BalanceOf(addr address) int64 { return ledger.BalanceOf(addr.String()) }
 89
 90// UsersTotal returns the sum of all claimable balances.
 91func UsersTotal() int64 { return ledger.UsersTotal() }
 92
 93// Held returns the ugnot actually held at the realm address.
 94func Held() int64 { return coinio.HeldAt(self, Denom) }
 95
 96// Surplus returns Held() - UsersTotal().
 97func Surplus() int64 { return Held() - ledger.Liabilities() }
 98
 99// Address returns this realm's address (the deposit target).
100func Address() address { return self }
101
102// Render shows totals and the conservation check.
103func Render(_ string) string {
104	held := Held()
105	status := "OK"
106	if held < ledger.Liabilities() {
107		status = "VIOLATED"
108	}
109	return "# Coindemo\n\n" +
110		"Echo-vault composing coinio + feeledger.\n\n" +
111		"- claimable (U): " + fmtInt(ledger.UsersTotal()) + Denom + "\n" +
112		"- held (H): " + fmtInt(held) + Denom + "\n" +
113		"- conservation (H >= U): " + status + "\n"
114}
115
116func fmtInt(n int64) string {
117	return strconv.FormatInt(n, 10)
118}