@@ -59,6 +59,7 @@ type Pool struct {
59
59
// conceptually equal with Pool.liquidity but only for the staked positions
60
60
// updated each time when the pool crosses a staked tick
61
61
stakedLiquidity *UintTree // blockNumber -> *u256.Uint
62
+ lastUnclaimableHeight *uint64
62
63
63
64
// cache of the internal reward per liquidity for each pool in tier
64
65
// value: (internal reward / total staked liquidity) * Q192
@@ -74,6 +75,7 @@ func NewPool(poolPath string, currentHeight uint64) *Pool {
74
75
return &Pool{
75
76
poolPath: poolPath,
76
77
stakedLiquidity: NewUintTree(),
78
+ lastUnclaimableHeight: ¤tHeight,
77
79
rewardCache: NewRewardCacheTree(),
78
80
lastRewardCacheHeight: ¤tHeight,
79
81
incentives: NewIncentives(currentHeight),
@@ -211,7 +213,10 @@ func (self *ExternalRewardState) Calculate(startHeight, endHeight int64, current
211
213
212
214
func (self *ExternalRewardState) AccumulateReward(startHeight, endHeight uint64) {
213
215
self.pool.incentives.rewardCache.RewardPerInterval(startHeight, endHeight, func(blockNumber uint64, poolRewardI interface{}) {
214
- poolRewardRatios := poolRewardI.(map[string]*u256.Uint)
216
+ poolRewardRatios := map[string]*u256.Uint{}
217
+ if poolRewardI != nil {
218
+ poolRewardRatios = poolRewardI.(map[string]*u256.Uint)
219
+ }
215
220
for incentiveId, rewardRatio := range poolRewardRatios {
216
221
positionReward := u256.Zero().Mul(self.deposit.liquidity, rewardRatio)
217
222
positionReward = u256.Zero().Mul(positionReward, u256.NewUint(blockNumber))
@@ -401,6 +406,50 @@ func (self *Pool) modifyDeposit(tokenId uint64, liquidity *i256.Int, currentHeig
401
406
self.stakedLiquidity.Set(currentHeight, liquidityMathAddDelta(lastStakedLiquidity, liquidity))
402
407
}
403
408
409
+ func (self *Pool) processUnclaimableInternalReward(poolTier *PoolTier, endHeight uint64) uint64 {
410
+ startHeight := *self.lastUnclaimableHeight
411
+ unclaimable := self.UnclaimableInternalReward(poolTier, startHeight, endHeight)
412
+ self.lastUnclaimableHeight = &endHeight
413
+ return unclaimable
414
+ }
415
+
416
+ func (self *Pool) UnclaimableInternalReward(poolTier *PoolTier, startHeight, endHeight uint64) uint64 {
417
+ tierRewardHeights, tierRewardUpdates := poolTier.TierRewardUpdates(self.poolPath, startHeight, endHeight)
418
+
419
+ currentTierReward := tierRewardUpdates[0]
420
+
421
+ unclaimable := uint64(0)
422
+
423
+ currentStakedLiquidity := self.CurrentStakedLiquidity(startHeight)
424
+
425
+ for i := 1; i < len(tierRewardHeights); i++ {
426
+ endHeight := tierRewardHeights[i]
427
+
428
+ currentStakedLiquidity = self.CurrentStakedLiquidity(startHeight)
429
+ self.stakedLiquidity.Iterate(startHeight, endHeight, func(height uint64, value interface{}) bool {
430
+ if currentStakedLiquidity.IsZero() {
431
+ unclaimable += currentTierReward * (height - startHeight)
432
+ }
433
+ startHeight = height
434
+ currentStakedLiquidity = value.(*u256.Uint)
435
+ return false
436
+ })
437
+
438
+ if currentStakedLiquidity.IsZero() {
439
+ unclaimable += currentTierReward * (endHeight - startHeight)
440
+ }
441
+
442
+ startHeight = endHeight
443
+ currentTierReward = tierRewardUpdates[i]
444
+ }
445
+
446
+ if currentStakedLiquidity.IsZero() {
447
+ unclaimable += currentTierReward * (endHeight - startHeight)
448
+ }
449
+
450
+ return unclaimable
451
+ }
452
+
404
453
// ============================================
405
454
// API/helpers
406
455
// ============================================
0 commit comments