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

escrow.gno

2.51 Kb · 74 lines
 1package arena
 2
 3import (
 4	"chain"
 5	"chain/banker"
 6)
 7
 8// The money of the realm goes through the four functions below and nowhere
 9// else.
10//
11// escrowed is what the realm owes: the stakes of every lobby and of every
12// running round, in ugnot. It goes up in hold, when a player enters, and
13// down in release, before coins leave. The balance of the realm's address is
14// what it has. The rule of this file is
15//
16//	balance >= escrowed, and balance == escrowed unless someone gave coins away
17//
18// Coins can only come in through Enter: the chain refuses a call that
19// attaches coins to a function that does not read them. Someone can still
20// send coins straight to the realm's address with a bank transfer. Such
21// coins are owed to nobody, no function spends them, and they stay there.
22//
23// Every function that moves money ends with assertSolvent. If a mistake in
24// this realm ever made a path send more than it released, the realm would be
25// paying one player with the stake of another: the check turns that into an
26// aborted transaction, which takes the payments back with it.
27
28// payDenom is the only coin the realm deals in.
29const payDenom = "ugnot"
30
31// hold records that the realm received amount in stakes.
32func hold(amount int64) {
33	if amount <= 0 {
34		panic(errEscrow)
35	}
36	escrowed += amount
37}
38
39// release takes amount out of what the realm owes. It is called before the
40// coins are sent, and it panics rather than let the counter go below zero.
41func release(amount int64) {
42	if amount <= 0 || amount > escrowed {
43		panic(errEscrow)
44	}
45	escrowed -= amount
46}
47
48// pay sends amount ugnot from the realm's own balance to an address.
49//
50// A RealmSend banker can spend everything the realm holds, which is why it
51// is built here and only here, from the live cur of the crossing function
52// (rlm), and never kept. The bank aborts the transaction if the realm does
53// not have the coins.
54func pay(_ int, rlm realm, to address, amount int64) {
55	if amount <= 0 {
56		panic(errEscrow)
57	}
58	coins := chain.NewCoins(chain.NewCoin(payDenom, amount))
59	banker.NewBanker(banker.BankerTypeRealmSend, rlm).SendCoins(rlm.Address(), to, coins)
60}
61
62// assertSolvent panics unless the realm holds at least what it owes.
63func assertSolvent(_ int, rlm realm) {
64	if banker.NewReadonlyBanker().GetCoin(rlm.Address(), payDenom) < escrowed {
65		panic(errInsolvent)
66	}
67}
68
69// Escrowed returns what the realm owes to players, in ugnot: the stakes of
70// every lobby and of every running round. The balance of the realm's
71// address is never below it.
72func Escrowed() int64 {
73	return escrowed
74}