Skip to content

Commit

Permalink
GSW-1968 feat: get token + teller object from grc20-reg in common (
Browse files Browse the repository at this point in the history
…#413)

* feat: get `token` and `teller` object from grc20reg
* feat: IsRegistered() to check if token is registered or not
  • Loading branch information
r3v4s authored Dec 10, 2024
1 parent 5965d6d commit ddac7e5
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
46 changes: 46 additions & 0 deletions _deploy/r/gnoswap/common/grc20reg_helper.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package common

import (
"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ufmt"
"gno.land/r/demo/grc20reg"
)

// GetToken returns a grc20.Token instance
// if token is not registered, it will panic
// token instance supports following methods:
// - GetName
// - GetSymbol
// - GetDecimals
// - TotalSupply
// - KnownAccounts
// - BalanceOf
// - Allowance
// - RenderHome
func GetToken(path string) *grc20.Token {
tokenGetter := grc20reg.MustGet(path) // if token is not registered, it will panic

return tokenGetter()
}

// GetTokenTeller returns a grc20.Teller instance
// if token is not registered, it will panic
// teller instance supports following methods:
// - Transfer
// - Approve
// - TransferFrom
func GetTokenTeller(path string) grc20.Teller {
tokenGetter := grc20reg.MustGet(path) // if token is not registered, it will panic
token := tokenGetter()
return token.CallerTeller()
}

// IsRegistered returns nil if token is registered to grc20reg
// otherwise, it returns an error
func IsRegistered(path string) error {
getter := grc20reg.Get(path)
if getter == nil {
return ufmt.Errorf("token(%s) is not registered to grc20reg", path)
}
return nil
}
134 changes: 134 additions & 0 deletions _deploy/r/gnoswap/common/grc20reg_helper_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package common

import (
"std"
"testing"

"gno.land/p/demo/testutils"
"gno.land/p/demo/uassert"
"gno.land/p/demo/ufmt"

_ "gno.land/r/demo/foo20"
)

var (
tokenPath = "gno.land/r/demo/foo20"
)

func TestGetToken(t *testing.T) {
t.Run("registered(by default)", func(t *testing.T) {
token := GetToken(tokenPath)
if token == nil {
t.Error("Expected non-nil teller for foo20")
}
})

t.Run("not registered", func(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic for non-registered token")
}
}()
GetToken("not_registered")
})
}

func TestTokenMethod(t *testing.T) {
token := GetToken(tokenPath)

t.Run("GetName()", func(t *testing.T) {
uassert.Equal(t, "Foo", token.GetName())
})

t.Run("GetSymbol()", func(t *testing.T) {
uassert.Equal(t, "FOO", token.GetSymbol())
})

t.Run("GetDecimals()", func(t *testing.T) {
uassert.Equal(t, uint(4), token.GetDecimals())
})

t.Run("TotalSupply()", func(t *testing.T) {
uassert.Equal(t, uint64(10000000000), token.TotalSupply())
})

t.Run("KnownAccounts()", func(t *testing.T) {
uassert.Equal(t, int(1), token.KnownAccounts())
})

t.Run("BalanceOf()", func(t *testing.T) {
uassert.Equal(t, uint64(10000000000), token.BalanceOf(std.Address("g1manfred47kzduec920z88wfr64ylksmdcedlf5")))
})

t.Run("Allowance()", func(t *testing.T) {
uassert.Equal(t, uint64(0), token.Allowance(std.Address("g1manfred47kzduec920z88wfr64ylksmdcedlf5"), std.Address("g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6")))
})

t.Run("RenderHome()", func(t *testing.T) {
expected := ""
expected += ufmt.Sprintf("# %s ($%s)\n\n", "Foo", "FOO")
expected += ufmt.Sprintf("* **Decimals**: %d\n", 4)
expected += ufmt.Sprintf("* **Total supply**: %d\n", 10000000000)
expected += ufmt.Sprintf("* **Known accounts**: %d\n", 1)
uassert.Equal(t, expected, token.RenderHome())
})
}

func TestGetTokenTeller(t *testing.T) {
t.Run("registered(by default)", func(t *testing.T) {
teller := GetTokenTeller(tokenPath)
if teller == nil {
t.Error("Expected non-nil teller for foo20")
}
})

t.Run("not registered", func(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic for non-registered token")
}
}()
GetTokenTeller("not_registered")
})
}

func TestTellerMethod(t *testing.T) {
teller := GetTokenTeller(tokenPath)
token := GetToken(tokenPath)
defaultHolder := std.Address("g1manfred47kzduec920z88wfr64ylksmdcedlf5")
addr01 := testutils.TestAddress("addr01")

t.Run("Transfer()", func(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(defaultHolder))

uassert.Equal(t, uint64(10000000000), token.BalanceOf(defaultHolder))

uassert.NoError(t, teller.Transfer(addr01, uint64(10000000000))) // transfer all balance to addr01

uassert.Equal(t, uint64(0), token.BalanceOf(defaultHolder))
uassert.Equal(t, uint64(10000000000), token.BalanceOf(addr01))

uassert.Error(t, teller.Transfer(addr01, uint64(10000000000))) // not enough balance
})

t.Run("Approve()", func(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(addr01))
uassert.NoError(t, teller.Approve(defaultHolder, uint64(500)))
uassert.Equal(t, uint64(500), token.Allowance(addr01, defaultHolder))
})

t.Run("TransferFrom()", func(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(defaultHolder))
uassert.NoError(t, teller.TransferFrom(addr01, defaultHolder, uint64(500)))
uassert.Equal(t, uint64(9999999500), token.BalanceOf(addr01))
uassert.Equal(t, uint64(500), token.BalanceOf(defaultHolder))
uassert.Equal(t, uint64(0), token.Allowance(addr01, defaultHolder))

uassert.Error(t, teller.TransferFrom(addr01, defaultHolder, uint64(500))) // not enough allowance
})
}

func TestIsRegistered(t *testing.T) {
uassert.NoError(t, IsRegistered(tokenPath))
uassert.Error(t, IsRegistered("not_registered"))
}

0 comments on commit ddac7e5

Please sign in to comment.