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

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