wugnot.gno
2.55 Kb · 108 lines
1package wugnot
2
3import (
4 "chain"
5 "chain/banker"
6 "chain/runtime"
7 "strings"
8
9 "gno.land/p/demo/tokens/grc20"
10 "gno.land/p/nt/ufmt/v0"
11 "gno.land/r/demo/defi/grc20reg"
12)
13
14var Token, adm = grc20.NewToken("wrapped GNOT", "wugnot", 0)
15
16const (
17 ugnotMinDeposit int64 = 1000
18 wugnotMinDeposit int64 = 1
19)
20
21func init() {
22 grc20reg.Register(cross, Token, "")
23}
24
25func Deposit(cur realm) {
26 // Prevent cross-realm MITM: without this, an intermediary could
27 // deposit on behalf of the caller and mint wugnot to itself
28 // instead of the actual sender.
29 runtime.AssertOriginCall()
30 caller := runtime.PreviousRealm().Address()
31 sent := banker.OriginSend()
32 amount := sent.AmountOf("ugnot")
33
34 require(int64(amount) >= ugnotMinDeposit, ufmt.Sprintf("Deposit below minimum: %d/%d ugnot.", amount, ugnotMinDeposit))
35
36 checkErr(adm.Mint(caller, int64(amount)))
37}
38
39func Withdraw(cur realm, amount int64) {
40 runtime.AssertOriginCall()
41 require(amount >= wugnotMinDeposit, ufmt.Sprintf("Deposit below minimum: %d/%d wugnot.", amount, wugnotMinDeposit))
42
43 caller := runtime.PreviousRealm().Address()
44 pkgaddr := runtime.CurrentRealm().Address()
45 callerBal := Token.BalanceOf(caller)
46 require(amount <= callerBal, ufmt.Sprintf("Insufficient balance: %d available, %d needed.", callerBal, amount))
47
48 // send swapped ugnots to qcaller
49 stdBanker := banker.NewBanker(banker.BankerTypeRealmSend)
50 send := chain.Coins{{"ugnot", int64(amount)}}
51 stdBanker.SendCoins(pkgaddr, caller, send)
52 checkErr(adm.Burn(caller, amount))
53}
54
55func Render(path string) string {
56 parts := strings.Split(path, "/")
57 c := len(parts)
58
59 switch {
60 case path == "":
61 return Token.RenderHome()
62 case c == 2 && parts[0] == "balance":
63 owner := address(parts[1])
64 balance := Token.BalanceOf(owner)
65 return ufmt.Sprintf("%d", balance)
66 default:
67 return "404"
68 }
69}
70
71func TotalSupply() int64 {
72 return Token.TotalSupply()
73}
74
75func BalanceOf(owner address) int64 {
76 return Token.BalanceOf(owner)
77}
78
79func Allowance(owner, spender address) int64 {
80 return Token.Allowance(owner, spender)
81}
82
83func Transfer(cur realm, to address, amount int64) {
84 userTeller := Token.CallerTeller()
85 checkErr(userTeller.Transfer(to, amount))
86}
87
88func Approve(cur realm, spender address, amount int64) {
89 userTeller := Token.CallerTeller()
90 checkErr(userTeller.Approve(spender, amount))
91}
92
93func TransferFrom(cur realm, from, to address, amount int64) {
94 userTeller := Token.CallerTeller()
95 checkErr(userTeller.TransferFrom(from, to, amount))
96}
97
98func require(condition bool, msg string) {
99 if !condition {
100 panic(msg)
101 }
102}
103
104func checkErr(err error) {
105 if err != nil {
106 panic(err)
107 }
108}