external_token_list.gno
3.33 Kb ยท 129 lines
1package v1
2
3import (
4 "chain"
5 "chain/runtime"
6
7 "gno.land/p/nt/ufmt"
8 "gno.land/r/gnoswap/access"
9 "gno.land/r/gnoswap/halt"
10)
11
12var defaultAllowed = []string{GNOT_DENOM, GNS_PATH}
13
14// AddToken adds a new token path to the list of allowed tokens
15// Only the admin can add a new token.
16//
17// Parameters:
18// - tokenPath (string): The path of the token to add
19//
20// Panics:
21// - If the caller is not the admin
22func (s *stakerV1) AddToken(tokenPath string) {
23 halt.AssertIsNotHaltedStaker()
24
25 previousRealm := runtime.PreviousRealm()
26 caller := previousRealm.Address()
27 access.AssertIsAdminOrGovernance(caller)
28
29 if err := modifyTokenList(s, tokenPath, addTokenValidator, addTokenExecutor); err != nil {
30 panic(err.Error())
31 }
32
33 chain.Emit(
34 "AddToken",
35 "prevAddr", caller.String(),
36 "prevRealm", previousRealm.PkgPath(),
37 "tokenPath", tokenPath,
38 )
39}
40
41// RemoveToken removes a token path from the list of allowed tokens.
42// Only the admin can remove a token.
43//
44// Default tokens cannot be removed.
45//
46// Parameters:
47// - tokenPath (string): The path of the token to remove
48//
49// Panics:
50// - If the caller is not the admin
51func (s *stakerV1) RemoveToken(tokenPath string) {
52 halt.AssertIsNotHaltedStaker()
53
54 previousRealm := runtime.PreviousRealm()
55 caller := previousRealm.Address()
56 access.AssertIsAdminOrGovernance(caller)
57
58 if err := modifyTokenList(s, tokenPath, removeTokenValidator, removeTokenExecutor); err != nil {
59 panic(err.Error())
60 }
61
62 chain.Emit(
63 "RemoveToken",
64 "prevAddr", caller.String(),
65 "prevRealm", previousRealm.PkgPath(),
66 "tokenPath", tokenPath,
67 )
68}
69
70// TokenValidator is a function type that validates a token
71type TokenValidator func(tokenPath string) error
72
73// TokenExecutor is a token manipulation function type
74type TokenExecutor func(tokenPath string, tokens []string) []string
75
76// modifyTokenList handles common token modification logics, such as admin check, validation, and execution.
77func modifyTokenList(s *stakerV1, tokenPath string, validator TokenValidator, executor TokenExecutor) error {
78 // validate token operation if validator is provided
79 if validator != nil {
80 if err := validator(tokenPath); err != nil {
81 return err
82 }
83 }
84
85 allowedTokens := s.store.GetAllowedTokens()
86 allowedTokens = executor(tokenPath, allowedTokens)
87 s.store.SetAllowedTokens(allowedTokens)
88 return nil
89}
90
91// addTokenExecutor executes token append operation
92func addTokenExecutor(tokenPath string, tokens []string) []string {
93 if contains(tokens, tokenPath) {
94 return tokens
95 }
96
97 return append(tokens, tokenPath)
98}
99
100// addTokenValidator validates token addition operation
101func addTokenValidator(tokenPath string) error {
102 if contains(defaultAllowed, tokenPath) {
103 return ufmt.Errorf("%v: cannot add existing token(%s)", errAddExistingToken, tokenPath)
104 }
105
106 return nil
107}
108
109// removeTokenExecutor executes token removal operation
110func removeTokenExecutor(tokenPath string, tokens []string) []string {
111 // find and remove token
112 for i, t := range tokens {
113 if t == tokenPath {
114 return append(tokens[:i], tokens[i+1:]...)
115 }
116 }
117
118 // if token not found, return the original list
119 return tokens
120}
121
122// removeTokenValidator validates token removal operation
123func removeTokenValidator(tokenPath string) error {
124 if contains(defaultAllowed, tokenPath) {
125 return ufmt.Errorf("%v: cannot remove default token(%s)", errDefaultExternalToken, tokenPath)
126 }
127
128 return nil
129}