forked from gnolang/gno
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Showing
4 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) | ||
|
||
// 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() | ||
|
||
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | | ||
// ----------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!' |