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}