protocol_fee_state.gno
9.25 Kb · 261 lines
1package protocol_fee
2
3import (
4 bptree "gno.land/p/nt/bptree/v0"
5 ufmt "gno.land/p/nt/ufmt/v0"
6
7 gnsmath "gno.land/p/gnoswap/gnsmath/v1"
8 prabc "gno.land/p/gnoswap/rbac/v1"
9 "gno.land/r/gnoswap/access/v1"
10 "gno.land/r/gnoswap/common"
11 "gno.land/r/gnoswap/protocol_fee"
12)
13
14// protocolFeeState holds all the state variables for protocol fee management
15type protocolFeeState struct {
16 store protocol_fee.IProtocolFeeStore
17}
18
19// DevOpsPct returns the percentage of protocol fees allocated to DevOps.
20//
21// Returns:
22// - pct: Stored DevOps protocol-fee allocation percentage in basis points.
23func (pfs *protocolFeeState) DevOpsPct() int64 {
24 return pfs.store.GetDevOpsPct()
25}
26
27// GovStakerPct returns the percentage of protocol fees allocated to Gov/Staker.
28//
29// Returns:
30// - pct: Gov/Staker protocol-fee allocation percentage in basis points, computed as 10000 minus the stored DevOps percentage.
31func (pfs *protocolFeeState) GovStakerPct() int64 {
32 return 10000 - pfs.store.GetDevOpsPct()
33}
34
35// AccuToGovStaker returns the cumulative amount allocated to GovStaker.
36// It includes allocations that may still be pending distribution; completed
37// transfers are tracked separately in the distribution history.
38//
39// Returns:
40// - tree: BP-tree mapping token paths to cumulative amounts allocated to Gov/Staker, including allocations pending distribution.
41func (pfs *protocolFeeState) AccuToGovStaker() *bptree.BPTree {
42 return pfs.store.GetAccuToGovStaker()
43}
44
45// AccuToDevOps returns the cumulative amount allocated to DevOps.
46// It includes allocations that may still be pending distribution; completed
47// transfers are tracked separately in the distribution history.
48//
49// Returns:
50// - tree: BP-tree mapping token paths to cumulative amounts allocated to DevOps, including allocations pending distribution.
51func (pfs *protocolFeeState) AccuToDevOps() *bptree.BPTree {
52 return pfs.store.GetAccuToDevOps()
53}
54
55// ActualDistributedToGovStaker returns the cumulative amounts actually distributed to Gov/Staker.
56//
57// Returns:
58// - tree: BP-tree mapping token paths to cumulative amounts actually distributed to Gov/Staker.
59func (pfs *protocolFeeState) ActualDistributedToGovStaker() *bptree.BPTree {
60 return pfs.store.GetDistributedToGovStakerHistory()
61}
62
63// ActualDistributedToDevOps returns the cumulative amounts actually distributed to DevOps.
64//
65// Returns:
66// - tree: BP-tree mapping token paths to cumulative amounts actually distributed to DevOps.
67func (pfs *protocolFeeState) ActualDistributedToDevOps() *bptree.BPTree {
68 return pfs.store.GetDistributedToDevOpsHistory()
69}
70
71// ReservedTokens returns token paths reserved for distribution.
72//
73// Returns:
74// - tokenPaths: Token paths currently reserved for protocol-fee distribution.
75func (pfs *protocolFeeState) ReservedTokens() []string {
76 return pfs.store.GetReservedTokens()
77}
78
79// distributeToDevOps distributes tokens to DevOps and updates related state.
80// Amount should be greater than 0 (already checked in DistributeProtocolFee).
81func (pfs *protocolFeeState) distributeToDevOps(_ int, rlm realm, token string, amount int64) error {
82 devOpsAddr := access.MustGetAddress(prabc.ROLE_DEVOPS.String())
83
84 if err := pfs.addActualDistributedToDevOps(0, rlm, token, amount); err != nil {
85 return err
86 }
87 common.SafeGRC20Transfer(0, rlm, token, devOpsAddr, amount)
88
89 return nil
90}
91
92// distributeToGovStaker distributes tokens to Gov/Staker and updates related state.
93// Amount should be greater than 0 (already checked in DistributeProtocolFee).
94func (pfs *protocolFeeState) distributeToGovStaker(_ int, rlm realm, token string, amount int64) error {
95 govStakerAddr := access.MustGetAddress(prabc.ROLE_GOV_STAKER.String())
96
97 if err := pfs.addActualDistributedToGovStaker(0, rlm, token, amount); err != nil {
98 return err
99 }
100 common.SafeGRC20Transfer(0, rlm, token, govStakerAddr, amount)
101
102 return nil
103}
104
105// setDevOpsPct sets the devOpsPct.
106func (pfs *protocolFeeState) setDevOpsPct(_ int, rlm realm, pct int64) (int64, error) {
107 if pct < 0 {
108 return 0, makeErrorWithDetail(
109 errInvalidPct,
110 ufmt.Sprintf("pct(%d) should not be negative", pct),
111 )
112 }
113 if pct > 10000 {
114 return 0, makeErrorWithDetail(
115 errInvalidPct,
116 ufmt.Sprintf("pct(%d) should not be bigger than 10000", pct),
117 )
118 }
119
120 if err := pfs.store.SetDevOpsPct(0, rlm, pct); err != nil {
121 return 0, err
122 }
123
124 return pct, nil
125}
126
127// setGovStakerPct sets the govStakerPct by calculating devOpsPct.
128func (pfs *protocolFeeState) setGovStakerPct(_ int, rlm realm, pct int64) (int64, error) {
129 if pct < 0 {
130 return 0, makeErrorWithDetail(
131 errInvalidPct,
132 ufmt.Sprintf("pct(%d) should not be negative", pct),
133 )
134 }
135
136 devOpsPct := 10000 - pct
137
138 if _, err := pfs.setDevOpsPct(0, rlm, devOpsPct); err != nil {
139 return 0, err
140 }
141
142 return pct, nil
143}
144
145// addAccuToGovStaker adds the amount to the accuToGovStaker by token path.
146func (pfs *protocolFeeState) addAccuToGovStaker(_ int, rlm realm, tokenPath string, amount int64) error {
147 before := pfs.GetAccuTransferToGovStakerByTokenPath(tokenPath)
148
149 // Check for overflow
150 after := gnsmath.SafeAddInt64(before, amount)
151 if err := pfs.store.SetAccuToGovStakerItem(0, rlm, tokenPath, after); err != nil {
152 return err
153 }
154 return nil
155}
156
157// addAccuToDevOps adds the amount to the accuToDevOps by token path.
158func (pfs *protocolFeeState) addAccuToDevOps(_ int, rlm realm, tokenPath string, amount int64) error {
159 before := pfs.GetAccuTransferToDevOpsByTokenPath(tokenPath)
160
161 // Check for overflow
162 after := gnsmath.SafeAddInt64(before, amount)
163 if err := pfs.store.SetAccuToDevOpsItem(0, rlm, tokenPath, after); err != nil {
164 return err
165 }
166 return nil
167}
168
169// addActualDistributedToGovStaker adds the amount to the actual distributed amount to gov/staker by token path.
170func (pfs *protocolFeeState) addActualDistributedToGovStaker(_ int, rlm realm, tokenPath string, amount int64) error {
171 before := pfs.GetActualDistributedToGovStakerByTokenPath(tokenPath)
172 after := gnsmath.SafeAddInt64(before, amount)
173 if err := pfs.store.SetDistributedToGovStakerHistoryItem(0, rlm, tokenPath, after); err != nil {
174 return err
175 }
176 return nil
177}
178
179// addActualDistributedToDevOps adds the amount to the actual distributed amount to devOps by token path.
180func (pfs *protocolFeeState) addActualDistributedToDevOps(_ int, rlm realm, tokenPath string, amount int64) error {
181 before := pfs.GetActualDistributedToDevOpsByTokenPath(tokenPath)
182 after := gnsmath.SafeAddInt64(before, amount)
183 if err := pfs.store.SetDistributedToDevOpsHistoryItem(0, rlm, tokenPath, after); err != nil {
184 return err
185 }
186 return nil
187}
188
189// GetAccuTransferToGovStakerByTokenPath gets the accumulated amount to gov/staker by token path.
190//
191// Parameters:
192// - tokenPath: Token path whose cumulative Gov/Staker allocation should be read.
193//
194// Returns:
195// - amount: Cumulative Gov/Staker allocation for tokenPath, or zero when no entry is recorded.
196func (pfs *protocolFeeState) GetAccuTransferToGovStakerByTokenPath(tokenPath string) int64 {
197 return retrieveAmount(pfs.store.GetAccuToGovStaker(), tokenPath)
198}
199
200// GetAccuTransferToDevOpsByTokenPath gets the accumulated amount to devOps by token path.
201//
202// Parameters:
203// - tokenPath: Token path whose cumulative DevOps allocation should be read.
204//
205// Returns:
206// - amount: Cumulative DevOps allocation for tokenPath, or zero when no entry is recorded.
207func (pfs *protocolFeeState) GetAccuTransferToDevOpsByTokenPath(tokenPath string) int64 {
208 return retrieveAmount(pfs.store.GetAccuToDevOps(), tokenPath)
209}
210
211// GetActualDistributedToGovStakerByTokenPath gets the actual distributed amount to gov/staker by token path.
212//
213// Parameters:
214// - tokenPath: Token path whose cumulative actual Gov/Staker distribution should be read.
215//
216// Returns:
217// - amount: Cumulative amount actually distributed to Gov/Staker for tokenPath, or zero when no history is recorded.
218func (pfs *protocolFeeState) GetActualDistributedToGovStakerByTokenPath(tokenPath string) int64 {
219 return retrieveAmount(pfs.store.GetDistributedToGovStakerHistory(), tokenPath)
220}
221
222// GetActualDistributedToDevOpsByTokenPath gets the actual distributed amount to devOps by token path.
223//
224// Parameters:
225// - tokenPath: Token path whose cumulative actual DevOps distribution should be read.
226//
227// Returns:
228// - amount: Cumulative amount actually distributed to DevOps for tokenPath, or zero when no history is recorded.
229func (pfs *protocolFeeState) GetActualDistributedToDevOpsByTokenPath(tokenPath string) int64 {
230 return retrieveAmount(pfs.store.GetDistributedToDevOpsHistory(), tokenPath)
231}
232
233// removeReservedToken removes one distributed token from the reserved token index.
234func (pfs *protocolFeeState) removeReservedToken(_ int, rlm realm, tokenPath string) error {
235 return pfs.store.RemoveReservedToken(0, rlm, tokenPath)
236}
237
238// NewProtocolFeeState creates a new instance of protocolFeeState with initialized values
239//
240// Parameters:
241// - protocolFeeStore: Store implementation backing the new protocol-fee state view.
242//
243// Returns:
244// - state: New protocolFeeState wrapper backed by protocolFeeStore.
245func NewProtocolFeeStateBy(protocolFeeStore protocol_fee.IProtocolFeeStore) *protocolFeeState {
246 return &protocolFeeState{
247 store: protocolFeeStore,
248 }
249}
250
251func retrieveAmount(tree *bptree.BPTree, key string) int64 {
252 amountI := tree.Get(key)
253 if amountI == nil {
254 return 0
255 }
256 res, ok := amountI.(int64)
257 if !ok {
258 panic(ufmt.Sprintf("failed to cast amount to int64: %T", amountI))
259 }
260 return res
261}