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

tellers_test.gno

5.15 Kb · 153 lines
  1package grc20
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/testutils/v0"
  7	"gno.land/p/nt/uassert/v0"
  8	"gno.land/p/nt/ufmt/v0"
  9	"gno.land/p/nt/urequire/v0"
 10)
 11
 12func TestCallerTellerImpl(cur realm, t *testing.T) {
 13	tok, ledger := newTestToken("Dummy", "DUMMY", 4, 0, cur)
 14	teller := ledger.CallerTeller()
 15	urequire.False(t, tok == nil)
 16	var _ Teller = teller
 17}
 18
 19// The sub-realm case (guardHome must not lock out the token's own realm when it
 20// operates under an identity minted by its own cur.Sub()) needs a real realm
 21// frame, since cur.Sub() refuses to mint from a p/ package. It lives in
 22// filetests/caller_teller_sub_realm_filetest.gno.
 23
 24// evilWrap embeds Teller; the seal-marker pattern (if we had one) would be
 25// satisfied via promotion, but IsCanonicalTeller rejects it because *evilWrap
 26// is nominally distinct from *fnTeller.
 27type evilWrap struct {
 28	Teller
 29}
 30
 31func TestIsCanonicalTeller(cur realm, t *testing.T) {
 32	_, ledger := newTestToken("Dummy", "DUMMY", 4, 0, cur)
 33	legit := ledger.CallerTeller()
 34
 35	uassert.True(t, IsCanonicalTeller(legit),
 36		"canonical *fnTeller from CallerTeller must pass")
 37
 38	evil := &evilWrap{Teller: legit}
 39	uassert.False(t, IsCanonicalTeller(evil),
 40		"foreign type embedding a canonical Teller must be rejected")
 41}
 42
 43func TestTeller(cur realm, t *testing.T) {
 44	var (
 45		alice = testutils.TestAddress("alice")
 46		bob   = testutils.TestAddress("bob")
 47		carl  = testutils.TestAddress("carl")
 48	)
 49
 50	token, ledger := newTestToken("Dummy", "DUMMY", 6, 0, cur)
 51
 52	checkBalances := func(aliceEB, bobEB, carlEB int64) {
 53		t.Helper()
 54		exp := ufmt.Sprintf("alice=%d bob=%d carl=%d", aliceEB, bobEB, carlEB)
 55		aliceGB := token.BalanceOf(alice)
 56		bobGB := token.BalanceOf(bob)
 57		carlGB := token.BalanceOf(carl)
 58		got := ufmt.Sprintf("alice=%d bob=%d carl=%d", aliceGB, bobGB, carlGB)
 59		uassert.Equal(t, got, exp, "invalid balances")
 60	}
 61	checkAllowances := func(abEB, acEB, baEB, bcEB, caEB, cbEB int64) {
 62		t.Helper()
 63		exp := ufmt.Sprintf("ab=%d ac=%d ba=%d bc=%d ca=%d cb=%s", abEB, acEB, baEB, bcEB, caEB, cbEB)
 64		abGB := token.Allowance(alice, bob)
 65		acGB := token.Allowance(alice, carl)
 66		baGB := token.Allowance(bob, alice)
 67		bcGB := token.Allowance(bob, carl)
 68		caGB := token.Allowance(carl, alice)
 69		cbGB := token.Allowance(carl, bob)
 70		got := ufmt.Sprintf("ab=%d ac=%d ba=%d bc=%d ca=%d cb=%s", abGB, acGB, baGB, bcGB, caGB, cbGB)
 71		uassert.Equal(t, got, exp, "invalid allowances")
 72	}
 73
 74	checkBalances(0, 0, 0)
 75	checkAllowances(0, 0, 0, 0, 0, 0)
 76
 77	urequire.NoError(t, ledger.Mint(alice, 1000))
 78	urequire.NoError(t, ledger.Mint(alice, 100))
 79	checkBalances(1100, 0, 0)
 80	checkAllowances(0, 0, 0, 0, 0, 0)
 81
 82	urequire.NoError(t, ledger.Approve(alice, bob, 99999999))
 83	checkBalances(1100, 0, 0)
 84	checkAllowances(99999999, 0, 0, 0, 0, 0)
 85
 86	urequire.NoError(t, ledger.Approve(alice, bob, 400))
 87	checkBalances(1100, 0, 0)
 88	checkAllowances(400, 0, 0, 0, 0, 0)
 89
 90	urequire.Error(t, ledger.TransferFrom(alice, bob, carl, 100000000))
 91	checkBalances(1100, 0, 0)
 92	checkAllowances(400, 0, 0, 0, 0, 0)
 93
 94	urequire.NoError(t, ledger.TransferFrom(alice, bob, carl, 100))
 95	checkBalances(1000, 0, 100)
 96	checkAllowances(300, 0, 0, 0, 0, 0)
 97
 98	urequire.Error(t, ledger.SpendAllowance(alice, bob, 2000000))
 99	checkBalances(1000, 0, 100)
100	checkAllowances(300, 0, 0, 0, 0, 0)
101
102	urequire.NoError(t, ledger.SpendAllowance(alice, bob, 100))
103	checkBalances(1000, 0, 100)
104	checkAllowances(200, 0, 0, 0, 0, 0)
105}
106
107func TestCallerTeller(cur realm, t *testing.T) {
108	alice := testutils.TestAddress("alice")
109	bob := testutils.TestAddress("bob")
110	carl := testutils.TestAddress("carl")
111
112	token, ledger := newTestToken("Dummy", "DUMMY", 6, 0, cur)
113	teller := ledger.CallerTeller()
114
115	checkBalances := func(aliceEB, bobEB, carlEB int64) {
116		t.Helper()
117		exp := ufmt.Sprintf("alice=%d bob=%d carl=%d", aliceEB, bobEB, carlEB)
118		aliceGB := token.BalanceOf(alice)
119		bobGB := token.BalanceOf(bob)
120		carlGB := token.BalanceOf(carl)
121		got := ufmt.Sprintf("alice=%d bob=%d carl=%d", aliceGB, bobGB, carlGB)
122		uassert.Equal(t, got, exp, "invalid balances")
123	}
124	checkAllowances := func(abEB, acEB, baEB, bcEB, caEB, cbEB int64) {
125		t.Helper()
126		exp := ufmt.Sprintf("ab=%d ac=%d ba=%d bc=%d ca=%d cb=%s", abEB, acEB, baEB, bcEB, caEB, cbEB)
127		abGB := token.Allowance(alice, bob)
128		acGB := token.Allowance(alice, carl)
129		baGB := token.Allowance(bob, alice)
130		bcGB := token.Allowance(bob, carl)
131		caGB := token.Allowance(carl, alice)
132		cbGB := token.Allowance(carl, bob)
133		got := ufmt.Sprintf("ab=%d ac=%d ba=%d bc=%d ca=%d cb=%s", abGB, acGB, baGB, bcGB, caGB, cbGB)
134		uassert.Equal(t, got, exp, "invalid allowances")
135	}
136
137	urequire.NoError(t, ledger.Mint(alice, 1000))
138	checkBalances(1000, 0, 0)
139	checkAllowances(0, 0, 0, 0, 0, 0)
140
141	testing.SetRealm(testing.NewUserRealm(alice))
142	func(cur realm) { urequire.NoError(t, teller.Approve(0, cur, bob, 600)) }(cross(cur))
143	checkBalances(1000, 0, 0)
144	checkAllowances(600, 0, 0, 0, 0, 0)
145
146	testing.SetRealm(testing.NewUserRealm(bob))
147	func(cur realm) { urequire.Error(t, teller.TransferFrom(0, cur, alice, carl, 700)) }(cross(cur))
148	checkBalances(1000, 0, 0)
149	checkAllowances(600, 0, 0, 0, 0, 0)
150	func(cur realm) { urequire.NoError(t, teller.TransferFrom(0, cur, alice, carl, 400)) }(cross(cur))
151	checkBalances(600, 0, 400)
152	checkAllowances(200, 0, 0, 0, 0, 0)
153}