external_token_list.gno
4.69 Kb · 166 lines
1package staker
2
3import (
4 "chain"
5
6 ufmt "gno.land/p/nt/ufmt/v0"
7 "gno.land/r/gnoswap/access/v1"
8 "gno.land/r/gnoswap/common"
9 "gno.land/r/gnoswap/halt/v1"
10 sr "gno.land/r/gnoswap/staker"
11)
12
13// AddToken adds a registered token key to the list of allowed tokens.
14// Only admin or governance can add a token.
15//
16// Parameters:
17// - _: Leading realm-call discriminator; callers pass 0.
18// - rlm: Current staker realm context, validated before storage is changed.
19// - tokenPath: Registered token path to add to the allowed-token list.
20//
21// Panics:
22// - If the caller is not admin or governance, or the token key is not registered.
23func (s *stakerV1) AddToken(_ int, rlm realm, tokenPath string) {
24 access.AssertIsRlmCurrent(0, rlm)
25
26 halt.AssertIsNotHaltedStaker()
27
28 previousRealm := rlm.Previous()
29 caller := previousRealm.Address()
30 access.AssertIsAdminOrGovernance(caller)
31
32 if err := checkCannotAddDefaultToken(tokenPath); err != nil {
33 panic(err.Error())
34 }
35
36 common.MustRegistered(tokenPath)
37
38 if err := s.store.AddAllowedToken(0, rlm, tokenPath); err != nil {
39 panic(err.Error())
40 }
41
42 chain.Emit(
43 "AddToken",
44 "prevAddr", caller.String(),
45 "prevRealm", previousRealm.PkgPath(),
46 "tokenPath", tokenPath,
47 )
48}
49
50// RemoveToken removes a token path from the list of allowed tokens.
51// Only the admin can remove a token.
52//
53// Default tokens cannot be removed.
54//
55// Parameters:
56// - _: Leading realm-call discriminator; callers pass 0.
57// - rlm: Current staker realm context, validated before storage is changed.
58// - tokenPath: Token path to remove from the allowed-token list.
59//
60// Panics:
61// - If the caller is not admin or governance, or the token path is a protected default token.
62func (s *stakerV1) RemoveToken(_ int, rlm realm, tokenPath string) {
63 access.AssertIsRlmCurrent(0, rlm)
64
65 halt.AssertIsNotHaltedStaker()
66
67 previousRealm := rlm.Previous()
68 caller := previousRealm.Address()
69 access.AssertIsAdminOrGovernance(caller)
70
71 if err := checkCannotRemoveDefaultToken(tokenPath); err != nil {
72 panic(err.Error())
73 }
74
75 if err := s.store.RemoveAllowedToken(0, rlm, tokenPath); err != nil {
76 panic(err.Error())
77 }
78
79 chain.Emit(
80 "RemoveToken",
81 "prevAddr", caller.String(),
82 "prevRealm", previousRealm.PkgPath(),
83 "tokenPath", tokenPath,
84 )
85}
86
87func checkCannotAddDefaultToken(tokenPath string) error {
88 if contains(sr.DefaultAllowedTokens(), tokenPath) {
89 return ufmt.Errorf("%v: cannot add existing token(%s)", errAddExistingToken, tokenPath)
90 }
91
92 return nil
93}
94
95func checkCannotRemoveDefaultToken(tokenPath string) error {
96 if contains(sr.DefaultAllowedTokens(), tokenPath) {
97 return ufmt.Errorf("%v: cannot remove default token(%s)", errDefaultExternalToken, tokenPath)
98 }
99
100 return nil
101}
102
103// SetDeniedRewardToken sets or clears the operational deny flag for an external
104// incentive reward token.
105//
106// Pool-pair tokens qualify as reward tokens for their own pool without the
107// governance allowlist (a product policy), so the deny flag is the only lever
108// to stop NEW incentives in a pair token whose issuer turned hostile. The flag
109// is checked at incentive creation only: collection of already-created
110// incentives is deliberately unaffected, because the ledger-level delivery
111// guard in deliverExternalIncentiveReward already bounds their blast radius to
112// the hostile token itself.
113//
114// Default protocol tokens (GNS, WUGNOT) cannot be denied.
115//
116// Only the admin or governance can set the flag.
117//
118// Parameters:
119// - _: Leading realm-call discriminator; callers pass 0.
120// - rlm: Current staker realm context, validated before the deny list is changed.
121// - tokenPath: Reward-token path whose denied status is being changed.
122// - denied: True to add tokenPath to the deny list, false to remove it.
123func (s *stakerV1) SetDeniedRewardToken(_ int, rlm realm, tokenPath string, denied bool) {
124 access.AssertIsRlmCurrent(0, rlm)
125
126 halt.AssertIsNotHaltedStaker()
127
128 previousRealm := rlm.Previous()
129 caller := previousRealm.Address()
130 access.AssertIsAdminOrGovernance(caller)
131
132 if denied {
133 if err := checkCannotDenyDefaultToken(tokenPath); err != nil {
134 panic(err.Error())
135 }
136
137 if err := s.store.AddDeniedRewardToken(0, rlm, tokenPath); err != nil {
138 panic(err.Error())
139 }
140 } else {
141 if err := s.store.RemoveDeniedRewardToken(0, rlm, tokenPath); err != nil {
142 panic(err.Error())
143 }
144 }
145
146 deniedStr := "false"
147 if denied {
148 deniedStr = "true"
149 }
150
151 chain.Emit(
152 "SetDeniedRewardToken",
153 "prevAddr", caller.String(),
154 "prevRealm", previousRealm.PkgPath(),
155 "tokenPath", tokenPath,
156 "denied", deniedStr,
157 )
158}
159
160func checkCannotDenyDefaultToken(tokenPath string) error {
161 if contains(sr.DefaultAllowedTokens(), tokenPath) {
162 return ufmt.Errorf("%v: cannot deny default token(%s)", errCannotDenyDefaultToken, tokenPath)
163 }
164
165 return nil
166}