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_reward_state.gno

10.53 Kb · 303 lines
  1package staker
  2
  3import (
  4	bptree "gno.land/p/nt/bptree/v0"
  5	ufmt "gno.land/p/nt/ufmt/v0"
  6
  7	u256 "gno.land/p/gnoswap/uint256/v1"
  8)
  9
 10// ProtocolFeeRewardState tracks the protocol fee rewards of one staker.
 11//
 12// Ordinary stake changes append one ProtocolFeeStakeEvent; Redelegate performs
 13// a remove plus an add and appends two events. Each token is settled on its own
 14// from those events, so the state keeps a per-token cursor into the event
 15// history rather than a reward debt for every token at once.
 16type ProtocolFeeRewardState struct {
 17	// stakedAmount is the current amount staked
 18	stakedAmount int64
 19	// stakeEvents records the staked amount in force from each stake change, by index
 20	stakeEvents *UintTree // index -> *ProtocolFeeStakeEvent
 21	// stakeEventCount is the number of recorded stake events
 22	stakeEventCount int64
 23	// tokenStates maps a token path to the settlement state of that token
 24	tokenStates *bptree.BPTree // tokenPath -> *ProtocolFeeTokenRewardState
 25	// claimedTimestamp is the last timestamp at which every token was collected
 26	claimedTimestamp int64
 27}
 28
 29// ProtocolFeeStakeEvent is one stake change: from epoch on, stakedAmount was staked.
 30type ProtocolFeeStakeEvent struct {
 31	epoch        int64
 32	stakedAmount int64
 33}
 34
 35// GetEpoch returns the accrual epoch from which this stake event applies.
 36//
 37// Returns:
 38//   - int64: epoch at which the stake amount became effective
 39func (e *ProtocolFeeStakeEvent) GetEpoch() int64 { return e.epoch }
 40
 41// GetStakedAmount returns the stake amount in force for this event.
 42//
 43// Returns:
 44//   - int64: staked amount associated with the event
 45func (e *ProtocolFeeStakeEvent) GetStakedAmount() int64 { return e.stakedAmount }
 46
 47// ProtocolFeeTokenRewardState is the settlement state of one token for one staker.
 48//
 49// Stake events up to eventCursor are folded into earnedX128. The open segment starts
 50// where the last folded event left the accumulator (segmentStartX128) with
 51// segmentStakedAmount staked.
 52type ProtocolFeeTokenRewardState struct {
 53	// eventCursor is the number of stake events already folded in
 54	eventCursor int64
 55	// segmentStakedAmount is the amount staked during the open segment
 56	segmentStakedAmount int64
 57	// segmentStartX128 is the accumulated fee per stake at the start of the open segment
 58	segmentStartX128 *u256.Uint
 59	// earnedX128 is the reward earned by closed segments and not yet collected, scaled by 2^128
 60	earnedX128 *u256.Uint
 61	// claimedReward is the total reward collected so far
 62	claimedReward int64
 63}
 64
 65// NewProtocolFeeRewardState creates an empty state for a staker with no stake.
 66//
 67// Returns:
 68//   - *ProtocolFeeRewardState: initialized reward state with empty event and token trees
 69func NewProtocolFeeRewardState() *ProtocolFeeRewardState {
 70	return &ProtocolFeeRewardState{
 71		stakedAmount:     0,
 72		stakeEvents:      NewUintTree(),
 73		stakeEventCount:  0,
 74		tokenStates:      bptree.NewBPTreeN(16),
 75		claimedTimestamp: 0,
 76	}
 77}
 78
 79// NewProtocolFeeTokenRewardState creates the settlement state of a token whose open
 80// segment starts at the given cursor, stake and accumulator value.
 81//
 82// Parameters:
 83//   - eventCursor: number of stake events already folded into this token state
 84//   - segmentStakedAmount: stake amount in force during the open segment
 85//   - segmentStartX128: accumulated fee-per-stake value at the open segment start, scaled by 2^128
 86//
 87// Returns:
 88//   - *ProtocolFeeTokenRewardState: token settlement state with zero closed-segment earnings and claimed reward
 89func NewProtocolFeeTokenRewardState(eventCursor int64, segmentStakedAmount int64, segmentStartX128 *u256.Uint) *ProtocolFeeTokenRewardState {
 90	return &ProtocolFeeTokenRewardState{
 91		eventCursor:         eventCursor,
 92		segmentStakedAmount: segmentStakedAmount,
 93		segmentStartX128:    u256.Zero().Set(segmentStartX128),
 94		earnedX128:          u256.Zero(),
 95		claimedReward:       0,
 96	}
 97}
 98
 99/* ProtocolFeeRewardState getters */
100
101// GetStakedAmount returns the current stake amount tracked for the staker.
102//
103// Returns:
104//   - int64: current staked amount
105func (p *ProtocolFeeRewardState) GetStakedAmount() int64 {
106	return p.stakedAmount
107}
108
109// GetStakeEventCount returns the number of stake-change events recorded.
110//
111// Returns:
112//   - int64: count of indexed stake events
113func (p *ProtocolFeeRewardState) GetStakeEventCount() int64 {
114	return p.stakeEventCount
115}
116
117// GetStakeEvent returns the indexed stake event.
118//
119// Parameters:
120//   - index: zero-based stake-event index
121//
122// Returns:
123//   - *ProtocolFeeStakeEvent: event at index, or nil when no event is stored there
124//   - bool: true when an event exists at index; false when the index is absent
125func (p *ProtocolFeeRewardState) GetStakeEvent(index int64) (*ProtocolFeeStakeEvent, bool) {
126	ei, ok := p.stakeEvents.Get(index)
127	if !ok {
128		return nil, false
129	}
130	event, castOk := ei.(*ProtocolFeeStakeEvent)
131	if !castOk {
132		panic(ufmt.Sprintf("failed to cast stake event: %T", ei))
133	}
134	return event, true
135}
136
137// GetTokenState returns the settlement state of tokenPath, or false when the token was
138// never settled for this staker.
139//
140// Parameters:
141//   - tokenPath: registered token path whose per-staker settlement state is requested
142//
143// Returns:
144//   - *ProtocolFeeTokenRewardState: token settlement state, or nil when it has not been initialized
145//   - bool: true when tokenPath has a stored settlement state, otherwise false
146func (p *ProtocolFeeRewardState) GetTokenState(tokenPath string) (*ProtocolFeeTokenRewardState, bool) {
147	ti := p.tokenStates.Get(tokenPath)
148	if ti == nil {
149		return nil, false
150	}
151	tokenState, castOk := ti.(*ProtocolFeeTokenRewardState)
152	if !castOk {
153		panic(ufmt.Sprintf("failed to cast token reward state: %T", ti))
154	}
155	return tokenState, true
156}
157
158// GetTokenPaths returns every token path settled for this staker, in key order.
159//
160// Returns:
161//   - []string: token paths with stored settlement state, ordered by the underlying tree keys
162func (p *ProtocolFeeRewardState) GetTokenPaths() []string {
163	tokenPaths := make([]string, 0, p.tokenStates.Size())
164	p.tokenStates.Iterate("", "", func(key string, _ any) bool {
165		tokenPaths = append(tokenPaths, key)
166		return false
167	})
168	return tokenPaths
169}
170
171// GetClaimedReward returns the total reward of tokenPath collected so far.
172//
173// Parameters:
174//   - tokenPath: token path whose accumulated claimed reward is requested
175//
176// Returns:
177//   - int64: total reward collected for tokenPath, or zero when no token state exists
178func (p *ProtocolFeeRewardState) GetClaimedReward(tokenPath string) int64 {
179	tokenState, ok := p.GetTokenState(tokenPath)
180	if !ok {
181		return 0
182	}
183	return tokenState.GetClaimedReward()
184}
185
186// GetClaimedTimestamp returns the last timestamp at which all token rewards were collected.
187//
188// Returns:
189//   - int64: Unix timestamp recorded for the most recent all-token collection
190func (p *ProtocolFeeRewardState) GetClaimedTimestamp() int64 {
191	return p.claimedTimestamp
192}
193
194/* ProtocolFeeRewardState setters */
195
196// SetStakedAmount updates the current stake amount tracked for the staker.
197//
198// Parameters:
199//   - stakedAmount: new current staked amount
200func (p *ProtocolFeeRewardState) SetStakedAmount(stakedAmount int64) {
201	p.stakedAmount = stakedAmount
202}
203
204// AppendStakeEvent records that stakedAmount is staked from epoch on.
205//
206// Parameters:
207//   - epoch: accrual epoch at which this stake amount becomes effective
208//   - stakedAmount: stake amount in force from epoch onward
209func (p *ProtocolFeeRewardState) AppendStakeEvent(epoch int64, stakedAmount int64) {
210	p.stakeEvents.Set(p.stakeEventCount, &ProtocolFeeStakeEvent{
211		epoch:        epoch,
212		stakedAmount: stakedAmount,
213	})
214	p.stakeEventCount++
215}
216
217// SetTokenState stores the settlement state for a token path.
218//
219// Parameters:
220//   - tokenPath: token path used as the settlement-state key
221//   - tokenState: per-token settlement state to store
222func (p *ProtocolFeeRewardState) SetTokenState(tokenPath string, tokenState *ProtocolFeeTokenRewardState) {
223	p.tokenStates.Set(tokenPath, tokenState)
224}
225
226// SetClaimedTimestamp records the timestamp at which all token rewards were collected.
227//
228// Parameters:
229//   - claimedTimestamp: Unix timestamp of the all-token collection
230func (p *ProtocolFeeRewardState) SetClaimedTimestamp(claimedTimestamp int64) {
231	p.claimedTimestamp = claimedTimestamp
232}
233
234/* ProtocolFeeTokenRewardState getters and setters */
235
236// GetEventCursor returns the number of stake events already folded for this token.
237//
238// Returns:
239//   - int64: count of folded stake events
240func (t *ProtocolFeeTokenRewardState) GetEventCursor() int64 {
241	return t.eventCursor
242}
243
244// GetSegmentStakedAmount returns the stake amount in the open segment.
245//
246// Returns:
247//   - int64: stake amount used while settling the open segment
248func (t *ProtocolFeeTokenRewardState) GetSegmentStakedAmount() int64 {
249	return t.segmentStakedAmount
250}
251
252// GetSegmentStartX128 returns the accumulator value at the open segment start.
253//
254// Returns:
255//   - *u256.Uint: fee-per-stake accumulator at segment start, scaled by 2^128
256func (t *ProtocolFeeTokenRewardState) GetSegmentStartX128() *u256.Uint {
257	return t.segmentStartX128
258}
259
260// GetEarnedX128 returns closed-segment earnings awaiting collection.
261//
262// Returns:
263//   - *u256.Uint: unclaimed reward accumulator scaled by 2^128
264func (t *ProtocolFeeTokenRewardState) GetEarnedX128() *u256.Uint {
265	return t.earnedX128
266}
267
268// GetClaimedReward returns the total reward collected for this token state.
269//
270// Returns:
271//   - int64: cumulative collected reward amount
272func (t *ProtocolFeeTokenRewardState) GetClaimedReward() int64 {
273	return t.claimedReward
274}
275
276// SetSegment moves the open segment: events up to eventCursor are folded, and the
277// segment starts at segmentStartX128 with segmentStakedAmount staked.
278//
279// Parameters:
280//   - eventCursor: number of stake events folded into the new segment
281//   - segmentStakedAmount: stake amount in force for the new open segment
282//   - segmentStartX128: fee-per-stake accumulator at the new segment start, scaled by 2^128
283func (t *ProtocolFeeTokenRewardState) SetSegment(eventCursor int64, segmentStakedAmount int64, segmentStartX128 *u256.Uint) {
284	t.eventCursor = eventCursor
285	t.segmentStakedAmount = segmentStakedAmount
286	t.segmentStartX128 = u256.Zero().Set(segmentStartX128)
287}
288
289// SetEarnedX128 replaces the closed-segment earnings accumulator.
290//
291// Parameters:
292//   - earnedX128: unclaimed earnings accumulator scaled by 2^128
293func (t *ProtocolFeeTokenRewardState) SetEarnedX128(earnedX128 *u256.Uint) {
294	t.earnedX128 = u256.Zero().Set(earnedX128)
295}
296
297// SetClaimedReward replaces the cumulative collected reward amount.
298//
299// Parameters:
300//   - claimedReward: total reward collected for this token state
301func (t *ProtocolFeeTokenRewardState) SetClaimedReward(claimedReward int64) {
302	t.claimedReward = claimedReward
303}