Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

abt.gno

3.12 Kb · 105 lines
  1package abt
  2
  3import (
  4	"chain"
  5	"chain/runtime/unsafe"
  6	"strconv"
  7
  8	"gno.land/p/akkadia/beta/accesscontrol"
  9	"gno.land/p/nt/grc20/v0"
 10	"gno.land/r/akkadia/beta/admin"
 11)
 12
 13const FrozenChangedEvent = "FrozenChanged"
 14
 15var (
 16	// Even a Token can create mutable tellers; keep all capabilities private.
 17	token  *grc20.Token
 18	ledger *grc20.PrivateLedger
 19	frozen = true
 20)
 21
 22func init(cur realm) {
 23	token, ledger = grc20.NewToken("Akkadia Beta Token", "abt", 6, 0, cur)
 24}
 25
 26// Mint remains available while frozen. Each successful call issues new tokens.
 27func Mint(cur realm, to address, amount int64) {
 28	accesscontrol.MustGetAdminOrOperatorCaller(0, cur, admin.IsAdmin, admin.IsOperator)
 29	assertNoCoins(0, cur)
 30	if !to.IsValid() {
 31		panic("invalid abt recipient")
 32	}
 33	if amount <= 0 {
 34		panic("abt amount must be positive")
 35	}
 36	if err := ledger.Mint(to, amount); err != nil {
 37		panic("abt mint failed: " + err.Error())
 38	}
 39}
 40
 41// SetFrozen preserves existing allowances, which become usable after unfreezing.
 42func SetFrozen(cur realm, value bool) {
 43	caller := accesscontrol.MustGetAdminCaller(0, cur, admin.IsAdmin)
 44	assertNoCoins(0, cur)
 45	if frozen == value {
 46		return
 47	}
 48	previous := frozen
 49	frozen = value
 50	chain.Emit(FrozenChangedEvent,
 51		"executor", caller.String(),
 52		"previous", strconv.FormatBool(previous),
 53		"frozen", strconv.FormatBool(frozen),
 54	)
 55}
 56
 57func Transfer(cur realm, to address, amount int64) {
 58	assertCanTransfer(0, cur)
 59	if err := ledger.CallerTeller().Transfer(0, cur, to, amount); err != nil {
 60		panic("abt transfer failed: " + err.Error())
 61	}
 62}
 63
 64// Approve also rejects allowance revocation while frozen.
 65func Approve(cur realm, spender address, amount int64) {
 66	assertCanTransfer(0, cur)
 67	if err := ledger.CallerTeller().Approve(0, cur, spender, amount); err != nil {
 68		panic("abt approval failed: " + err.Error())
 69	}
 70}
 71
 72func TransferFrom(cur realm, from, to address, amount int64) {
 73	assertCanTransfer(0, cur)
 74	// The library spends allowance before rejecting self-transfers. Reject
 75	// here so even a caller that revives the abort cannot consume allowance.
 76	if from == to {
 77		panic("abt transfer failed: cannot send transfer to self")
 78	}
 79	if err := ledger.CallerTeller().TransferFrom(0, cur, from, to, amount); err != nil {
 80		panic("abt transfer failed: " + err.Error())
 81	}
 82}
 83
 84func IsFrozen() bool                         { return frozen }
 85func GetName() string                        { return token.GetName() }
 86func GetSymbol() string                      { return token.GetSymbol() }
 87func GetDecimals() int                       { return token.GetDecimals() }
 88func TotalSupply() int64                     { return token.TotalSupply() }
 89func BalanceOf(owner address) int64          { return token.BalanceOf(owner) }
 90func Allowance(owner, spender address) int64 { return token.Allowance(owner, spender) }
 91
 92func assertCanTransfer(_ int, rlm realm) {
 93	accesscontrol.AssertCurrentRealm(0, rlm)
 94	assertNoCoins(0, rlm)
 95	if frozen {
 96		panic("abt is frozen")
 97	}
 98}
 99
100func assertNoCoins(_ int, rlm realm) {
101	// OriginSend belongs to the origin call, not a subsequent realm relay.
102	if rlm.Previous().IsUser() && len(unsafe.OriginSend()) != 0 {
103		panic("attached coins not allowed")
104	}
105}