protocol_fee_state.gno
7.02 Kb · 208 lines
1package v1
2
3import (
4 bptree "gno.land/p/nt/bptree/v0"
5 ufmt "gno.land/p/nt/ufmt/v0"
6
7 prabc "gno.land/p/gnoswap/rbac"
8 "gno.land/r/gnoswap/access"
9 "gno.land/r/gnoswap/common"
10 "gno.land/r/gnoswap/protocol_fee"
11)
12
13// protocolFeeState holds all the state variables for protocol fee management
14type protocolFeeState struct {
15 store protocol_fee.IProtocolFeeStore
16}
17
18// DevOpsPct returns the percentage of protocol fees allocated to DevOps.
19func (pfs *protocolFeeState) DevOpsPct() int64 {
20 return pfs.store.GetDevOpsPct()
21}
22
23// GovStakerPct returns the percentage of protocol fees allocated to Gov/Staker.
24func (pfs *protocolFeeState) GovStakerPct() int64 {
25 return 10000 - pfs.store.GetDevOpsPct()
26}
27
28// AccuToGovStaker returns the accumulated amounts distributed to Gov/Staker.
29func (pfs *protocolFeeState) AccuToGovStaker() *bptree.BPTree {
30 return pfs.store.GetAccuToGovStaker()
31}
32
33// AccuToDevOps returns the accumulated amounts distributed to DevOps.
34func (pfs *protocolFeeState) AccuToDevOps() *bptree.BPTree {
35 return pfs.store.GetAccuToDevOps()
36}
37
38// ActualDistributedToGovStaker returns the cumulative amounts actually distributed to Gov/Staker.
39func (pfs *protocolFeeState) ActualDistributedToGovStaker() *bptree.BPTree {
40 return pfs.store.GetDistributedToGovStakerHistory()
41}
42
43// ActualDistributedToDevOps returns the cumulative amounts actually distributed to DevOps.
44func (pfs *protocolFeeState) ActualDistributedToDevOps() *bptree.BPTree {
45 return pfs.store.GetDistributedToDevOpsHistory()
46}
47
48// ReservedTokens returns token paths reserved for distribution.
49func (pfs *protocolFeeState) ReservedTokens() []string {
50 return pfs.store.GetReservedTokens()
51}
52
53// distributeToDevOps distributes tokens to DevOps and updates related state.
54// Amount should be greater than 0 (already checked in DistributeProtocolFee).
55func (pfs *protocolFeeState) distributeToDevOps(_ int, rlm realm, token string, amount int64) error {
56 devOpsAddr := access.MustGetAddress(prabc.ROLE_DEVOPS.String())
57
58 if err := pfs.addActualDistributedToDevOps(0, rlm, token, amount); err != nil {
59 return err
60 }
61 common.SafeGRC20Transfer(cross(rlm), token, devOpsAddr, amount)
62
63 return nil
64}
65
66// distributeToGovStaker distributes tokens to Gov/Staker and updates related state.
67// Amount should be greater than 0 (already checked in DistributeProtocolFee).
68func (pfs *protocolFeeState) distributeToGovStaker(_ int, rlm realm, token string, amount int64) error {
69 govStakerAddr := access.MustGetAddress(prabc.ROLE_GOV_STAKER.String())
70
71 if err := pfs.addActualDistributedToGovStaker(0, rlm, token, amount); err != nil {
72 return err
73 }
74 common.SafeGRC20Transfer(cross(rlm), token, govStakerAddr, amount)
75
76 return nil
77}
78
79// setDevOpsPct sets the devOpsPct.
80func (pfs *protocolFeeState) setDevOpsPct(_ int, rlm realm, pct int64) (int64, error) {
81 if pct < 0 {
82 return 0, makeErrorWithDetail(
83 errInvalidPct,
84 ufmt.Sprintf("pct(%d) should not be negative", pct),
85 )
86 }
87 if pct > 10000 {
88 return 0, makeErrorWithDetail(
89 errInvalidPct,
90 ufmt.Sprintf("pct(%d) should not be bigger than 10000", pct),
91 )
92 }
93
94 if err := pfs.store.SetDevOpsPct(0, rlm, pct); err != nil {
95 return 0, err
96 }
97
98 return pct, nil
99}
100
101// setGovStakerPct sets the govStakerPct by calculating devOpsPct.
102func (pfs *protocolFeeState) setGovStakerPct(_ int, rlm realm, pct int64) (int64, error) {
103 if pct < 0 {
104 return 0, makeErrorWithDetail(
105 errInvalidPct,
106 ufmt.Sprintf("pct(%d) should not be negative", pct),
107 )
108 }
109
110 devOpsPct := 10000 - pct
111
112 if _, err := pfs.setDevOpsPct(0, rlm, devOpsPct); err != nil {
113 return 0, err
114 }
115
116 return pct, nil
117}
118
119// addAccuToGovStaker adds the amount to the accuToGovStaker by token path.
120func (pfs *protocolFeeState) addAccuToGovStaker(_ int, rlm realm, tokenPath string, amount int64) error {
121 before := pfs.GetAccuTransferToGovStakerByTokenPath(tokenPath)
122
123 // Check for overflow
124 after := safeAddInt64(before, amount)
125 if err := pfs.store.SetAccuToGovStakerItem(0, rlm, tokenPath, after); err != nil {
126 return err
127 }
128 return nil
129}
130
131// addAccuToDevOps adds the amount to the accuToDevOps by token path.
132func (pfs *protocolFeeState) addAccuToDevOps(_ int, rlm realm, tokenPath string, amount int64) error {
133 before := pfs.GetAccuTransferToDevOpsByTokenPath(tokenPath)
134
135 // Check for overflow
136 after := safeAddInt64(before, amount)
137 if err := pfs.store.SetAccuToDevOpsItem(0, rlm, tokenPath, after); err != nil {
138 return err
139 }
140 return nil
141}
142
143// addActualDistributedToGovStaker adds the amount to the actual distributed amount to gov/staker by token path.
144func (pfs *protocolFeeState) addActualDistributedToGovStaker(_ int, rlm realm, tokenPath string, amount int64) error {
145 before := pfs.GetActualDistributedToGovStakerByTokenPath(tokenPath)
146 after := safeAddInt64(before, amount)
147 if err := pfs.store.SetDistributedToGovStakerHistoryItem(0, rlm, tokenPath, after); err != nil {
148 return err
149 }
150 return nil
151}
152
153// addActualDistributedToDevOps adds the amount to the actual distributed amount to devOps by token path.
154func (pfs *protocolFeeState) addActualDistributedToDevOps(_ int, rlm realm, tokenPath string, amount int64) error {
155 before := pfs.GetActualDistributedToDevOpsByTokenPath(tokenPath)
156 after := safeAddInt64(before, amount)
157 if err := pfs.store.SetDistributedToDevOpsHistoryItem(0, rlm, tokenPath, after); err != nil {
158 return err
159 }
160 return nil
161}
162
163// GetAccuTransferToGovStakerByTokenPath gets the accumulated amount to gov/staker by token path.
164func (pfs *protocolFeeState) GetAccuTransferToGovStakerByTokenPath(tokenPath string) int64 {
165 return retrieveAmount(pfs.store.GetAccuToGovStaker(), tokenPath)
166}
167
168// GetAccuTransferToDevOpsByTokenPath gets the accumulated amount to devOps by token path.
169func (pfs *protocolFeeState) GetAccuTransferToDevOpsByTokenPath(tokenPath string) int64 {
170 return retrieveAmount(pfs.store.GetAccuToDevOps(), tokenPath)
171}
172
173// GetActualDistributedToGovStakerByTokenPath gets the actual distributed amount to gov/staker by token path.
174func (pfs *protocolFeeState) GetActualDistributedToGovStakerByTokenPath(tokenPath string) int64 {
175 return retrieveAmount(pfs.store.GetDistributedToGovStakerHistory(), tokenPath)
176}
177
178// GetActualDistributedToDevOpsByTokenPath gets the actual distributed amount to devOps by token path.
179func (pfs *protocolFeeState) GetActualDistributedToDevOpsByTokenPath(tokenPath string) int64 {
180 return retrieveAmount(pfs.store.GetDistributedToDevOpsHistory(), tokenPath)
181}
182
183// clearReservedTokens clears the reserved token index after distribution.
184func (pfs *protocolFeeState) clearReservedTokens(_ int, rlm realm) error {
185 if err := pfs.store.SetReservedTokens(0, rlm, []string{}); err != nil {
186 return err
187 }
188 return nil
189}
190
191// NewProtocolFeeState creates a new instance of protocolFeeState with initialized values
192func NewProtocolFeeStateBy(protocolFeeStore protocol_fee.IProtocolFeeStore) *protocolFeeState {
193 return &protocolFeeState{
194 store: protocolFeeStore,
195 }
196}
197
198func retrieveAmount(tree *bptree.BPTree, key string) int64 {
199 amountI, exists := tree.Get(key)
200 if !exists {
201 return 0
202 }
203 res, ok := amountI.(int64)
204 if !ok {
205 panic(ufmt.Sprintf("failed to cast amount to int64: %T", amountI))
206 }
207 return res
208}