types.gno
4.19 Kb ยท 126 lines
1package grc20
2
3import (
4 "errors"
5 "std"
6
7 "gno.land/p/nt/avl"
8)
9
10// Teller interface defines the methods that a GRC20 token must implement. It
11// extends the TokenMetadata interface to include methods for managing token
12// transfers, allowances, and querying balances.
13//
14// The Teller interface is designed to ensure that any token adhering to this
15// standard provides a consistent API for interacting with fungible tokens.
16type Teller interface {
17 // Returns the name of the token.
18 GetName() string
19
20 // Returns the symbol of the token, usually a shorter version of the
21 // name.
22 GetSymbol() string
23
24 // Returns the decimals places of the token.
25 GetDecimals() int
26
27 // Returns the amount of tokens in existence.
28 TotalSupply() int64
29
30 // Returns the amount of tokens owned by `account`.
31 BalanceOf(account std.Address) int64
32
33 // Moves `amount` tokens from the caller's account to `to`.
34 //
35 // Returns an error if the operation failed.
36 Transfer(to std.Address, amount int64) error
37
38 // Returns the remaining number of tokens that `spender` will be
39 // allowed to spend on behalf of `owner` through {transferFrom}. This is
40 // zero by default.
41 //
42 // This value changes when {approve} or {transferFrom} are called.
43 Allowance(owner, spender std.Address) int64
44
45 // Sets `amount` as the allowance of `spender` over the caller's tokens.
46 //
47 // Returns an error if the operation failed.
48 //
49 // IMPORTANT: Beware that changing an allowance with this method brings
50 // the risk that someone may use both the old and the new allowance by
51 // unfortunate transaction ordering. One possible solution to mitigate
52 // this race condition is to first reduce the spender's allowance to 0
53 // and set the desired value afterwards:
54 // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
55 Approve(spender std.Address, amount int64) error
56
57 // Moves `amount` tokens from `from` to `to` using the
58 // allowance mechanism. `amount` is then deducted from the caller's
59 // allowance.
60 //
61 // Returns an error if the operation failed.
62 TransferFrom(from, to std.Address, amount int64) error
63}
64
65// Token represents a fungible token with a name, symbol, and a certain number
66// of decimal places. It maintains a ledger for tracking balances and allowances
67// of addresses.
68//
69// The Token struct provides methods for retrieving token metadata, such as the
70// name, symbol, and decimals, as well as methods for interacting with the
71// ledger, including checking balances and allowances.
72type Token struct {
73 // Name of the token (e.g., "Dummy Token").
74 name string
75 // Symbol of the token (e.g., "DUMMY").
76 symbol string
77 // Number of decimal places used for the token's precision.
78 decimals int
79 // Original realm of the token (e.g., "gno.land/r/demo/foo20").
80 origRealm string
81 // Pointer to the PrivateLedger that manages balances and allowances.
82 ledger *PrivateLedger
83}
84
85// PrivateLedger is a struct that holds the balances and allowances for the
86// token. It provides administrative functions for minting, burning,
87// transferring tokens, and managing allowances.
88//
89// The PrivateLedger is not safe to expose publicly, as it contains sensitive
90// information regarding token balances and allowances, and allows direct,
91// unrestricted access to all administrative functions.
92type PrivateLedger struct {
93 // Total supply of the token managed by this ledger.
94 totalSupply int64
95 // std.Address -> int64
96 balances avl.Tree
97 // owner.(std.Address)+":"+spender.(std.Address)) -> int64
98 allowances avl.Tree
99 // Pointer to the associated Token struct
100 token *Token
101}
102
103var (
104 ErrInsufficientBalance = errors.New("insufficient balance")
105 ErrInsufficientAllowance = errors.New("insufficient allowance")
106 ErrInvalidAddress = errors.New("invalid address")
107 ErrCannotTransferToSelf = errors.New("cannot send transfer to self")
108 ErrReadonly = errors.New("banker is readonly")
109 ErrRestrictedTokenOwner = errors.New("restricted to bank owner")
110 ErrMintOverflow = errors.New("mint overflow")
111 ErrInvalidAmount = errors.New("invalid amount")
112)
113
114const (
115 MintEvent = "Mint"
116 BurnEvent = "Burn"
117 TransferEvent = "Transfer"
118 ApprovalEvent = "Approval"
119)
120
121type fnTeller struct {
122 accountFn func() std.Address
123 *Token
124}
125
126var _ Teller = (*fnTeller)(nil)