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