protocol_fee_state.gno
5.20 Kb ยท 178 lines
1package v1
2
3import (
4 "gno.land/p/nt/avl"
5 "gno.land/p/nt/ufmt"
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() *avl.Tree {
30 return pfs.store.GetAccuToGovStaker()
31}
32
33// AccuToDevOps returns the accumulated amounts distributed to DevOps.
34func (pfs *protocolFeeState) AccuToDevOps() *avl.Tree {
35 return pfs.store.GetAccuToDevOps()
36}
37
38// TokenListWithAmounts returns the map of token paths to their accumulated amounts.
39func (pfs *protocolFeeState) TokenListWithAmounts() map[string]int64 {
40 return pfs.store.GetTokenListWithAmounts()
41}
42
43// TokenAmountOfTokenPath returns the accumulated amount for a specific token path.
44func (pfs *protocolFeeState) TokenAmountOfTokenPath(tokenPath string) int64 {
45 amount, exists := pfs.store.GetTokenListWithAmountItem(tokenPath)
46 if !exists {
47 return 0
48 }
49
50 return amount
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(token string, amount int64) error {
56 if err := pfs.addAccuToDevOps(token, amount); err != nil {
57 return err
58 }
59
60 devOpsAddr := access.MustGetAddress(prabc.ROLE_DEVOPS.String())
61 common.SafeGRC20Transfer(cross, 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(token string, amount int64) error {
69 if err := pfs.addAccuToGovStaker(token, amount); err != nil {
70 return err
71 }
72
73 govStakerAddr := access.MustGetAddress(prabc.ROLE_GOV_STAKER.String())
74 common.SafeGRC20Transfer(cross, token, govStakerAddr, amount)
75
76 return nil
77}
78
79// setDevOpsPct sets the devOpsPct.
80func (pfs *protocolFeeState) setDevOpsPct(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(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(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(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(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(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(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(tokenPath, after); err != nil {
138 return err
139 }
140 return nil
141}
142
143// GetAccuTransferToGovStakerByTokenPath gets the accumulated amount to gov/staker by token path.
144func (pfs *protocolFeeState) GetAccuTransferToGovStakerByTokenPath(tokenPath string) int64 {
145 return retrieveAmount(pfs.store.GetAccuToGovStaker(), tokenPath)
146}
147
148// GetAccuTransferToDevOpsByTokenPath gets the accumulated amount to devOps by token path.
149func (pfs *protocolFeeState) GetAccuTransferToDevOpsByTokenPath(tokenPath string) int64 {
150 return retrieveAmount(pfs.store.GetAccuToDevOps(), tokenPath)
151}
152
153// clearTokenListWithAmount clears the tokenListWithAmount.
154func (pfs *protocolFeeState) clearTokenListWithAmount() error {
155 if err := pfs.store.SetTokenListWithAmounts(make(map[string]int64)); err != nil {
156 return err
157 }
158 return nil
159}
160
161// NewProtocolFeeState creates a new instance of protocolFeeState with initialized values
162func NewProtocolFeeStateBy(protocolFeeStore protocol_fee.IProtocolFeeStore) *protocolFeeState {
163 return &protocolFeeState{
164 store: protocolFeeStore,
165 }
166}
167
168func retrieveAmount(tree *avl.Tree, key string) int64 {
169 amountI, exists := tree.Get(key)
170 if !exists {
171 return 0
172 }
173 res, ok := amountI.(int64)
174 if !ok {
175 panic(ufmt.Sprintf("failed to cast amount to int64: %T", amountI))
176 }
177 return res
178}