1package grc20factory23import (4 "testing"56 "gno.land/p/nt/testutils/v0"7 "gno.land/p/nt/uassert/v0"8 "gno.land/p/nt/ufmt/v0"9)1011func TestReadOnlyPublicMethods(cur realm, t *testing.T) {12 admin := testutils.TestAddress("admin")13 bob := testutils.TestAddress("bob")14 carl := testutils.TestAddress("carl")1516 type test struct {17 name string18 balance int6419 fn func() int6420 }2122 checkBalances := func(step string, totSup, balAdm, balBob, allowAdmBob, balCarl int64) {23 tests := []test{24 {"TotalSupply", totSup, func() int64 { return TotalSupply("FOO") }},25 {"BalanceOf(admin)", balAdm, func() int64 { return BalanceOf("FOO", admin) }},26 {"BalanceOf(bob)", balBob, func() int64 { return BalanceOf("FOO", bob) }},27 {"Allowance(admin, bob)", allowAdmBob, func() int64 { return Allowance("FOO", admin, bob) }},28 {"BalanceOf(carl)", balCarl, func() int64 { return BalanceOf("FOO", carl) }},29 }30 for _, tc := range tests {31 reason := ufmt.Sprintf("%s.%s - %s", step, tc.name, "balances do not match")32 uassert.Equal(t, tc.balance, tc.fn(), reason)33 }34 }3536 // admin creates FOO and BAR.37 testing.SetOriginCaller(admin)38 NewWithAdmin(cross(cur), "Foo", "FOO", 3, 1_111_111_000, 5_555, admin)39 NewWithAdmin(cross(cur), "Bar", "BAR", 3, 2_222_000, 6_666, admin)40 uassert.Equal(t, Bank("FOO").ID(), "gno.land/r/demo/defi/grc20factory.FOO.0000001")41 uassert.Equal(t, Bank("BAR").ID(), "gno.land/r/demo/defi/grc20factory.BAR.0000002")42 checkBalances("step1", 1_111_111_000, 1_111_111_000, 0, 0, 0)4344 // admin mints to bob.45 mustGetInstance("FOO").ledger.Mint(bob, 333_333_000)46 checkBalances("step2", 1_444_444_000, 1_111_111_000, 333_333_000, 0, 0)4748 // carl uses the faucet.49 testing.SetOriginCaller(carl)50 Faucet(cross(cur), "FOO")51 checkBalances("step3", 1_444_449_555, 1_111_111_000, 333_333_000, 0, 5_555)5253 // admin gives to bob some allowance.54 testing.SetOriginCaller(admin)55 Approve(cross(cur), "FOO", bob, 1_000_000)56 checkBalances("step4", 1_444_449_555, 1_111_111_000, 333_333_000, 1_000_000, 5_555)5758 // bob uses a part of the allowance.59 testing.SetOriginCaller(bob)60 TransferFrom(cross(cur), "FOO", admin, carl, 400_000)61 checkBalances("step5", 1_444_449_555, 1_110_711_000, 333_333_000, 600_000, 405_555)6263 // bob uses a part of the allowance.64 testing.SetOriginCaller(bob)65 TransferFrom(cross(cur), "FOO", admin, carl, 600_000)66 checkBalances("step6", 1_444_449_555, 1_110_111_000, 333_333_000, 0, 1_005_555)67}68Allowance(symbol string, owner string, spender string) int64
Approve(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, spender string, amount int64)
BalanceOf(symbol string, owner string) int64
Bank(symbol string) *gno.land/p/nt/grc20/v0.Token
Burn(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, from string, amount int64)
DropInstanceOwnership(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string)
Faucet(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string)
HasAddr(symbol string, owner string) bool
ListTokens(pageNumber int, pageSize int) []*gno.land/p/nt/grc20/v0.Token
Mint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, to string, amount int64)
New(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, symbol string, decimals int, initialMint int64, faucet int64)
NewWithAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, symbol string, decimals int, initialMint int64, faucet int64, admin string)
Render(path string) string
TotalSupply(symbol string) int64
Transfer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, to string, amount int64)
TransferFrom(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, from string, to string, amount int64)
TransferInstanceOwnership(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, symbol string, newOwner string)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.