Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(examples): wugnot (grc20’s wrapped ugnot) #1356

Merged
merged 5 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions examples/gno.land/r/demo/wugnot/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module gno.land/r/demo/wugnot

require (
gno.land/p/demo/grc/grc20 v0.0.0-latest
gno.land/p/demo/ufmt v0.0.0-latest
)
126 changes: 126 additions & 0 deletions examples/gno.land/r/demo/wugnot/wugnot.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package wugnot

import (
"std"
"strings"

"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ufmt"
)

var (
// wugnot is the admin token, able to mint and burn.
wugnot *grc20.AdminToken = grc20.NewAdminToken("wrapped GNOT", "wugnot", 0)
// WUGNOT is the banker usable by users directly.
WUGNOT = wugnot.GRC20()
)

const (
ugnotMinDeposit uint64 = 1000
wugnotMinDeposit uint64 = 1
)
Comment on lines +18 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a min / max for wrapping ugnot?


// wrapper.
//

func Deposit() {
caller := std.PrevRealm().Addr()
sent := std.GetOrigSend()
amount := sent.AmountOf("ugnot")

if uint64(amount) < ugnotMinDeposit {
panic(ufmt.Sprintf("Deposit below minimum: %d/%d ugnot.", amount, ugnotMinDeposit))
}
wugnot.Mint(caller, uint64(amount))
}

func Withdraw(amount uint64) {
if amount < wugnotMinDeposit {
panic(ufmt.Sprintf("Deposit below minimum: %d/%d wugnot.", amount, wugnotMinDeposit))
}

caller := std.PrevRealm().Addr()
pkgaddr := std.GetOrigPkgAddr()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not CurrentRealm().Addr()?


callerBal, _ := wugnot.BalanceOf(caller)
if callerBal < amount {
panic(ufmt.Sprintf("Insufficient balance: %d available, %d needed.", callerBal, amount))
}

// send swapped ugnots to caller
banker := std.GetBanker(std.BankerTypeRealmSend)
send := std.Coins{{"ugnot", int64(amount)}}
banker.SendCoins(pkgaddr, caller, send)
wugnot.Burn(caller, amount)
}

// render.
//

func Render(path string) string {
parts := strings.Split(path, "/")
c := len(parts)

switch {
case path == "":
return wugnot.RenderHome()
case c == 2 && parts[0] == "balance":
owner := std.Address(parts[1])
balance, _ := wugnot.BalanceOf(owner)
return ufmt.Sprintf("%d\n", balance)
default:
return "404\n"
}
}

// XXX: if we could call WUGNOT.XXX instead of XXX from gnokey, then, all the following lines would not be needed.

// direct getters.
// XXX: remove them in favor of q_call wugnot.XXX

func TotalSupply() uint64 {
return wugnot.TotalSupply()
}

func BalanceOf(owner std.Address) uint64 {
balance, err := wugnot.BalanceOf(owner)
if err != nil {
panic(err)
}
return balance
}

func Allowance(owner, spender std.Address) uint64 {
allowance, err := wugnot.Allowance(owner, spender)
if err != nil {
panic(err)
}
return allowance
}

// setters.
//

func Transfer(to std.Address, amount uint64) {
caller := std.PrevRealm().Addr()
err := wugnot.Transfer(caller, to, amount)
if err != nil {
panic(err)
}
}

func Approve(spender std.Address, amount uint64) {
caller := std.PrevRealm().Addr()
err := wugnot.Approve(caller, spender, amount)
if err != nil {
panic(err)
}
}

func TransferFrom(from, to std.Address, amount uint64) {
caller := std.PrevRealm().Addr()
err := wugnot.TransferFrom(caller, from, to, amount)
if err != nil {
panic(err)
}
}
75 changes: 75 additions & 0 deletions examples/gno.land/r/demo/wugnot/z0_filetest.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// PKGPATH: gno.land/r/demo/wugnot_test
package wugnot_test

import (
"fmt"
"std"

"gno.land/p/demo/testutils"
"gno.land/r/demo/wugnot"
)

var (
addr1 = testutils.TestAddress("test1")
addrc = std.DerivePkgAddr("gno.land/r/demo/wugnot")
addrt = std.DerivePkgAddr("gno.land/r/demo/wugnot_test")
)

func main() {
std.TestSetOrigPkgAddr(addrc)
std.TestIssueCoins(addrc, std.Coins{{"ugnot", 100000001}}) // TODO: remove this

// issue ugnots
std.TestIssueCoins(addr1, std.Coins{{"ugnot", 100000001}})

// print initial state
printBalances()
// println(wugnot.Render("queues"))
// println("A -", wugnot.Render(""))

std.TestSetOrigCaller(addr1)
std.TestSetOrigSend(std.Coins{{"ugnot", 123_400}}, nil)
wugnot.Deposit()
printBalances()
wugnot.Withdraw(4242)
printBalances()
}

func printBalances() {
printSingleBalance := func(name string, addr std.Address) {
wugnotBal := wugnot.BalanceOf(addr)
std.TestSetOrigCaller(addr)
abanker := std.GetBanker(std.BankerTypeOrigSend)
acoins := abanker.GetCoins(addr).AmountOf("ugnot")
bbanker := std.GetBanker(std.BankerTypeRealmIssue)
bcoins := bbanker.GetCoins(addr).AmountOf("ugnot")
cbanker := std.GetBanker(std.BankerTypeRealmSend)
ccoins := cbanker.GetCoins(addr).AmountOf("ugnot")
dbanker := std.GetBanker(std.BankerTypeReadonly)
dcoins := dbanker.GetCoins(addr).AmountOf("ugnot")
fmt.Printf("| %-13s | addr=%s | wugnot=%-5d | ugnot=%-9d %-9d %-9d %-9d |\n",
name, addr, wugnotBal, acoins, bcoins, ccoins, dcoins)
}
println("-----------")
printSingleBalance("wugnot_test", addrt)
printSingleBalance("wugnot", addrc)
printSingleBalance("addr1", addr1)
println("-----------")
}

// Output:
// -----------
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=0 | ugnot=200000000 200000000 200000000 200000000 |
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
// -----------
// -----------
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=123400 | ugnot=200000000 200000000 200000000 200000000 |
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
// -----------
// -----------
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=119158 | ugnot=200004242 200004242 200004242 200004242 |
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=99995759 99995759 99995759 99995759 |
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
// -----------
43 changes: 43 additions & 0 deletions gno.land/cmd/gnoland/testdata/wugnot.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
gnoland start

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout '# wrapped GNOT \(\$wugnot\)'
stdout 'Decimals..: 0'
stdout 'Total supply..: 0'
stdout 'Known accounts..: 0'
stdout 'OK!'

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout 'OK!'

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout 'Total supply..: 12345678'
stdout 'Known accounts..: 1'
stdout 'OK!'

# XXX: use test2 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069)
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout 'OK!'

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout 'Total supply..: 24691356'
stdout 'Known accounts..: 1' # should be 2 once we can use test2
stdout 'OK!'

# XXX: replace hardcoded address with test3
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Transfer -gas-fee 1000000ugnot -gas-wanted 2000000 -args 'g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq' -args '10000000' -broadcast -chainid=tendermint_test test1
stdout 'OK!'

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout 'Total supply..: 24691356'
stdout 'Known accounts..: 2' # should be 3 once we can use test2
stdout 'OK!'

# XXX: use test3 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069)
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Withdraw -args 10000000 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout 'OK!'

gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
stdout 'Total supply..: 14691356'
stdout 'Known accounts..: 2' # should be 3 once we can use test2
stdout 'OK!'
Loading