Skip to content

Commit 63e3b52

Browse files
moulgfanton
authored andcommitted
feat(examples): wugnot (grc20’s wrapped ugnot) (gnolang#1356)
This PR presents a GNOT wrapper that conforms to the GRC20 interface. Optimally, the txtar file should be relocated to the wugnot directory, pending resolution of [issue gnolang#1269](gnolang#1269 (comment)). Enabling the use of `gnokey maketx call -func WUGNOT.Transfer` over `-func Transfer` would streamline the wrapper, reducing it to just the initial 55 lines. <!-- please provide a detailed description of the changes made in this pull request. --> <details><summary>Contributors' checklist...</summary> - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [x] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md). </details> --------- Signed-off-by: moul <94029+moul@users.noreply.github.com>
1 parent 1705647 commit 63e3b52

File tree

4 files changed

+250
-0
lines changed

4 files changed

+250
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module gno.land/r/demo/wugnot
2+
3+
require (
4+
gno.land/p/demo/grc/grc20 v0.0.0-latest
5+
gno.land/p/demo/ufmt v0.0.0-latest
6+
)
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package wugnot
2+
3+
import (
4+
"std"
5+
"strings"
6+
7+
"gno.land/p/demo/grc/grc20"
8+
"gno.land/p/demo/ufmt"
9+
)
10+
11+
var (
12+
// wugnot is the admin token, able to mint and burn.
13+
wugnot *grc20.AdminToken = grc20.NewAdminToken("wrapped GNOT", "wugnot", 0)
14+
// WUGNOT is the banker usable by users directly.
15+
WUGNOT = wugnot.GRC20()
16+
)
17+
18+
const (
19+
ugnotMinDeposit uint64 = 1000
20+
wugnotMinDeposit uint64 = 1
21+
)
22+
23+
// wrapper.
24+
//
25+
26+
func Deposit() {
27+
caller := std.PrevRealm().Addr()
28+
sent := std.GetOrigSend()
29+
amount := sent.AmountOf("ugnot")
30+
31+
if uint64(amount) < ugnotMinDeposit {
32+
panic(ufmt.Sprintf("Deposit below minimum: %d/%d ugnot.", amount, ugnotMinDeposit))
33+
}
34+
wugnot.Mint(caller, uint64(amount))
35+
}
36+
37+
func Withdraw(amount uint64) {
38+
if amount < wugnotMinDeposit {
39+
panic(ufmt.Sprintf("Deposit below minimum: %d/%d wugnot.", amount, wugnotMinDeposit))
40+
}
41+
42+
caller := std.PrevRealm().Addr()
43+
pkgaddr := std.GetOrigPkgAddr()
44+
45+
callerBal, _ := wugnot.BalanceOf(caller)
46+
if callerBal < amount {
47+
panic(ufmt.Sprintf("Insufficient balance: %d available, %d needed.", callerBal, amount))
48+
}
49+
50+
// send swapped ugnots to caller
51+
banker := std.GetBanker(std.BankerTypeRealmSend)
52+
send := std.Coins{{"ugnot", int64(amount)}}
53+
banker.SendCoins(pkgaddr, caller, send)
54+
wugnot.Burn(caller, amount)
55+
}
56+
57+
// render.
58+
//
59+
60+
func Render(path string) string {
61+
parts := strings.Split(path, "/")
62+
c := len(parts)
63+
64+
switch {
65+
case path == "":
66+
return wugnot.RenderHome()
67+
case c == 2 && parts[0] == "balance":
68+
owner := std.Address(parts[1])
69+
balance, _ := wugnot.BalanceOf(owner)
70+
return ufmt.Sprintf("%d\n", balance)
71+
default:
72+
return "404\n"
73+
}
74+
}
75+
76+
// XXX: if we could call WUGNOT.XXX instead of XXX from gnokey, then, all the following lines would not be needed.
77+
78+
// direct getters.
79+
// XXX: remove them in favor of q_call wugnot.XXX
80+
81+
func TotalSupply() uint64 {
82+
return wugnot.TotalSupply()
83+
}
84+
85+
func BalanceOf(owner std.Address) uint64 {
86+
balance, err := wugnot.BalanceOf(owner)
87+
if err != nil {
88+
panic(err)
89+
}
90+
return balance
91+
}
92+
93+
func Allowance(owner, spender std.Address) uint64 {
94+
allowance, err := wugnot.Allowance(owner, spender)
95+
if err != nil {
96+
panic(err)
97+
}
98+
return allowance
99+
}
100+
101+
// setters.
102+
//
103+
104+
func Transfer(to std.Address, amount uint64) {
105+
caller := std.PrevRealm().Addr()
106+
err := wugnot.Transfer(caller, to, amount)
107+
if err != nil {
108+
panic(err)
109+
}
110+
}
111+
112+
func Approve(spender std.Address, amount uint64) {
113+
caller := std.PrevRealm().Addr()
114+
err := wugnot.Approve(caller, spender, amount)
115+
if err != nil {
116+
panic(err)
117+
}
118+
}
119+
120+
func TransferFrom(from, to std.Address, amount uint64) {
121+
caller := std.PrevRealm().Addr()
122+
err := wugnot.TransferFrom(caller, from, to, amount)
123+
if err != nil {
124+
panic(err)
125+
}
126+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// PKGPATH: gno.land/r/demo/wugnot_test
2+
package wugnot_test
3+
4+
import (
5+
"fmt"
6+
"std"
7+
8+
"gno.land/p/demo/testutils"
9+
"gno.land/r/demo/wugnot"
10+
)
11+
12+
var (
13+
addr1 = testutils.TestAddress("test1")
14+
addrc = std.DerivePkgAddr("gno.land/r/demo/wugnot")
15+
addrt = std.DerivePkgAddr("gno.land/r/demo/wugnot_test")
16+
)
17+
18+
func main() {
19+
std.TestSetOrigPkgAddr(addrc)
20+
std.TestIssueCoins(addrc, std.Coins{{"ugnot", 100000001}}) // TODO: remove this
21+
22+
// issue ugnots
23+
std.TestIssueCoins(addr1, std.Coins{{"ugnot", 100000001}})
24+
25+
// print initial state
26+
printBalances()
27+
// println(wugnot.Render("queues"))
28+
// println("A -", wugnot.Render(""))
29+
30+
std.TestSetOrigCaller(addr1)
31+
std.TestSetOrigSend(std.Coins{{"ugnot", 123_400}}, nil)
32+
wugnot.Deposit()
33+
printBalances()
34+
wugnot.Withdraw(4242)
35+
printBalances()
36+
}
37+
38+
func printBalances() {
39+
printSingleBalance := func(name string, addr std.Address) {
40+
wugnotBal := wugnot.BalanceOf(addr)
41+
std.TestSetOrigCaller(addr)
42+
abanker := std.GetBanker(std.BankerTypeOrigSend)
43+
acoins := abanker.GetCoins(addr).AmountOf("ugnot")
44+
bbanker := std.GetBanker(std.BankerTypeRealmIssue)
45+
bcoins := bbanker.GetCoins(addr).AmountOf("ugnot")
46+
cbanker := std.GetBanker(std.BankerTypeRealmSend)
47+
ccoins := cbanker.GetCoins(addr).AmountOf("ugnot")
48+
dbanker := std.GetBanker(std.BankerTypeReadonly)
49+
dcoins := dbanker.GetCoins(addr).AmountOf("ugnot")
50+
fmt.Printf("| %-13s | addr=%s | wugnot=%-5d | ugnot=%-9d %-9d %-9d %-9d |\n",
51+
name, addr, wugnotBal, acoins, bcoins, ccoins, dcoins)
52+
}
53+
println("-----------")
54+
printSingleBalance("wugnot_test", addrt)
55+
printSingleBalance("wugnot", addrc)
56+
printSingleBalance("addr1", addr1)
57+
println("-----------")
58+
}
59+
60+
// Output:
61+
// -----------
62+
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=0 | ugnot=200000000 200000000 200000000 200000000 |
63+
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
64+
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
65+
// -----------
66+
// -----------
67+
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=123400 | ugnot=200000000 200000000 200000000 200000000 |
68+
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
69+
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
70+
// -----------
71+
// -----------
72+
// | wugnot_test | addr=g19rmydykafrqyyegc8uuaxxpzqwzcnxraj2dev9 | wugnot=119158 | ugnot=200004242 200004242 200004242 200004242 |
73+
// | wugnot | addr=g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6 | wugnot=0 | ugnot=99995759 99995759 99995759 99995759 |
74+
// | addr1 | addr=g1w3jhxap3ta047h6lta047h6lta047h6l4mfnm7 | wugnot=0 | ugnot=100000001 100000001 100000001 100000001 |
75+
// -----------
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
gnoland start
2+
3+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
4+
stdout '# wrapped GNOT \(\$wugnot\)'
5+
stdout 'Decimals..: 0'
6+
stdout 'Total supply..: 0'
7+
stdout 'Known accounts..: 0'
8+
stdout 'OK!'
9+
10+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
11+
stdout 'OK!'
12+
13+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
14+
stdout 'Total supply..: 12345678'
15+
stdout 'Known accounts..: 1'
16+
stdout 'OK!'
17+
18+
# XXX: use test2 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069)
19+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
20+
stdout 'OK!'
21+
22+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
23+
stdout 'Total supply..: 24691356'
24+
stdout 'Known accounts..: 1' # should be 2 once we can use test2
25+
stdout 'OK!'
26+
27+
# XXX: replace hardcoded address with test3
28+
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
29+
stdout 'OK!'
30+
31+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
32+
stdout 'Total supply..: 24691356'
33+
stdout 'Known accounts..: 2' # should be 3 once we can use test2
34+
stdout 'OK!'
35+
36+
# XXX: use test3 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069)
37+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Withdraw -args 10000000 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
38+
stdout 'OK!'
39+
40+
gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1
41+
stdout 'Total supply..: 14691356'
42+
stdout 'Known accounts..: 2' # should be 3 once we can use test2
43+
stdout 'OK!'

0 commit comments

Comments
 (0)