Skip to content

Commit

Permalink
modify external reward to be indexed by incentive id
Browse files Browse the repository at this point in the history
  • Loading branch information
mconcat committed Dec 30, 2024
1 parent a57e240 commit e8da8bd
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 81 deletions.
4 changes: 3 additions & 1 deletion staker/reward_calculation_canonical_env_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ func newExternalIncentiveByHeight(
}
}

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

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

// update global state
self.global.pools.GetOrCreate(targetPoolPath).incentives.create(refundee, incentive)

return incentive.incentiveId
}

func (self *canonicalRewardState) EndExternalIncentive(targetPoolPath string, rewardToken string) {
Expand Down
24 changes: 11 additions & 13 deletions staker/reward_calculation_canonical_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ func TestExternalReward_1(t *testing.T) {
gnousdc := GetPoolPath("gno", "usdc", 3000)
canonical.CreatePool(gnousdc, 1, 200)

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

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

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

canonical.AssertEmulatedExternalRewardOf(uint64(0), "gno", expected)
canonical.AssertEmulatedExternalRewardOf(uint64(0), incentiveId, expected)
}

func TestMultiplePool_1(t *testing.T) {
Expand Down Expand Up @@ -830,17 +830,15 @@ func TestMultiplePool_2(t *testing.T) {
canonical.AssertEmulatedRewardOf(0, 0)
canonical.AssertEmulatedRewardOf(1, 0)
canonical.AssertEmulatedRewardOf(2, expected * 20 / 100)
}

func TestMultiplePool_3(t *testing.T) {
canonical := Setup(t)

gnousdc := GetPoolPath("gno", "usdc", 3000)
gnousdc2 := GetPoolPath("gno", "usdc", 10000)
gnousdc3 := GetPoolPath("gno", "usdc", 30000)
canonical.CreatePool(gnousdc, 1, 200)
canonical.CreatePool(gnousdc2, 2, 200)
canonical.CreatePool(gnousdc3, 3, 200)
canonical.ChangePoolTier(gnousdc2, 1)
canonical.MoveTick(gnousdc, 200)
canonical.MoveTick(gnousdc2, 300)
canonical.MoveTick(gnousdc3, 400)

canonical.NextBlock()
canonical.AssertEmulatedRewardOf(0, expected * 40 / 100)
canonical.AssertEmulatedRewardOf(1, expected * 40 / 100)
canonical.AssertEmulatedRewardOf(2, expected * 20 / 100)
}

// Large number of blocks passed
Expand Down
94 changes: 41 additions & 53 deletions staker/reward_calculation_incentives.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,36 @@ import (
u256 "gno.land/p/gnoswap/uint256"
)

type IncentiveBound struct {
Incentive ExternalIncentive
IsEnter bool
}

// per-pool incentives
type Incentives struct {
byTime *avl.Tree // (startTime, endTime, creator, rewardToken) => ExternalIncentive
byHeight *avl.Tree // (startHeight, endHeight, creator, rewardToken) => ExternalIncentive
byCreator *avl.Tree // (creator, startHeight, endHeight, rewardToken) => ExternalIncentive

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

rewardCache *RewardCacheTree // blockNumber -> map[string]*u256.Uint
lastRewardCacheHeight *uint64

// refund to the refundee
totalPenalty *uint64
claimedPenalty *uint64
}

func NewIncentives(currentHeight uint64) Incentives {
totalPenalty := uint64(0)
claimedPenalty := uint64(0)

return Incentives{
byTime: avl.NewTree(),
byHeight: avl.NewTree(),
byCreator: avl.NewTree(),

delta: NewUintTree(),
incentiveBound: NewUintTree(),

rewardCache: NewRewardCacheTree(),
lastRewardCacheHeight: &currentHeight,

totalPenalty: &totalPenalty,
claimedPenalty: &claimedPenalty,
}
}

func (self *Incentives) claimPenalty() uint64 {
amount := *self.totalPenalty - *self.claimedPenalty
*self.claimedPenalty += amount
return amount
}

func (self *Incentives) Exists(startTime, endTime int64, creator std.Address, rewardToken string) bool {
byTimeId := incentiveIdByTime(uint64(startTime), uint64(endTime), creator, rewardToken)
return self.byTime.Has(byTimeId)
Expand All @@ -77,12 +65,12 @@ func (self *Incentives) remove(incentive *ExternalIncentive) {
self.byCreator.Remove(byCreatorId)
}

func (self *Incentives) GetDelta(height uint64) map[string]int64 {
delta, ok := self.delta.Get(height)
func (self *Incentives) GetBound(height uint64) []IncentiveBound {
value, ok := self.incentiveBound.Get(height)
if !ok {
return make(map[string]int64)
return []IncentiveBound{}
}
return delta.(map[string]int64)
return value.([]IncentiveBound)
}

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

startIncentiveDelta := self.GetDelta(uint64(incentive.startHeight))
startIncentiveDelta[incentive.rewardToken] += int64(incentive.rewardPerBlock)
startHeight := uint64(incentive.startHeight)
self.delta.Set(startHeight, startIncentiveDelta)

println("startIncentiveDelta")
for tokenId, deltaAmount := range startIncentiveDelta {
println(startHeight, tokenId, deltaAmount)
}
startIncentiveBound := self.GetBound(uint64(incentive.startHeight))
startIncentiveBound = append(startIncentiveBound, IncentiveBound{
Incentive: *incentive,
IsEnter: true,
})
self.incentiveBound.Set(uint64(incentive.startHeight), startIncentiveBound)

endHeight := uint64(incentive.endHeight)
endIncentiveDelta := self.GetDelta(endHeight)
endIncentiveDelta[incentive.rewardToken] -= int64(incentive.rewardPerBlock)
self.delta.Set(endHeight, endIncentiveDelta)
endIncentiveBound := self.GetBound(endHeight)
endIncentiveBound = append(endIncentiveBound, IncentiveBound{
Incentive: *incentive,
IsEnter: false,
})
self.incentiveBound.Set(endHeight, endIncentiveBound)

println("endIncentiveDelta")
for tokenId, deltaAmount := range endIncentiveDelta {
println(endHeight, tokenId, deltaAmount)
println("endIncentiveBound")
for _, bound := range endIncentiveBound {
println(bound.Incentive.rewardToken, bound.IsEnter)
}
}

// endHeight MUST be less than or equal to the current block height
func (self *Incentives) cacheRewardPerLiquidityUnit(startHeight, endHeight uint64, stakedLiquidity *u256.Uint) {
currentReward := self.CurrentReward(startHeight)

/*
delta := self.GetDelta(startHeight)
reward := make(map[string]*u256.Uint)
Expand All @@ -156,25 +145,24 @@ func (self *Incentives) cacheRewardPerLiquidityUnit(startHeight, endHeight uint6

self.rewardCache.Set(startHeight, reward)
*/
self.delta.Iterate(startHeight, endHeight, func(key uint64, value interface{}) bool {
delta := value.(map[string]int64)

self.incentiveBound.Iterate(startHeight, endHeight, func(key uint64, value interface{}) bool {
bound := value.([]IncentiveBound)
reward := make(map[string]*u256.Uint)
for token, deltaAmount := range delta {
delta := i256.NewInt(deltaAmount)
deltaQ96 := i256.Zero().Mul(delta, _iQ96)
ratio := i256.Zero().Div(deltaQ96, i256.FromUint256(stakedLiquidity))
currentRewardToken, ok := currentReward[token]
if !ok {
currentRewardToken = u256.Zero()
}
deltaApplied := liquidityMathAddDelta(currentRewardToken, ratio)
if deltaApplied.IsZero() {
continue
for incentiveId, ratio := range currentReward {
reward[incentiveId] = ratio
}
for _, bound := range bound {
if bound.IsEnter {
delta := u256.NewUint(bound.Incentive.rewardPerBlock)
deltaQ96 := delta.Mul(delta, q96)
ratio := u256.Zero().Div(deltaQ96, stakedLiquidity)
reward[bound.Incentive.incentiveId] = ratio
} else {
delete(reward, bound.Incentive.incentiveId)
}
reward[token] = deltaApplied
}
self.rewardCache.Set(key, reward)
currentReward = reward
return false
})
*self.lastRewardCacheHeight = endHeight
Expand Down
24 changes: 12 additions & 12 deletions staker/reward_calculation_pool.gno
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,11 @@ func (self *ExternalRewardState) Calculate(startHeight, endHeight int64, current
for i := range self.rewards {
rewards[i] = make(map[string]uint64)
penalties[i] = make(map[string]uint64)
for tokenId, reward := range self.rewards[i] {
rewards[i][tokenId] = reward.Uint64()
for incentiveId, reward := range self.rewards[i] {
rewards[i][incentiveId] = reward.Uint64()
}
for tokenId, penalty := range self.penalties[i] {
penalties[i][tokenId] = penalty.Uint64()
for incentiveId, penalty := range self.penalties[i] {
penalties[i][incentiveId] = penalty.Uint64()
}
}

Expand All @@ -232,23 +232,23 @@ func (self *ExternalRewardState) Calculate(startHeight, endHeight int64, current
func (self *ExternalRewardState) AccumulateReward(startHeight, endHeight uint64) {
self.pool.incentives.rewardCache.RewardPerInterval(startHeight, endHeight, func(blockNumber uint64, poolRewardI interface{}) {
poolRewardRatios := poolRewardI.(map[string]*u256.Uint)
for tokenId, poolRewardRatio := range poolRewardRatios {
positionReward := u256.Zero().Mul(self.deposit.liquidity, poolRewardRatio)
for incentiveId, rewardRatio := range poolRewardRatios {
positionReward := u256.Zero().Mul(self.deposit.liquidity, rewardRatio)
positionReward = u256.Zero().Mul(positionReward, u256.NewUint(blockNumber))
println("AccumulateReward", blockNumber, tokenId, poolRewardRatio.ToString(), positionReward.ToString())
acc, ok := self.rewards[self.currentWarmup.Index][tokenId]
println("AccumulateReward", blockNumber, incentiveId, rewardRatio.ToString(), positionReward.ToString())
acc, ok := self.rewards[self.currentWarmup.Index][incentiveId]
if !ok {
acc = u256.Zero()
}
acc.Add(acc, positionReward)
self.rewards[self.currentWarmup.Index][tokenId] = acc
self.rewards[self.currentWarmup.Index][incentiveId] = acc
}
})
}

func (self *ExternalRewardState) ApplyWarmup() {
for i, warmup := range self.deposit.warmups {
for tokenId, rewardRatio := range self.rewards[i] {
for incentiveId, rewardRatio := range self.rewards[i] {
if rewardRatio.IsZero() {
continue
}
Expand All @@ -262,8 +262,8 @@ func (self *ExternalRewardState) ApplyWarmup() {
penalty = penalty.Div(penalty, u256.NewUint(100))
penalty = penalty.Div(penalty, q96)

self.rewards[i][tokenId] = reward
self.penalties[i][tokenId] = penalty
self.rewards[i][incentiveId] = reward
self.penalties[i][incentiveId] = penalty
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions staker/reward_calculation_pool_tier.gno
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ func (self *PoolTier) CurrentReward(tier uint64, currentHeight uint64) uint64 {
return reward.(uint64)
}

func (self *PoolTier) createPool(pools *Pools, poolPath string, initialTier uint64, currentHeight uint64) {
_ = pools.GetOrCreate(poolPath)

self.changeTier(currentHeight, poolPath, initialTier)
}

func (self *PoolTier) changeTier(currentHeight uint64, poolPath string, nextTier uint64) {
currentTier := self.CurrentTier(poolPath, currentHeight)
if currentTier == nextTier {
Expand Down
2 changes: 0 additions & 2 deletions staker/reward_calculation_warmup.gno
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ func DefaultWarmupTemplate(currentHeight int64) []Warmup {
blocksIn10Days := int64(10 * blocksInDay)
blocksIn30Days := int64(30 * blocksInDay)

println(blocksIn5Days, blocksIn10Days, blocksIn30Days)

return []Warmup{
{
Index: 0,
Expand Down

0 comments on commit e8da8bd

Please sign in to comment.