Search Apps Documentation Source Content File Folder Download Copy Actions Download

deposit.gno

9.68 Kb ยท 338 lines
  1package staker
  2
  3import (
  4	"math"
  5
  6	u256 "gno.land/p/gnoswap/uint256"
  7	"gno.land/p/nt/avl"
  8)
  9
 10type Deposit struct {
 11	warmups                        []Warmup   // warmup information
 12	liquidity                      *u256.Uint // liquidity
 13	targetPoolPath                 string     // staked position's pool path
 14	owner                          address    // owner address
 15	stakeTime                      int64      // staked time
 16	internalRewardLastCollectTime  int64      // last collect time for internal reward
 17	collectedInternalReward        int64      // collected internal reward
 18	collectedExternalRewards       *avl.Tree  // collected external reward by incentive id (incentiveID -> int64)
 19	externalRewardLastCollectTimes *avl.Tree  // last collect time for external rewards by incentive id (incentiveID -> int64)
 20	externalIncentiveIds           *avl.Tree  // external incentive ids for this deposit (incentiveID -> bool)
 21	lastExternalIncentiveUpdatedAt int64      // last time when external incentive ids were synced
 22	tickLower                      int32      // tick lower
 23	tickUpper                      int32      // tick upper
 24}
 25
 26func (d *Deposit) Owner() address {
 27	return d.owner
 28}
 29
 30func (d *Deposit) SetOwner(owner address) {
 31	d.owner = owner
 32}
 33
 34func (d *Deposit) TargetPoolPath() string {
 35	return d.targetPoolPath
 36}
 37
 38func (d *Deposit) SetTargetPoolPath(targetPoolPath string) {
 39	d.targetPoolPath = targetPoolPath
 40}
 41
 42func (d *Deposit) Liquidity() *u256.Uint {
 43	return d.liquidity
 44}
 45
 46func (d *Deposit) SetLiquidity(liquidity *u256.Uint) {
 47	d.liquidity = liquidity
 48}
 49
 50func (d *Deposit) StakeTime() int64 {
 51	return d.stakeTime
 52}
 53
 54func (d *Deposit) SetStakeTime(stakeTime int64) {
 55	d.stakeTime = stakeTime
 56}
 57
 58func (d *Deposit) InternalRewardLastCollectTime() int64 {
 59	return d.internalRewardLastCollectTime
 60}
 61
 62func (d *Deposit) SetInternalRewardLastCollectTime(internalRewardLastCollectTime int64) {
 63	d.internalRewardLastCollectTime = internalRewardLastCollectTime
 64}
 65
 66func (d *Deposit) CollectedInternalReward() int64 {
 67	return d.collectedInternalReward
 68}
 69
 70func (d *Deposit) SetCollectedInternalReward(collectedInternalReward int64) {
 71	d.collectedInternalReward = collectedInternalReward
 72}
 73
 74func (d *Deposit) CollectedExternalRewards() *avl.Tree {
 75	return d.collectedExternalRewards
 76}
 77
 78func (d *Deposit) SetCollectedExternalRewards(collectedExternalRewards *avl.Tree) {
 79	d.collectedExternalRewards = collectedExternalRewards
 80}
 81
 82// GetCollectedExternalReward returns the collected external reward for the given incentive ID.
 83// Returns 0 if the incentive ID does not exist.
 84func (d *Deposit) GetCollectedExternalReward(incentiveID string) (int64, bool) {
 85	if d.collectedExternalRewards == nil {
 86		return 0, false
 87	}
 88
 89	value, exists := d.collectedExternalRewards.Get(incentiveID)
 90	if !exists {
 91		return 0, false
 92	}
 93
 94	v, ok := value.(int64)
 95	if !ok {
 96		panic("failed to cast value to int64")
 97	}
 98	return v, true
 99}
100
101func (d *Deposit) SetCollectedExternalReward(incentiveID string, reward int64) {
102	if d.collectedExternalRewards == nil {
103		d.collectedExternalRewards = avl.NewTree()
104	}
105	d.collectedExternalRewards.Set(incentiveID, reward)
106}
107
108func (d *Deposit) ExternalRewardLastCollectTimes() *avl.Tree {
109	return d.externalRewardLastCollectTimes
110}
111
112func (d *Deposit) SetExternalRewardLastCollectTimes(externalRewardLastCollectTimes *avl.Tree) {
113	d.externalRewardLastCollectTimes = externalRewardLastCollectTimes
114}
115
116// GetExternalRewardLastCollectTime returns the last collect time for the given incentive ID.
117// Returns 0 if the incentive ID does not exist.
118func (d *Deposit) GetExternalRewardLastCollectTime(incentiveID string) (int64, bool) {
119	if d.externalRewardLastCollectTimes == nil {
120		return 0, false
121	}
122
123	value, exists := d.externalRewardLastCollectTimes.Get(incentiveID)
124	if !exists {
125		return 0, false
126	}
127
128	v, ok := value.(int64)
129	if !ok {
130		panic("failed to cast value to int64")
131	}
132	return v, true
133}
134
135func (d *Deposit) SetExternalRewardLastCollectTime(incentiveID string, currentTime int64) {
136	if d.externalRewardLastCollectTimes == nil {
137		d.externalRewardLastCollectTimes = avl.NewTree()
138	}
139	d.externalRewardLastCollectTimes.Set(incentiveID, currentTime)
140}
141
142func (d *Deposit) TickLower() int32 {
143	return d.tickLower
144}
145
146func (d *Deposit) SetTickLower(tickLower int32) {
147	d.tickLower = tickLower
148}
149
150func (d *Deposit) TickUpper() int32 {
151	return d.tickUpper
152}
153
154func (d *Deposit) SetTickUpper(tickUpper int32) {
155	d.tickUpper = tickUpper
156}
157
158func (d *Deposit) ExternalIncentiveIds() *avl.Tree {
159	return d.externalIncentiveIds
160}
161
162func (d *Deposit) SetExternalIncentiveIds(externalIncentiveIds *avl.Tree) {
163	d.externalIncentiveIds = externalIncentiveIds
164}
165
166// AddExternalIncentiveId adds an external incentive id to the deposit.
167func (d *Deposit) AddExternalIncentiveId(incentiveId string) {
168	if d.externalIncentiveIds == nil {
169		d.externalIncentiveIds = avl.NewTree()
170	}
171	d.externalIncentiveIds.Set(incentiveId, true)
172}
173
174// HasExternalIncentiveId checks if the deposit has the given external incentive id.
175func (d *Deposit) HasExternalIncentiveId(incentiveId string) bool {
176	if d.externalIncentiveIds == nil {
177		return false
178	}
179	return d.externalIncentiveIds.Has(incentiveId)
180}
181
182// RemoveExternalIncentiveId removes an external incentive id from the deposit.
183func (d *Deposit) RemoveExternalIncentiveId(incentiveId string) {
184	if d.externalIncentiveIds == nil {
185		return
186	}
187	d.externalIncentiveIds.Remove(incentiveId)
188}
189
190// GetExternalIncentiveIdList returns a list of external incentive ids for the deposit.
191func (d *Deposit) GetExternalIncentiveIdList() []string {
192	if d.externalIncentiveIds == nil {
193		return []string{}
194	}
195
196	ids := make([]string, 0, d.externalIncentiveIds.Size())
197	d.externalIncentiveIds.Iterate("", "", func(key string, _ any) bool {
198		ids = append(ids, key)
199		return false
200	})
201	return ids
202}
203
204// IterateExternalIncentiveIds iterates over external incentive IDs without allocating a slice.
205// The callback function receives each incentive ID and should return false to continue iteration,
206// or true to stop early. This method is more memory-efficient than GetExternalIncentiveIdList
207// for cases where you only need to process IDs sequentially.
208func (d *Deposit) IterateExternalIncentiveIds(fn func(incentiveId string) bool) {
209	if d.externalIncentiveIds == nil {
210		return
211	}
212	d.externalIncentiveIds.Iterate("", "", func(key string, _ any) bool {
213		return fn(key)
214	})
215}
216
217func (d *Deposit) Warmups() []Warmup {
218	return d.warmups
219}
220
221func (d *Deposit) SetWarmups(warmups []Warmup) {
222	d.warmups = warmups
223}
224
225func (d *Deposit) LastExternalIncentiveUpdatedAt() int64 {
226	return d.lastExternalIncentiveUpdatedAt
227}
228
229func (d *Deposit) SetLastExternalIncentiveUpdatedAt(timestamp int64) {
230	d.lastExternalIncentiveUpdatedAt = timestamp
231}
232
233// Clone returns a deep copy of the deposit.
234func (d *Deposit) Clone() *Deposit {
235	if d == nil {
236		return nil
237	}
238
239	return &Deposit{
240		warmups:                        cloneWarmups(d.warmups),
241		liquidity:                      d.liquidity.Clone(),
242		targetPoolPath:                 d.targetPoolPath,
243		owner:                          d.owner,
244		stakeTime:                      d.stakeTime,
245		internalRewardLastCollectTime:  d.internalRewardLastCollectTime,
246		collectedInternalReward:        d.collectedInternalReward,
247		collectedExternalRewards:       cloneAvlTree(d.collectedExternalRewards),
248		externalRewardLastCollectTimes: cloneAvlTree(d.externalRewardLastCollectTimes),
249		externalIncentiveIds:           cloneAvlTree(d.externalIncentiveIds),
250		lastExternalIncentiveUpdatedAt: d.lastExternalIncentiveUpdatedAt,
251		tickLower:                      d.tickLower,
252		tickUpper:                      d.tickUpper,
253	}
254}
255
256func NewDeposit(
257	owner address,
258	targetPoolPath string,
259	liquidity *u256.Uint,
260	currentTime int64,
261	tickLower, tickUpper int32,
262	warmups []Warmup,
263) *Deposit {
264	return &Deposit{
265		owner:                          owner,
266		targetPoolPath:                 targetPoolPath,
267		liquidity:                      liquidity,
268		warmups:                        warmups,
269		stakeTime:                      currentTime,
270		tickLower:                      tickLower,
271		tickUpper:                      tickUpper,
272		internalRewardLastCollectTime:  currentTime,
273		externalRewardLastCollectTimes: avl.NewTree(),
274		collectedInternalReward:        0,
275		collectedExternalRewards:       avl.NewTree(),
276		externalIncentiveIds:           avl.NewTree(),
277		lastExternalIncentiveUpdatedAt: 0,
278	}
279}
280
281type Warmup struct {
282	Index          int
283	TimeDuration   int64
284	NextWarmupTime int64 // time when this warmup period ends
285	WarmupRatio    uint64
286}
287
288func (w *Warmup) SetNextWarmupTime(nextWarmupTime int64) {
289	w.NextWarmupTime = nextWarmupTime
290}
291
292func (w *Warmup) SetWarmupRatio(warmupRatio uint64) {
293	w.WarmupRatio = warmupRatio
294}
295
296func (w *Warmup) SetTimeDuration(timeDuration int64) {
297	w.TimeDuration = timeDuration
298}
299
300func DefaultWarmupTemplate() []Warmup {
301	secondsInDay := int64(86400)
302	secondsIn5Days := int64(5 * secondsInDay)
303	secondsIn10Days := int64(10 * secondsInDay)
304	secondsIn30Days := int64(30 * secondsInDay)
305
306	// NextWarmupTime is set to 0 for template.
307	// They will be set by InstantiateWarmup()
308	return []Warmup{
309		{
310			Index:        0,
311			TimeDuration: secondsIn5Days,
312			// NextWarmupTime will be set based on currentTime
313			// NextWarmupTime: currentTime + secondsIn5Days,
314			WarmupRatio: 30,
315		},
316		{
317			Index:        1,
318			TimeDuration: secondsIn10Days,
319			// NextWarmupTime will be set based on currentTime
320			// NextWarmupTime: currentTime + secondsIn10Days,
321			WarmupRatio: 50,
322		},
323		{
324			Index:        2,
325			TimeDuration: secondsIn30Days,
326			// NextWarmupTime will be set based on currentTime
327			// NextWarmupTime: currentTime + secondsIn30Days,
328			WarmupRatio: 70,
329		},
330		{
331			Index:        3,
332			TimeDuration: math.MaxInt64,
333			// NextWarmupTime will be set to math.MaxInt64
334			// NextWarmupTime: math.MaxInt64,
335			WarmupRatio: 100,
336		},
337	}
338}