Skip to content

Commit ac46554

Browse files
committed
external reward tip
1 parent 822661e commit ac46554

10 files changed

+842
-48
lines changed

emission.txt

Lines changed: 772 additions & 0 deletions
Large diffs are not rendered by default.

emission/distribution.gno

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ var (
4444
// - Governance Stakers: 0%
4545
func init() {
4646
distributionBpsPct = avl.NewTree()
47-
distributionBpsPct.Set(strconv.Itoa(LIQUIDITY_STAKER), 7500)
48-
distributionBpsPct.Set(strconv.Itoa(DEVOPS), 2000)
49-
distributionBpsPct.Set(strconv.Itoa(COMMUNITY_POOL), 500)
50-
distributionBpsPct.Set(strconv.Itoa(GOV_STAKER), 0)
47+
distributionBpsPct.Set(strconv.Itoa(LIQUIDITY_STAKER), uint64(7500))
48+
distributionBpsPct.Set(strconv.Itoa(DEVOPS), uint64(2000))
49+
distributionBpsPct.Set(strconv.Itoa(COMMUNITY_POOL), uint64(500))
50+
distributionBpsPct.Set(strconv.Itoa(GOV_STAKER), uint64(0))
5151

52-
addStakerPerBlockMintUpdate(uint64(std.GetHeight()), gns.GetCurrentEmission() * 7500)
52+
addStakerPerBlockMintUpdate(uint64(std.GetHeight()), gns.GetCurrentEmission() * uint64(7500))
5353
}
5454

5555
var (
@@ -254,8 +254,8 @@ func distributeToTarget(amount uint64) uint64 {
254254
))
255255
}
256256

257-
pct := iPct.(int)
258-
distAmount := calculateAmount(amount, uint64(pct))
257+
pct := iPct.(uint64)
258+
distAmount := calculateAmount(amount, pct)
259259
totalSent += distAmount
260260

261261
transferToTarget(targetInt, distAmount)

emission/emission.gno

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,24 @@ var (
2222
func MintAndDistributeGns() uint64 {
2323
assertOnlyNotHalted()
2424

25-
println("AAA")
2625
currentHeight := std.GetHeight()
2726
lastMintedHeight := gns.GetLastMintedHeight()
2827
if lastMintedHeight >= currentHeight {
2928
// Skip if we've already minted tokens at this height
3029
return 0
3130
}
32-
println("BBB")
33-
3431
// Mint new tokens and add any leftover amounts from previous distribution
3532
mintedEmissionRewardAmount := gns.MintGns(a2u(consts.EMISSION_ADDR))
3633
if hasLeftGNSAmount() {
3734
mintedEmissionRewardAmount += GetLeftGNSAmount()
3835
setLeftGNSAmount(0)
3936
}
40-
println("CCC")
4137
// Distribute tokens and track any undistributed amount
4238
distributedGNSAmount := distributeToTarget(mintedEmissionRewardAmount)
43-
println("DDD")
4439
if mintedEmissionRewardAmount != distributedGNSAmount {
4540
setLeftGNSAmount(mintedEmissionRewardAmount - distributedGNSAmount)
4641
}
4742

48-
println("DDD")
4943
// Emit event with distribution details
5044
prevAddr, prevPkgPath := getPrevAsString()
5145
std.Emit(
@@ -59,10 +53,8 @@ func MintAndDistributeGns() uint64 {
5953
"internal_totalSupply", ufmt.Sprintf("%d", gns.TotalSupply()),
6054
)
6155

62-
println("EEE")
6356
setLastExecutedHeight(currentHeight)
6457

65-
println("FFF")
6658
return distributedGNSAmount
6759
}
6860

staker/calculate_pool_position_reward.gno

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ type CalcPositionRewardParam struct {
9494
}
9595

9696
func CalcPositionReward(param CalcPositionRewardParam) []Reward {
97-
println("===== CalcPositionReward", param.TokenId)
98-
9997
// cache per-pool rewards in the internal incentive(tiers)
10098
param.PoolTier.cacheReward(param.CurrentHeight, param.Pools)
10199

@@ -123,7 +121,6 @@ func CalcPositionReward(param CalcPositionRewardParam) []Reward {
123121
// XXX: Tick ordering code, memoing for future
124122

125123
lastCollectHeight := deposit.lastCollectHeight
126-
println("===== lastCollectHeight", param.TokenId, lastCollectHeight)
127124

128125
initialUpperCross := upperTick.previousCross(lastCollectHeight)
129126
initialLowerCross := lowerTick.previousCross(lastCollectHeight)

staker/reward_calculation_incentives.gno

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ type IncentiveBound struct {
1515
IsEnter bool
1616
}
1717

18+
type IncentiveRewardEntry struct {
19+
ActiveIncentives []string
20+
TotalStakedLiquidity *u256.Uint
21+
}
22+
1823
// per-pool incentives
1924
type Incentives struct {
2025
byTime *avl.Tree // (startTime, endTime, creator, rewardToken) => ExternalIncentive
@@ -23,7 +28,9 @@ type Incentives struct {
2328

2429
incentiveBound *UintTree // blockNumber -> []IncentiveBound
2530

26-
rewardCache *RewardCacheTree // blockNumber -> map[string]*u256.Uint
31+
currentIncentives []string
32+
33+
rewardCache *RewardCacheTree // blockNumber -> IncentiveRewardEntry
2734
lastRewardCacheHeight *uint64
2835
}
2936

@@ -37,6 +44,8 @@ func NewIncentives(currentHeight uint64) Incentives {
3744

3845
rewardCache: NewRewardCacheTree(),
3946
lastRewardCacheHeight: &currentHeight,
47+
48+
currentIncentives: []string{},
4049
}
4150
}
4251

@@ -81,12 +90,15 @@ func (self *Incentives) GetBound(height uint64) []IncentiveBound {
8190
}
8291

8392
// cacheReward() MUST be called before this function
84-
func (self *Incentives) CurrentReward(currentHeight uint64) map[string]*u256.Uint {
93+
func (self *Incentives) CurrentReward(currentHeight uint64) IncentiveRewardEntry {
8594
value := self.rewardCache.CurrentReward(currentHeight)
8695
if value == nil {
87-
return make(map[string]*u256.Uint)
96+
return IncentiveRewardEntry{
97+
ActiveIncentives: []string{},
98+
TotalStakedLiquidity: u256.Zero(),
99+
}
88100
}
89-
return value.(map[string]*u256.Uint)
101+
return value.(IncentiveRewardEntry)
90102
}
91103

92104
func (self *Incentives) create(
@@ -129,22 +141,35 @@ func (self *Incentives) cacheRewardPerLiquidityUnit(startHeight, endHeight uint6
129141

130142
self.incentiveBound.Iterate(startHeight, endHeight, func(key uint64, value interface{}) bool {
131143
bound := value.([]IncentiveBound)
132-
reward := make(map[string]*u256.Uint)
133-
for incentiveId, ratio := range currentReward {
134-
reward[incentiveId] = ratio
144+
reward := IncentiveRewardEntry{
145+
ActiveIncentives: []string{},
146+
TotalStakedLiquidity: currentReward.TotalStakedLiquidity.Clone(),
135147
}
148+
copy(reward.ActiveIncentives, currentReward.ActiveIncentives)
136149
for _, bound := range bound {
137150
if bound.IsEnter {
138-
delta := u256.NewUint(bound.Incentive.rewardPerBlock)
139-
deltaQ192 := delta.Mul(delta, q192)
140-
ratio := u256.Zero().Div(deltaQ192, stakedLiquidity)
141-
reward[bound.Incentive.incentiveId] = ratio
151+
reward.ActiveIncentives = append(reward.ActiveIncentives, bound.Incentive.incentiveId)
142152
} else {
143-
delete(reward, bound.Incentive.incentiveId)
153+
for i, incentiveId := range reward.ActiveIncentives {
154+
if incentiveId == bound.Incentive.incentiveId {
155+
reward.ActiveIncentives = append(reward.ActiveIncentives[:i], reward.ActiveIncentives[i+1:]...)
156+
break
157+
}
158+
}
144159
}
145160
}
146161
self.rewardCache.Set(key, reward)
147162
return false
148163
})
149164
*self.lastRewardCacheHeight = endHeight
150-
}
165+
}
166+
167+
func (self *Incentives) updateRewardByLiquidityChange(currentHeight uint64, liquidity *u256.Uint) {
168+
entry := IncentiveRewardEntry{
169+
ActiveIncentives: []string{},
170+
TotalStakedLiquidity: liquidity.Clone(),
171+
}
172+
copy(entry.ActiveIncentives, self.currentIncentives)
173+
174+
self.rewardCache.Set(currentHeight, entry)
175+
}

staker/reward_calculation_pool.gno

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ type Pool struct {
7171
lastUnclaimableHeight *uint64
7272
unclaimableAcc *uint64
7373

74-
tierReward *uint64 // per liquidity, (internal reward / total staked liquidity) * Q192
75-
tierRewardTotal *uint64 // total internal reward, used for unclaimable reward calculation
74+
tierRewardTotal *uint64 // current total internal reward per block, used for unclaimable reward calculation
7675

7776
rewardCache *RewardCacheTree // blockNumber -> *u256.Uint
7877
lastRewardCacheHeight *uint64
@@ -84,15 +83,13 @@ type Pool struct {
8483

8584
func NewPool(poolPath string, currentHeight uint64) *Pool {
8685
unclaimableAcc := uint64(0)
87-
tierReward := uint64(0)
8886
tierRewardTotal := uint64(0)
8987

9088
return &Pool{
9189
poolPath: poolPath,
9290
stakedLiquidity: NewUintTree(),
9391
lastUnclaimableHeight: &currentHeight,
9492
unclaimableAcc: &unclaimableAcc,
95-
tierReward: &tierReward,
9693
tierRewardTotal: &tierRewardTotal,
9794
rewardCache: NewRewardCacheTree(),
9895
lastRewardCacheHeight: &currentHeight,
@@ -129,6 +126,8 @@ func (self *Pool) updateRewardByLiquidityChange(currentTierReward uint64, curren
129126
ratio = u256.Zero().Mul(ratio, q192)
130127
ratio = u256.Zero().Div(ratio, liquidity)
131128
self.rewardCache.Set(currentHeight, ratio)
129+
130+
self.incentives.updateRewardByLiquidityChange(currentHeight, liquidity)
132131
}
133132

134133
func (self *Pool) cacheRewardPerLiquidityUnit(startHeight, endHeight uint64, currentTierReward uint64) {
@@ -176,6 +175,11 @@ func (self *Pool) cacheInternalReward(currentHeight uint64, emissionUpdate en.Em
176175
}
177176

178177
func (self *Pool) cacheExternalReward(endHeight uint64) {
178+
self.stakedLiquidity.Iterate(0, 9999999, func(key uint64, value interface{}) bool {
179+
println("(((cacheExternalReward)))", key, value.(*u256.Uint).ToString())
180+
return false
181+
})
182+
179183
startHeight := *self.incentives.lastRewardCacheHeight
180184
currentStakedLiquidity := self.CurrentStakedLiquidity(startHeight)
181185

@@ -187,6 +191,11 @@ func (self *Pool) cacheExternalReward(endHeight uint64) {
187191
})
188192

189193
self.incentives.cacheRewardPerLiquidityUnit(startHeight, endHeight, currentStakedLiquidity)
194+
195+
self.incentives.rewardCache.Iterate(0, 9999999, func(key uint64, value interface{}) bool {
196+
println("cacheExternalReward", key, value)
197+
return false
198+
})
190199
}
191200

192201
type ExternalRewardState struct {
@@ -501,7 +510,7 @@ func (self *Pool) processUnclaimableReward(poolTier *PoolTier, endHeight uint64)
501510
internalUnClaimable := *self.unclaimableAcc
502511
*self.unclaimableAcc = 0
503512
externalUnClaimable := make(map[string]uint64)
504-
for incentiveId := range self.incentives.CurrentReward(startHeight) {
513+
for _, incentiveId := range self.incentives.CurrentReward(startHeight).ActiveIncentives {
505514
externalUnClaimable[incentiveId] = self.UnclaimableExternalReward(incentiveId, startHeight, endHeight)
506515
}
507516
self.lastUnclaimableHeight = &endHeight

staker/reward_calculation_pool_tier.gno

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,18 @@ func TierRatioFromCounts(tier1Count, tier2Count, tier3Count uint64) *TierRatio {
6363
// RewardDenominator[i] = TierCount[i] * TierRatioLCM / (TierRatio[i] * 100)
6464
// TierReward[i] = Emission * TierRatioLCM / RewardDenominator[i] / 100
6565
func (self *TierRatio) IntoRewardDenominators(counts []uint64) []uint64 {
66-
println("IntoRewardDenominators", self, counts)
6766
result := make([]uint64, 4)
6867
for i := 1; i < 4; i++ {
6968
if counts[i] == 0 {
7069
result[i] = 0
7170
} else {
72-
println("IntoRewardDenominators", i, counts[i], self.Get(uint64(i)))
7371
result[i] = counts[i] * TierRatioLCM / (self.Get(uint64(i)))
7472
}
7573
}
76-
println("IntoRewardDenominators result", result)
7774
return result
7875
}
7976

8077
func ApplyDenominator(emission uint64, denominator uint64) uint64 {
81-
println(">>>> ApplyDenominator", emission, TierRatioLCM, denominator)
8278
if denominator == 0 {
8379
return 0
8480
}
@@ -236,8 +232,6 @@ func (self *PoolTier) cacheReward(currentHeight uint64, pools *Pools) {
236232
// - msPerBlock is changed
237233
// - emission distribution ratio is changed
238234
// during the period of PoolTier.lastRewardCacheHeight to currentHeight
239-
println("cacheReward", *self.lastRewardCacheHeight, currentHeight)
240-
println("emissionUpdate", self.emissionUpdate(*self.lastRewardCacheHeight, currentHeight))
241235

242236
emissionUpdate := self.emissionUpdate(*self.lastRewardCacheHeight, currentHeight)
243237
if emissionUpdate.IsEmpty() {
@@ -246,11 +240,10 @@ func (self *PoolTier) cacheReward(currentHeight uint64, pools *Pools) {
246240

247241
rewardDenominators := self.tierRatio.IntoRewardDenominators(self.CurrentCounts())
248242

249-
println(">>>> rewardDenominators", rewardDenominators)
250243
self.membership.Iterate("", "", func(key string, value interface{}) bool {
251244
pool, ok := pools.Get(key)
252245
if !ok {
253-
panic("cacheReward: pool not found")
246+
panic("pool not found")
254247
}
255248

256249
pool.cacheInternalReward(currentHeight, emissionUpdate, rewardDenominators[value.(uint64)])

staker/reward_calculation_tick.gno

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ func TickCrossHook(pools *Pools, height func() int64) func(poolPath string, tick
330330
tick.updateCross(blockNumber, zeroForOne)
331331

332332
liquidityInRangeDelta := tick.stakedLiquidityDelta
333+
if liquidityInRangeDelta.Sign() == 0 {
334+
return
335+
}
336+
333337
if zeroForOne {
334338
liquidityInRangeDelta = i256.Zero().Neg(liquidityInRangeDelta)
335339
}
@@ -344,11 +348,13 @@ func TickCrossHook(pools *Pools, height func() int64) func(poolPath string, tick
344348
if stakedLiquidity.Sign() == 1 {
345349
// StakedLiquidity moved from positive to zero, start unclaimable period
346350
pool.startInternalUnclaimablePeriod(blockNumber)
351+
pool.startExternalUnclaimablePeriod(blockNumber)
347352
}
348353
case 1:
349354
if stakedLiquidity.Sign() == 0 {
350355
// StakedLiquidity moved from zero to positive, end unclaimable period
351356
pool.endInternalUnclaimablePeriod(blockNumber)
357+
pool.endExternalUnclaimablePeriod(blockNumber)
352358
}
353359
}
354360

staker/reward_calculation_types.gno

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,13 @@ type RewardCalculationFunc = func(blockNumbers uint64, poolReward interface{})
169169
func (self *RewardCacheTree) RewardPerInterval(startHeight, endHeight uint64, f RewardCalculationFunc) {
170170
currentPoolReward := self.CurrentReward(startHeight)
171171
currentHeight := startHeight
172-
println("RewardPerInterval 0:", startHeight, endHeight, currentPoolReward)
173172
self.Iterate(startHeight, endHeight, func(height uint64, poolReward interface{}) bool {
174-
println("RewardPerInterval 1:", height, currentHeight, poolReward, currentPoolReward)
175173
f(height-currentHeight, currentPoolReward)
176174
currentHeight = height
177175
currentPoolReward = poolReward
178176
return false
179177
})
180178
if endHeight > currentHeight {
181-
println("RewardPerInterval 2:", endHeight, currentHeight, currentPoolReward)
182179
f(endHeight-currentHeight, currentPoolReward)
183180
}
184181
}

staker/staker.gno

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,5 +649,8 @@ func getTokenPairBalanceFromPosition(poolPath string, tokenId uint64) (string, s
649649
func getTickOf(tokenId uint64) (int32, int32) {
650650
tickLower := pn.PositionGetPositionTickLower(tokenId)
651651
tickUpper := pn.PositionGetPositionTickUpper(tokenId)
652-
return tickLower, tickUpper
652+
if tickUpper < tickLower {
653+
panic(ufmt.Sprintf("tickUpper(%d) is less than tickLower(%d)", tickUpper.id, tickLower.id))
654+
}
655+
return tickLower.id, tickUpper.id
653656
}

0 commit comments

Comments
 (0)