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