Skip to content

Commit e8da8bd

Browse files
committed
modify external reward to be indexed by incentive id
1 parent a57e240 commit e8da8bd

6 files changed

+73
-81
lines changed

staker/reward_calculation_canonical_env_test.gno

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ func newExternalIncentiveByHeight(
440440
}
441441
}
442442

443-
func (self *canonicalRewardState) CreateExternalIncentive(targetPoolPath string, rewardToken string, rewardAmount uint64, startTimestamp, endTimestamp, startHeight, endHeight int64, refundee std.Address) {
443+
func (self *canonicalRewardState) CreateExternalIncentive(targetPoolPath string, rewardToken string, rewardAmount uint64, startTimestamp, endTimestamp, startHeight, endHeight int64, refundee std.Address) string {
444444
incentive := newExternalIncentiveByHeight(targetPoolPath, rewardToken, rewardAmount, startTimestamp, endTimestamp, startHeight, endHeight, refundee)
445445

446446
// update canonical state
@@ -458,6 +458,8 @@ func (self *canonicalRewardState) CreateExternalIncentive(targetPoolPath string,
458458

459459
// update global state
460460
self.global.pools.GetOrCreate(targetPoolPath).incentives.create(refundee, incentive)
461+
462+
return incentive.incentiveId
461463
}
462464

463465
func (self *canonicalRewardState) EndExternalIncentive(targetPoolPath string, rewardToken string) {

staker/reward_calculation_canonical_test.gno

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ func TestExternalReward_1(t *testing.T) {
673673
gnousdc := GetPoolPath("gno", "usdc", 3000)
674674
canonical.CreatePool(gnousdc, 1, 200)
675675

676-
canonical.CreateExternalIncentive(gnousdc, "gno", 100000000, 1, 5, 1, 5, std.Address("gno1qyqszqgpqyqszqgpqyqszqgpqyqszqgp"))
676+
incentiveId := canonical.CreateExternalIncentive(gnousdc, "gno", 100000000, 1, 5, 1, 5, std.Address("gno1qyqszqgpqyqszqgpqyqszqgpqyqszqgp"))
677677

678678
err := canonical.StakeToken(
679679
0,
@@ -692,7 +692,7 @@ func TestExternalReward_1(t *testing.T) {
692692

693693
expected := uint64(100000000 / 4) * 30 / 100
694694

695-
canonical.AssertEmulatedExternalRewardOf(uint64(0), "gno", expected)
695+
canonical.AssertEmulatedExternalRewardOf(uint64(0), incentiveId, expected)
696696
}
697697

698698
func TestMultiplePool_1(t *testing.T) {
@@ -830,17 +830,15 @@ func TestMultiplePool_2(t *testing.T) {
830830
canonical.AssertEmulatedRewardOf(0, 0)
831831
canonical.AssertEmulatedRewardOf(1, 0)
832832
canonical.AssertEmulatedRewardOf(2, expected * 20 / 100)
833-
}
834-
835-
func TestMultiplePool_3(t *testing.T) {
836-
canonical := Setup(t)
837-
838-
gnousdc := GetPoolPath("gno", "usdc", 3000)
839-
gnousdc2 := GetPoolPath("gno", "usdc", 10000)
840-
gnousdc3 := GetPoolPath("gno", "usdc", 30000)
841-
canonical.CreatePool(gnousdc, 1, 200)
842-
canonical.CreatePool(gnousdc2, 2, 200)
843-
canonical.CreatePool(gnousdc3, 3, 200)
833+
canonical.ChangePoolTier(gnousdc2, 1)
834+
canonical.MoveTick(gnousdc, 200)
835+
canonical.MoveTick(gnousdc2, 300)
836+
canonical.MoveTick(gnousdc3, 400)
837+
838+
canonical.NextBlock()
839+
canonical.AssertEmulatedRewardOf(0, expected * 40 / 100)
840+
canonical.AssertEmulatedRewardOf(1, expected * 40 / 100)
841+
canonical.AssertEmulatedRewardOf(2, expected * 20 / 100)
844842
}
845843

846844
// Large number of blocks passed

staker/reward_calculation_incentives.gno

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,36 @@ import (
1111
u256 "gno.land/p/gnoswap/uint256"
1212
)
1313

14+
type IncentiveBound struct {
15+
Incentive ExternalIncentive
16+
IsEnter bool
17+
}
18+
1419
// per-pool incentives
1520
type Incentives struct {
1621
byTime *avl.Tree // (startTime, endTime, creator, rewardToken) => ExternalIncentive
1722
byHeight *avl.Tree // (startHeight, endHeight, creator, rewardToken) => ExternalIncentive
1823
byCreator *avl.Tree // (creator, startHeight, endHeight, rewardToken) => ExternalIncentive
1924

20-
// the value map denotes delta of the external incentive per block for the token
21-
delta *UintTree // blockNumber -> map[string]int64
25+
incentiveBound *UintTree // blockNumber -> []IncentiveBound
2226

2327
rewardCache *RewardCacheTree // blockNumber -> map[string]*u256.Uint
2428
lastRewardCacheHeight *uint64
25-
26-
// refund to the refundee
27-
totalPenalty *uint64
28-
claimedPenalty *uint64
2929
}
3030

3131
func NewIncentives(currentHeight uint64) Incentives {
32-
totalPenalty := uint64(0)
33-
claimedPenalty := uint64(0)
34-
3532
return Incentives{
3633
byTime: avl.NewTree(),
3734
byHeight: avl.NewTree(),
3835
byCreator: avl.NewTree(),
3936

40-
delta: NewUintTree(),
37+
incentiveBound: NewUintTree(),
4138

4239
rewardCache: NewRewardCacheTree(),
4340
lastRewardCacheHeight: &currentHeight,
44-
45-
totalPenalty: &totalPenalty,
46-
claimedPenalty: &claimedPenalty,
4741
}
4842
}
4943

50-
func (self *Incentives) claimPenalty() uint64 {
51-
amount := *self.totalPenalty - *self.claimedPenalty
52-
*self.claimedPenalty += amount
53-
return amount
54-
}
55-
5644
func (self *Incentives) Exists(startTime, endTime int64, creator std.Address, rewardToken string) bool {
5745
byTimeId := incentiveIdByTime(uint64(startTime), uint64(endTime), creator, rewardToken)
5846
return self.byTime.Has(byTimeId)
@@ -77,12 +65,12 @@ func (self *Incentives) remove(incentive *ExternalIncentive) {
7765
self.byCreator.Remove(byCreatorId)
7866
}
7967

80-
func (self *Incentives) GetDelta(height uint64) map[string]int64 {
81-
delta, ok := self.delta.Get(height)
68+
func (self *Incentives) GetBound(height uint64) []IncentiveBound {
69+
value, ok := self.incentiveBound.Get(height)
8270
if !ok {
83-
return make(map[string]int64)
71+
return []IncentiveBound{}
8472
}
85-
return delta.(map[string]int64)
73+
return value.([]IncentiveBound)
8674
}
8775

8876
// cacheReward() MUST be called before this function
@@ -112,30 +100,31 @@ func (self *Incentives) create(
112100
self.byHeight.Set(byHeightId, incentive)
113101
self.byCreator.Set(byCreatorId, incentive)
114102

115-
startIncentiveDelta := self.GetDelta(uint64(incentive.startHeight))
116-
startIncentiveDelta[incentive.rewardToken] += int64(incentive.rewardPerBlock)
117-
startHeight := uint64(incentive.startHeight)
118-
self.delta.Set(startHeight, startIncentiveDelta)
119-
120-
println("startIncentiveDelta")
121-
for tokenId, deltaAmount := range startIncentiveDelta {
122-
println(startHeight, tokenId, deltaAmount)
123-
}
103+
startIncentiveBound := self.GetBound(uint64(incentive.startHeight))
104+
startIncentiveBound = append(startIncentiveBound, IncentiveBound{
105+
Incentive: *incentive,
106+
IsEnter: true,
107+
})
108+
self.incentiveBound.Set(uint64(incentive.startHeight), startIncentiveBound)
124109

125110
endHeight := uint64(incentive.endHeight)
126-
endIncentiveDelta := self.GetDelta(endHeight)
127-
endIncentiveDelta[incentive.rewardToken] -= int64(incentive.rewardPerBlock)
128-
self.delta.Set(endHeight, endIncentiveDelta)
111+
endIncentiveBound := self.GetBound(endHeight)
112+
endIncentiveBound = append(endIncentiveBound, IncentiveBound{
113+
Incentive: *incentive,
114+
IsEnter: false,
115+
})
116+
self.incentiveBound.Set(endHeight, endIncentiveBound)
129117

130-
println("endIncentiveDelta")
131-
for tokenId, deltaAmount := range endIncentiveDelta {
132-
println(endHeight, tokenId, deltaAmount)
118+
println("endIncentiveBound")
119+
for _, bound := range endIncentiveBound {
120+
println(bound.Incentive.rewardToken, bound.IsEnter)
133121
}
134122
}
135123

136124
// endHeight MUST be less than or equal to the current block height
137125
func (self *Incentives) cacheRewardPerLiquidityUnit(startHeight, endHeight uint64, stakedLiquidity *u256.Uint) {
138126
currentReward := self.CurrentReward(startHeight)
127+
139128
/*
140129
delta := self.GetDelta(startHeight)
141130
reward := make(map[string]*u256.Uint)
@@ -156,25 +145,24 @@ func (self *Incentives) cacheRewardPerLiquidityUnit(startHeight, endHeight uint6
156145

157146
self.rewardCache.Set(startHeight, reward)
158147
*/
159-
self.delta.Iterate(startHeight, endHeight, func(key uint64, value interface{}) bool {
160-
delta := value.(map[string]int64)
148+
149+
self.incentiveBound.Iterate(startHeight, endHeight, func(key uint64, value interface{}) bool {
150+
bound := value.([]IncentiveBound)
161151
reward := make(map[string]*u256.Uint)
162-
for token, deltaAmount := range delta {
163-
delta := i256.NewInt(deltaAmount)
164-
deltaQ96 := i256.Zero().Mul(delta, _iQ96)
165-
ratio := i256.Zero().Div(deltaQ96, i256.FromUint256(stakedLiquidity))
166-
currentRewardToken, ok := currentReward[token]
167-
if !ok {
168-
currentRewardToken = u256.Zero()
169-
}
170-
deltaApplied := liquidityMathAddDelta(currentRewardToken, ratio)
171-
if deltaApplied.IsZero() {
172-
continue
152+
for incentiveId, ratio := range currentReward {
153+
reward[incentiveId] = ratio
154+
}
155+
for _, bound := range bound {
156+
if bound.IsEnter {
157+
delta := u256.NewUint(bound.Incentive.rewardPerBlock)
158+
deltaQ96 := delta.Mul(delta, q96)
159+
ratio := u256.Zero().Div(deltaQ96, stakedLiquidity)
160+
reward[bound.Incentive.incentiveId] = ratio
161+
} else {
162+
delete(reward, bound.Incentive.incentiveId)
173163
}
174-
reward[token] = deltaApplied
175164
}
176165
self.rewardCache.Set(key, reward)
177-
currentReward = reward
178166
return false
179167
})
180168
*self.lastRewardCacheHeight = endHeight

staker/reward_calculation_pool.gno

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ func (self *ExternalRewardState) Calculate(startHeight, endHeight int64, current
218218
for i := range self.rewards {
219219
rewards[i] = make(map[string]uint64)
220220
penalties[i] = make(map[string]uint64)
221-
for tokenId, reward := range self.rewards[i] {
222-
rewards[i][tokenId] = reward.Uint64()
221+
for incentiveId, reward := range self.rewards[i] {
222+
rewards[i][incentiveId] = reward.Uint64()
223223
}
224-
for tokenId, penalty := range self.penalties[i] {
225-
penalties[i][tokenId] = penalty.Uint64()
224+
for incentiveId, penalty := range self.penalties[i] {
225+
penalties[i][incentiveId] = penalty.Uint64()
226226
}
227227
}
228228

@@ -232,23 +232,23 @@ func (self *ExternalRewardState) Calculate(startHeight, endHeight int64, current
232232
func (self *ExternalRewardState) AccumulateReward(startHeight, endHeight uint64) {
233233
self.pool.incentives.rewardCache.RewardPerInterval(startHeight, endHeight, func(blockNumber uint64, poolRewardI interface{}) {
234234
poolRewardRatios := poolRewardI.(map[string]*u256.Uint)
235-
for tokenId, poolRewardRatio := range poolRewardRatios {
236-
positionReward := u256.Zero().Mul(self.deposit.liquidity, poolRewardRatio)
235+
for incentiveId, rewardRatio := range poolRewardRatios {
236+
positionReward := u256.Zero().Mul(self.deposit.liquidity, rewardRatio)
237237
positionReward = u256.Zero().Mul(positionReward, u256.NewUint(blockNumber))
238-
println("AccumulateReward", blockNumber, tokenId, poolRewardRatio.ToString(), positionReward.ToString())
239-
acc, ok := self.rewards[self.currentWarmup.Index][tokenId]
238+
println("AccumulateReward", blockNumber, incentiveId, rewardRatio.ToString(), positionReward.ToString())
239+
acc, ok := self.rewards[self.currentWarmup.Index][incentiveId]
240240
if !ok {
241241
acc = u256.Zero()
242242
}
243243
acc.Add(acc, positionReward)
244-
self.rewards[self.currentWarmup.Index][tokenId] = acc
244+
self.rewards[self.currentWarmup.Index][incentiveId] = acc
245245
}
246246
})
247247
}
248248

249249
func (self *ExternalRewardState) ApplyWarmup() {
250250
for i, warmup := range self.deposit.warmups {
251-
for tokenId, rewardRatio := range self.rewards[i] {
251+
for incentiveId, rewardRatio := range self.rewards[i] {
252252
if rewardRatio.IsZero() {
253253
continue
254254
}
@@ -262,8 +262,8 @@ func (self *ExternalRewardState) ApplyWarmup() {
262262
penalty = penalty.Div(penalty, u256.NewUint(100))
263263
penalty = penalty.Div(penalty, q96)
264264

265-
self.rewards[i][tokenId] = reward
266-
self.penalties[i][tokenId] = penalty
265+
self.rewards[i][incentiveId] = reward
266+
self.penalties[i][incentiveId] = penalty
267267
}
268268
}
269269
}

staker/reward_calculation_pool_tier.gno

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ func (self *PoolTier) CurrentReward(tier uint64, currentHeight uint64) uint64 {
160160
return reward.(uint64)
161161
}
162162

163+
func (self *PoolTier) createPool(pools *Pools, poolPath string, initialTier uint64, currentHeight uint64) {
164+
_ = pools.GetOrCreate(poolPath)
165+
166+
self.changeTier(currentHeight, poolPath, initialTier)
167+
}
168+
163169
func (self *PoolTier) changeTier(currentHeight uint64, poolPath string, nextTier uint64) {
164170
currentTier := self.CurrentTier(poolPath, currentHeight)
165171
if currentTier == nextTier {

staker/reward_calculation_warmup.gno

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ func DefaultWarmupTemplate(currentHeight int64) []Warmup {
2626
blocksIn10Days := int64(10 * blocksInDay)
2727
blocksIn30Days := int64(30 * blocksInDay)
2828

29-
println(blocksIn5Days, blocksIn10Days, blocksIn30Days)
30-
3129
return []Warmup{
3230
{
3331
Index: 0,

0 commit comments

Comments
 (0)