Skip to content

Commit 62531b3

Browse files
committed
rewrite pooltier logic
1 parent d8330fe commit 62531b3

16 files changed

+492
-596
lines changed

staker/__TEST_staker_emission_and_external_incentive_test.gno

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func TestStakerWithEmissionAmount(t *testing.T) {
3434
testStakeToken03(t)
3535
testSameHeightCalculation(t)
3636
testCollectReward01(t)
37-
testUnstakeToken01(t)
38-
testExternalIncentiveReward(t)
37+
//testUnstakeToken01(t)
38+
//testExternalIncentiveReward(t)
3939
}
4040

4141
func testInit(t *testing.T) {
@@ -45,6 +45,7 @@ func testInit(t *testing.T) {
4545
// init pool tiers
4646
// tier 1
4747
// deletePoolTier(t, MUST_EXISTS_IN_TIER_1)
48+
println("GENESIS", std.GetHeight())
4849
addPoolTier(t, `gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:500`, 1)
4950
std.TestSkipHeights(1)
5051

@@ -121,7 +122,7 @@ func testPositionMintPos01Tier01(t *testing.T) {
121122
"gno.land/r/gnoswap/v1/gns", // token0
122123
"gno.land/r/demo/wugnot", // token1
123124
fee3000, // fee
124-
int32(0), // tickLower
125+
int32(-60), // tickLower
125126
int32(60), // tickUpper
126127
"1000", // amount0Desired
127128
"1000", // amount1Desired
@@ -141,7 +142,7 @@ func testPositionMintPos01Tier01(t *testing.T) {
141142
uassert.Equal(t, uint64(1), gnsBalance(consts.EMISSION_ADDR))
142143
uassert.Equal(t, uint64(1), lpTokenId)
143144
uassert.Equal(t, gnft.MustOwnerOf(tid(lpTokenId)), users.Resolve(admin))
144-
uassert.Equal(t, amount0, "0")
145+
uassert.Equal(t, amount0, "1000")
145146
uassert.Equal(t, amount1, "1000")
146147

147148
std.TestSkipHeights(1)
@@ -311,6 +312,7 @@ func testStakeToken01(t *testing.T) {
311312
func testStakeToken02(t *testing.T) {
312313
t.Run("stake token 02", func(t *testing.T) {
313314
std.TestSetRealm(adminRealm)
315+
println(">>>>>>>>> StakeToken02", "height", std.GetHeight(), " duration : ", std.GetHeight()-123)
314316
StakeToken(2) // GNFT tokenId
315317

316318
uassert.Equal(t, consts.STAKER_ADDR, gnft.MustOwnerOf(tid(2))) // staker
@@ -398,8 +400,11 @@ func testCollectReward01(t *testing.T) {
398400
oneBlockDevOpsAmount := uint64(3567351)
399401
externalInecntiveDeposit := uint64(1000000000)
400402

403+
println("1")
401404
r1, p1 := CollectReward(1, false)
405+
println("2")
402406
r2, p2 := CollectReward(2, false)
407+
println("3")
403408
r3, p3 := CollectReward(3, false)
404409

405410
println("r1", r1)
@@ -434,24 +439,34 @@ func testCollectReward01(t *testing.T) {
434439
leftAmount := uint64(1)
435440
expectedPoolAmount := token2Amount + token2Penalty + token3Amount + token3Penalty + leftAmount
436441

442+
println("A")
437443
rewardForUser := uint64(1884096693)
438444
rewardForPenalty := uint64(807470014)
439445
rewardFee := rewardForUser * 100 / 10000
446+
println("1")
440447
uassert.Equal(t, uint64(18840966), rewardFee)
441448
rewardForUserWithFee := rewardForUser - rewardFee
449+
println("2")
442450
uassert.Equal(t, uint64(1865255727), rewardForUserWithFee)
451+
println("3")
443452
uassert.Equal(t, rewardForUserWithFee, gnsBalance(consts.ADMIN)-beforeGNSForAdmin)
444453

445454
prevGNSForCommunityPool := uint64(3204195117) + uint64(1426940)
446455
currGNSForCommunityPool := prevGNSForCommunityPool + rewardForPenalty
456+
println("4")
447457
uassert.Equal(t, currGNSForCommunityPool, gnsBalance(consts.COMMUNITY_POOL_ADDR)) // 4013092071
448458

449459
prevGNSForStaker := uint64(3686215680)
450460
currentGNSForStaker := prevGNSForStaker + uint64(21404109) - rewardForUser - rewardForPenalty
461+
println("5")
451462
uassert.Equal(t, currentGNSForStaker, gnsBalance(consts.STAKER_ADDR)) // 1016053082
463+
println("6")
452464
uassert.Equal(t, uint64(1472602698)+uint64(5707762), gnsBalance(consts.DEV_OPS)) // 1478310460
465+
println("7")
453466
uassert.Equal(t, uint64(200000000)+rewardFee, gnsBalance(consts.PROTOCOL_FEE_ADDR)) // 218840966
467+
println("8")
454468
uassert.Equal(t, uint64(100007363013496)+uint64(28538812), gns.TotalSupply()) // 100007391552308
469+
println("9")
455470
uassert.Equal(t, uint64(2), gnsBalance(consts.EMISSION_ADDR)) // 2
456471

457472
std.TestSkipHeights(1)

staker/_helper_test.gno

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -444,17 +444,17 @@ func burnAllNFT(t *testing.T) {
444444
func deletePoolTier(t *testing.T, poolPath string) {
445445
t.Helper()
446446
if poolTier != nil {
447-
poolTier.changeTier(uint64(std.GetHeight()), poolPath, 0)
447+
poolTier.changeTier(uint64(std.GetHeight()), pools, poolPath, 0)
448448
}
449449
}
450450

451451
func addPoolTier(t *testing.T, poolPath string, tier uint64) {
452452
t.Helper()
453453
if poolTier != nil {
454-
poolTier.changeTier(uint64(std.GetHeight()), poolPath, tier)
455454
if pools != nil {
456455
pools.GetOrCreate(poolPath)
457456
}
457+
poolTier.changeTier(uint64(std.GetHeight()), pools, poolPath, tier)
458458
}
459459
}
460460

@@ -463,9 +463,10 @@ func changeWarmup(t *testing.T, index int, blockDuration int64) {
463463
}
464464

465465
func getNumPoolTiers(t *testing.T) (uint64, uint64, uint64) {
466-
tier1Num := poolTier.count[1].tree.Size()
467-
tier2Num := poolTier.count[2].tree.Size()
468-
tier3Num := poolTier.count[3].tree.Size()
466+
counts := poolTier.CurrentCounts()
467+
tier1Num := counts[1]
468+
tier2Num := counts[2]
469+
tier3Num := counts[3]
469470

470471
return uint64(tier1Num), uint64(tier2Num), uint64(tier3Num)
471472
}
@@ -538,7 +539,7 @@ func getPrintInfo(t *testing.T) string {
538539

539540
poolTiers := make(map[string]uint64)
540541
pools.tree.Iterate("", "", func(poolPath string, iPool interface{}) bool {
541-
poolTier := poolTier.CurrentTier(poolPath, uint64(std.GetHeight()))
542+
poolTier := poolTier.CurrentTier(poolPath)
542543
poolTiers[poolPath] = poolTier
543544
return false
544545
})
@@ -647,7 +648,7 @@ func makePoolsNode(t *testing.T, emissionPool []ApiEmissionDebugPool) []*json.No
647648

648649
poolTiers := make(map[string]uint64)
649650
pools.tree.Iterate("", "", func(poolPath string, iPool interface{}) bool {
650-
poolTier := poolTier.CurrentTier(poolPath, uint64(std.GetHeight()))
651+
poolTier := poolTier.CurrentTier(poolPath)
651652
poolTiers[poolPath] = poolTier
652653
return false
653654
})

staker/calculate_pool_position_reward.gno

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package staker
33
import (
44
"gno.land/r/gnoswap/v1/consts"
55
"gno.land/r/gnoswap/v1/gns"
6+
en "gno.land/r/gnoswap/v1/emission"
67

78
u256 "gno.land/p/gnoswap/uint256"
89
)
@@ -25,49 +26,51 @@ type Reward struct {
2526
}
2627

2728
func calcPositionRewardByWarmups(currentHeight uint64, tokenId uint64) []Reward {
28-
deposit := deposits.Get(tokenId)
29-
emissionUpdateHeights, emissionUpdates := gns.EmissionUpdates(deposit.lastCollectHeight, currentHeight)
30-
internalRewards, internalPenalties, externalRewards, externalPenalties := CalcPositionReward(currentHeight, tokenId, deposits, pools, poolTier, emissionUpdateHeights, emissionUpdates)
29+
rewards := CalcPositionReward(CalcPositionRewardParam{
30+
CurrentHeight: currentHeight,
31+
Deposits: deposits,
32+
Pools: pools,
33+
PoolTier: poolTier,
34+
TokenId: tokenId,
35+
})
3136

32-
rewards := make([]Reward, len(internalRewards))
33-
for i := range internalRewards {
34-
rewards[i] = Reward{}
35-
rewards[i].Internal = internalRewards[i]
36-
rewards[i].InternalPenalty = internalPenalties[i]
37-
if len(externalRewards) > i {
38-
rewards[i].External = externalRewards[i]
39-
rewards[i].ExternalPenalty = externalPenalties[i]
40-
}
41-
}
4237
return rewards
4338
}
4439

4540
func calcPositionReward(currentHeight uint64, tokenId uint64) Reward {
46-
deposit := deposits.Get(tokenId)
47-
emissionUpdateHeights, emissionUpdates := gns.EmissionUpdates(deposit.lastCollectHeight, currentHeight)
48-
internalRewards, internalPenalties, externalRewards, externalPenalties := CalcPositionReward(currentHeight, tokenId, deposits, pools, poolTier, emissionUpdateHeights, emissionUpdates)
41+
rewards := CalcPositionReward(CalcPositionRewardParam{
42+
CurrentHeight: currentHeight,
43+
Deposits: deposits,
44+
Pools: pools,
45+
PoolTier: poolTier,
46+
TokenId: tokenId,
47+
})
4948

5049
internal := uint64(0)
51-
for _, reward := range internalRewards {
52-
internal += reward
50+
for _, reward := range rewards {
51+
internal += reward.Internal
5352
}
5453

5554
internalPenalty := uint64(0)
56-
for _, penalty := range internalPenalties {
57-
internalPenalty += penalty
55+
for _, reward := range rewards {
56+
internalPenalty += reward.InternalPenalty
5857
}
5958

6059
externalReward := make(map[string]uint64)
61-
for _, external := range externalRewards {
62-
for incentive, reward := range external {
63-
externalReward[incentive] += reward
60+
for _, reward := range rewards {
61+
if reward.External != nil {
62+
for incentive, reward := range reward.External {
63+
externalReward[incentive] += reward
64+
}
6465
}
6566
}
6667

6768
externalPenalty := make(map[string]uint64)
68-
for _, external := range externalPenalties {
69-
for incentive, penalty := range external {
70-
externalPenalty[incentive] += penalty
69+
for _, reward := range rewards {
70+
if reward.ExternalPenalty != nil {
71+
for incentive, penalty := range reward.ExternalPenalty {
72+
externalPenalty[incentive] += penalty
73+
}
7174
}
7275
}
7376

@@ -79,41 +82,74 @@ func calcPositionReward(currentHeight uint64, tokenId uint64) Reward {
7982
}
8083
}
8184

82-
func CalcPositionReward(currentHeight uint64, tokenId uint64, deposits *Deposits, pools *Pools, poolTier *PoolTier, emissionUpdateHeights []uint64, emissionUpdates []uint64) ([]uint64, []uint64, []map[string]uint64, []map[string]uint64) {
83-
// cache per-tier and per-pool rewards
84-
poolTier.cacheReward(currentHeight, emissionUpdateHeights, emissionUpdates)
85+
type CalcPositionRewardParam struct {
86+
// Environmental variables
87+
CurrentHeight uint64
88+
Deposits *Deposits
89+
Pools *Pools
90+
PoolTier *PoolTier
8591

86-
deposit := deposits.Get(tokenId)
92+
// Position variables
93+
TokenId uint64
94+
}
95+
96+
func CalcPositionReward(param CalcPositionRewardParam) []Reward {
97+
println("===== CalcPositionReward", param.TokenId)
98+
99+
// cache per-pool rewards in the internal incentive(tiers)
100+
param.PoolTier.cacheReward(param.CurrentHeight, param.Pools)
101+
102+
deposit := param.Deposits.Get(param.TokenId)
87103
poolPath := deposit.targetPoolPath
88104

89-
pool, ok := pools.Get(poolPath)
105+
pool, ok := param.Pools.Get(poolPath)
90106
if !ok {
91-
pool = NewPool(poolPath, currentHeight)
92-
pools.Set(poolPath, pool)
107+
pool = NewPool(poolPath, param.CurrentHeight)
108+
param.Pools.Set(poolPath, pool)
93109
}
94110

95-
pool.cacheInternalReward(poolTier, currentHeight)
96-
97-
pool.cacheExternalReward(currentHeight)
98-
111+
// cacheInternalReward is called by poolTier.cacheReward
112+
pool.cacheExternalReward(param.CurrentHeight)
99113
// eligible(in-range) intervals for a position
100-
upperTick := pool.ticks.Get(deposit.tickUpper)
101-
lowerTick := pool.ticks.Get(deposit.tickLower)
114+
// XXX: Tick ordering code, memoing for future
115+
tickUpper := deposit.tickUpper
116+
tickLower := deposit.tickLower
117+
token0, token1, _ := poolPathDivide(poolPath)
118+
if token1 < token0 {
119+
tickUpper, tickLower = -tickLower, -tickUpper
120+
}
121+
upperTick := pool.ticks.Get(tickUpper)
122+
lowerTick := pool.ticks.Get(tickLower)
123+
// XXX: Tick ordering code, memoing for future
102124

103125
lastCollectHeight := deposit.lastCollectHeight
126+
println("===== lastCollectHeight", param.TokenId, lastCollectHeight)
104127

105128
initialUpperCross := upperTick.previousCross(lastCollectHeight)
106129
initialLowerCross := lowerTick.previousCross(lastCollectHeight)
107130
currentlyInRange := initialUpperCross && !initialLowerCross
108131

109-
tickUpperCrosses := upperTick.crossInfo(lastCollectHeight, currentHeight)
110-
tickLowerCrosses := lowerTick.crossInfo(lastCollectHeight, currentHeight)
132+
tickUpperCrosses := upperTick.crossInfo(lastCollectHeight, param.CurrentHeight)
133+
tickLowerCrosses := lowerTick.crossInfo(lastCollectHeight, param.CurrentHeight)
111134

112-
internalRewards, internalPenalties := pool.InternalRewardOf(deposit).Calculate(int64(lastCollectHeight), int64(currentHeight), currentlyInRange, tickUpperCrosses, tickLowerCrosses)
135+
internalRewards, internalPenalties := pool.InternalRewardOf(deposit).Calculate(int64(lastCollectHeight), int64(param.CurrentHeight), currentlyInRange, tickUpperCrosses, tickLowerCrosses)
113136

114-
externalRewards, externalPenalties := pool.ExternalRewardOf(deposit).Calculate(int64(lastCollectHeight), int64(currentHeight), currentlyInRange, tickUpperCrosses, tickLowerCrosses)
137+
externalRewards, externalPenalties := pool.ExternalRewardOf(deposit).Calculate(int64(lastCollectHeight), int64(param.CurrentHeight), currentlyInRange, tickUpperCrosses, tickLowerCrosses)
115138

116-
return internalRewards, internalPenalties, externalRewards, externalPenalties
139+
rewards := make([]Reward, len(internalRewards))
140+
for i := range internalRewards {
141+
rewards[i] = Reward{
142+
Internal: internalRewards[i],
143+
InternalPenalty: internalPenalties[i],
144+
}
145+
if externalRewards != nil {
146+
if len(externalRewards[i]) > 0 {
147+
rewards[i].External = externalRewards[i]
148+
rewards[i].ExternalPenalty = externalPenalties[i]
149+
}
150+
}
151+
}
152+
return rewards
117153
}
118154

119155
func ProcessUnClaimableReward(poolPath string, endHeight uint64) (uint64, map[string]uint64) {

staker/external_token_list_test.gno

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
"gno.land/r/gnoswap/v1/consts"
1010
)
11-
11+
/*
1212
func TestAddToken(t *testing.T) {
1313
adminAddr := consts.ADMIN
1414
nonAdminAddr := testutils.TestAddress("nonadmin")
@@ -128,3 +128,4 @@ func TestRemoveToken(t *testing.T) {
128128
})
129129
}
130130
}
131+
*/

staker/getter.gno

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ func GetDepositWarmUp(lpTokenId uint64) []Warmup {
458458
// Panics:
459459
// - If the pool tier does not exist for the given poolPath
460460
func GetPoolTier(poolPath string) uint64 {
461-
return poolTier.CurrentTier(poolPath, uint64(std.GetHeight()))
461+
return poolTier.CurrentTier(poolPath)
462462
}
463463

464464
// GetPoolTierRatio retrieves the current reward ratio for the specified pool tier.
@@ -472,9 +472,8 @@ func GetPoolTier(poolPath string) uint64 {
472472
// Returns:
473473
// - uint64: The current reward ratio for the specified pool tier.
474474
func GetPoolTierRatio(poolPath string) uint64 {
475-
currentHeight := uint64(std.GetHeight())
476475
tier := GetPoolTier(poolPath)
477-
return poolTier.CurrentRatio(tier, currentHeight)
476+
return poolTier.tierRatio.Get(tier)
478477
}
479478

480479
// GetPoolTierCount retrieves the current count of pools in the specified tier.
@@ -491,7 +490,7 @@ func GetPoolTierCount(tier uint64) uint64 {
491490
if tier == 0 {
492491
return 0
493492
}
494-
return poolTier.CurrentCount(tier, uint64(std.GetHeight()))
493+
return uint64(poolTier.CurrentCount(tier))
495494
}
496495

497496
// GetPoolReward retrieves the current reward amount for the specified pool tier.
@@ -504,7 +503,9 @@ func GetPoolTierCount(tier uint64) uint64 {
504503
// Returns:
505504
// - uint64: The current reward amount for the specified tier.
506505
func GetPoolReward(tier uint64) uint64 {
507-
return poolTier.CurrentReward(tier, uint64(std.GetHeight()))
506+
rewardDenominators := poolTier.tierRatio.IntoRewardDenominators(poolTier.CurrentCounts())
507+
currentEmission := poolTier.emissionUpdate(uint64(std.GetHeight()), uint64(std.GetHeight())).LastEmissionUpdate
508+
return ApplyDenominator(currentEmission, rewardDenominators[tier])
508509
}
509510

510511
// GetRewardCacheOf retrieves the reward cache tree for the specified pool tier.
@@ -517,9 +518,9 @@ func GetPoolReward(tier uint64) uint64 {
517518
//
518519
// Returns:
519520
// - *RewardCacheTree: A pointer to the reward cache tree for the specified tier.
520-
func GetRewardCacheOf(tier uint64) *RewardCacheTree {
521-
return poolTier.rewardCacheOf(tier)
522-
}
521+
//func GetRewardCacheOf(tier uint64) *RewardCacheTree {
522+
// return poolTier.rewardCacheOf(tier)
523+
//}
523524

524525
func printExternalInfo(poolPath string) {
525526
currentHeight := std.GetHeight()

0 commit comments

Comments
 (0)