Search Apps Documentation Source Content File Folder Download Copy Actions Download

wugnot.gno

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