instance.gno
5.72 Kb · 175 lines
1package common
2
3import (
4 "errors"
5
6 "gno.land/p/nt/grc20/v0"
7 "gno.land/p/nt/ufmt/v0"
8 "gno.land/r/gnoswap/common"
9 "gno.land/r/nt/grc20reg/v0"
10)
11
12// commonV1 executes token operations against gno.land/r/nt/grc20reg/v0.
13type commonV1 struct{}
14
15// NewCommonV1 returns the common implementation backed by the registered GRC20
16// token registry.
17//
18// Returns:
19// - implementation: new ICommon implementation instance
20func NewCommonV1() common.ICommon {
21 return &commonV1{}
22}
23
24// IsRegistered verifies that tokenKey is valid and resolves to a registered
25// GRC20 token.
26//
27// Parameters:
28// - tokenKey: registry key identifying the token, including its realm path and symbol
29//
30// Returns:
31// - error: nil when the key is valid and registered; an error when validation
32// fails or no token is registered under the key
33func (c *commonV1) IsRegistered(tokenKey string) error {
34 if err := validateTokenKey(tokenKey); err != nil {
35 return err
36 }
37
38 if grc20reg.Get(tokenKey) == nil {
39 return ufmt.Errorf("token(%s) is not registered", tokenKey)
40 }
41
42 return nil
43}
44
45// ValidateRegistered verifies every supplied token key before a multi-token
46// operation proceeds.
47//
48// Parameters:
49// - tokenKeys: token registry keys that must all be valid and registered
50//
51// Returns:
52// - error: nil when every key is registered; an error identifying the first
53// key that is invalid or unregistered otherwise
54func (c *commonV1) ValidateRegistered(tokenKeys ...string) error {
55 for _, tokenKey := range tokenKeys {
56 if err := c.IsRegistered(tokenKey); err != nil {
57 return errors.New(newErrorWithDetail(
58 errNotRegistered,
59 ufmt.Sprintf("token(%s)", tokenKey),
60 ))
61 }
62 }
63
64 return nil
65}
66
67// TotalSupply returns the total supply recorded for a registered token.
68//
69// Parameters:
70// - tokenKey: registry key of the token to inspect
71//
72// Returns:
73// - supply: token total supply; panics when tokenKey is invalid or unregistered
74func (c *commonV1) TotalSupply(tokenKey string) int64 {
75 return c.mustGetToken(tokenKey).TotalSupply()
76}
77
78// BalanceOf returns the token balance held by addr.
79//
80// Parameters:
81// - tokenKey: registry key of the token to inspect
82// - addr: address whose token balance is queried
83//
84// Returns:
85// - balance: amount of tokenKey held by addr; panics when tokenKey is invalid
86// or unregistered
87func (c *commonV1) BalanceOf(tokenKey string, addr address) int64 {
88 return c.mustGetToken(tokenKey).BalanceOf(addr)
89}
90
91// Allowance returns the amount that spender may transfer from owner.
92//
93// Parameters:
94// - tokenKey: registry key of the token to inspect
95// - owner: address that granted the allowance
96// - spender: address authorized to spend from owner
97//
98// Returns:
99// - allowance: remaining token amount spender may transfer; panics when
100// tokenKey is invalid or unregistered
101func (c *commonV1) Allowance(tokenKey string, owner, spender address) int64 {
102 return c.mustGetToken(tokenKey).Allowance(owner, spender)
103}
104
105// Transfer moves amount of a registered token to to using a teller bound to rlm.
106//
107// Parameters:
108// - _: realm-call discriminator; callers pass 0
109// - rlm: propagated realm context used to bind the token teller and forwarded
110// for the token actor's realm validation
111// - tokenKey: registry key of the token to transfer
112// - to: recipient address
113// - amount: number of token units to transfer
114//
115// Returns:
116// - error: nil after a successful transfer; the token teller's validation or
117// transfer error otherwise
118func (c *commonV1) Transfer(_ int, rlm realm, tokenKey string, to address, amount int64) error {
119 return c.getTokenTeller(0, rlm, tokenKey).Transfer(0, rlm, to, amount)
120}
121
122// TransferFrom moves amount of a registered token from from to to using the
123// allowance/authorization associated with the calling realm.
124//
125// Parameters:
126// - _: realm-call discriminator; callers pass 0
127// - rlm: propagated realm context used to bind the token teller and forwarded
128// for the token actor's realm validation
129// - tokenKey: registry key of the token to transfer
130// - from: address whose token balance is debited
131// - to: recipient address
132// - amount: number of token units to transfer
133//
134// Returns:
135// - error: nil after a successful transfer; the token teller's validation,
136// allowance, or balance error otherwise
137func (c *commonV1) TransferFrom(_ int, rlm realm, tokenKey string, from, to address, amount int64) error {
138 return c.getTokenTeller(0, rlm, tokenKey).TransferFrom(0, rlm, from, to, amount)
139}
140
141// Approve sets amount as the allowance that spender may use from the caller.
142//
143// Parameters:
144// - _: realm-call discriminator; callers pass 0
145// - rlm: propagated realm context used to bind the token teller and forwarded
146// for the token actor's realm validation
147// - tokenKey: registry key of the token to approve
148// - spender: address authorized to spend
149// - amount: maximum number of token units spender may transfer
150//
151// Returns:
152// - error: nil after the allowance is stored; the token teller's validation
153// error otherwise
154func (c *commonV1) Approve(_ int, rlm realm, tokenKey string, spender address, amount int64) error {
155 return c.getTokenTeller(0, rlm, tokenKey).Approve(0, rlm, spender, amount)
156}
157
158func (c *commonV1) mustGetToken(tokenKey string) *grc20.Token {
159 if err := validateTokenKey(tokenKey); err != nil {
160 panic(err.Error())
161 }
162
163 token := grc20reg.Get(tokenKey)
164 if token == nil {
165 panic(newErrorWithDetail(errNotRegistered, ufmt.Sprintf("unknown token(%s)", tokenKey)))
166 }
167
168 return token
169}
170
171// getTokenTeller binds the token actor to rlm. This is a same-realm borrow,
172// so rlm stays current and the actor is the calling realm.
173func (c *commonV1) getTokenTeller(_ int, rlm realm, tokenKey string) grc20.Teller {
174 return c.mustGetToken(tokenKey).RealmTeller(0, rlm)
175}