Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}