Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Preaudit #465

Draft
wants to merge 20 commits into
base: init
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: deploy contracts on the latest gno (#479)
r3v4s authored and moul committed Jan 21, 2025
commit 8c3761570ab427d40612e2d58e166a3c44c22b58
1 change: 0 additions & 1 deletion contract/r/gnoswap/gov/staker/api_staker.gno
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ import (
"std"
"time"

"gno.land/p/demo/avl"
"gno.land/p/demo/json"

en "gno.land/r/gnoswap/v1/emission"
1 change: 0 additions & 1 deletion contract/r/gnoswap/pool/protocol_fee_pool_creation.gno
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ package pool
import (
"std"

"gno.land/p/demo/ufmt"
"gno.land/r/gnoswap/v1/common"
)

3 changes: 1 addition & 2 deletions contract/r/gnoswap/staker/calculate_pool_position_reward.gno
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@ package staker

import (
"gno.land/r/gnoswap/v1/consts"
pl "gno.land/r/gnoswap/v1/pool"

u256 "gno.land/p/gnoswap/uint256"
)
@@ -120,7 +119,7 @@ func CalcPositionReward(param CalcPositionRewardParam) []Reward {
externalPenalties := make([]map[string]uint64, len(deposit.warmups))

if param.PoolTier.CurrentTier(poolPath) != 0 {
// Internal incentivized pool.
// Internal incentivized pool.
// Calculate reward for each warmup
internalRewards, internalPenalties = pool.RewardStateOf(deposit).CalculateInternalReward(lastCollectHeight, param.CurrentHeight)
}
2 changes: 0 additions & 2 deletions contract/r/gnoswap/staker/external_deposit_fee.gno
Original file line number Diff line number Diff line change
@@ -3,8 +3,6 @@ package staker
import (
"std"

"gno.land/p/demo/ufmt"

"gno.land/r/gnoswap/v1/common"
)

32 changes: 13 additions & 19 deletions contract/r/gnoswap/staker/reward_calculation_incentives.gno
Original file line number Diff line number Diff line change
@@ -4,41 +4,37 @@ import (
"std"

"gno.land/p/demo/avl"

"gno.land/p/demo/ufmt"

u256 "gno.land/p/gnoswap/uint256"
)


// Incentives is a collection of external incentives for a given pool.
//
//
// Fields:
// - byTime: ExternalIncentive primarily indexed by startTime
// - byHeight: ExternalIncentive primarily indexed by startHeight
// - byEndHeight: ExternalIncentive primarily indexed by endHeight
// - byCreator: ExternalIncentive primarily indexed by creator
//
// - unclaimablePeriods:
// For each unclaimable period(start, end) for this pool,
// it stores (key: start) => (value: end)
// if end is 0, it means the unclaimable period is ongoing.
// - unclaimablePeriods:
// For each unclaimable period(start, end) for this pool,
// it stores (key: start) => (value: end)
// if end is 0, it means the unclaimable period is ongoing.
type Incentives struct {
byTime *avl.Tree // (startTime, endTime, creator, rewardToken) => ExternalIncentive
byHeight *avl.Tree // (startHeight, endHeight, creator, rewardToken) => ExternalIncentive
byTime *avl.Tree // (startTime, endTime, creator, rewardToken) => ExternalIncentive
byHeight *avl.Tree // (startHeight, endHeight, creator, rewardToken) => ExternalIncentive
byEndHeight *avl.Tree // (endHeight, startHeight, creator, rewardToken) => ExternalIncentive
byCreator *avl.Tree // (creator, startHeight, endHeight, rewardToken) => ExternalIncentive
byCreator *avl.Tree // (creator, startHeight, endHeight, rewardToken) => ExternalIncentive

unclaimablePeriods *UintTree // startHeight => endHeight
}

// NewIncentives creates a new Incentives instance.
func NewIncentives() Incentives {
result := Incentives{
byTime: avl.NewTree(),
byHeight: avl.NewTree(),
byEndHeight: avl.NewTree(),
byCreator: avl.NewTree(),
byTime: avl.NewTree(),
byHeight: avl.NewTree(),
byEndHeight: avl.NewTree(),
byCreator: avl.NewTree(),
unclaimablePeriods: NewUintTree(),
}

@@ -79,7 +75,7 @@ func (self *Incentives) GetAllInHeights(startHeight, endHeight int64) map[string
// incentive is already ended
return false
}

incentives[incentive.incentiveId] = incentive
return false
},
@@ -166,7 +162,6 @@ func (self *Incentives) calculateUnclaimableReward(incentiveId string) uint64 {

blocks := int64(0)


self.unclaimablePeriods.ReverseIterate(0, incentive.startHeight, func(key int64, value interface{}) bool {
endHeight := value.(int64)
if endHeight == 0 {
@@ -191,4 +186,3 @@ func (self *Incentives) calculateUnclaimableReward(incentiveId string) uint64 {

return uint64(blocks) * incentive.rewardPerBlock
}

87 changes: 42 additions & 45 deletions contract/r/gnoswap/staker/reward_calculation_pool.gno
Original file line number Diff line number Diff line change
@@ -4,14 +4,11 @@ import (
"std"

"gno.land/p/demo/avl"

i256 "gno.land/p/gnoswap/int256"
u256 "gno.land/p/gnoswap/uint256"

"gno.land/r/gnoswap/v1/consts"

en "gno.land/r/gnoswap/v1/emission"

pl "gno.land/r/gnoswap/v1/pool"
)

var (
@@ -80,40 +77,40 @@ func (self *Pools) IterateAll(fn func(key string, pool *Pool) bool) {
// Fields:
// - poolPath: The path of the pool.
//
// - currentStakedLiquidity:
// The current total staked liquidity of the in-range positions for the pool.
// Updated when tick cross happens or stake/unstake happens.
// Used to calculate the global reward ratio accumulation or
// decide whether to enter/exit unclaimable period.
// - currentStakedLiquidity:
// The current total staked liquidity of the in-range positions for the pool.
// Updated when tick cross happens or stake/unstake happens.
// Used to calculate the global reward ratio accumulation or
// decide whether to enter/exit unclaimable period.
//
// - lastUnclaimableHeight:
// The height at which the unclaimable period started.
// Set to 0 when the pool is not in an unclaimable period.
// - lastUnclaimableHeight:
// The height at which the unclaimable period started.
// Set to 0 when the pool is not in an unclaimable period.
//
// - unclaimableAcc:
// The accumulated undisributed unclaimable reward.
// Reset to 0 when processUnclaimableReward is called and sent to community pool.
// - unclaimableAcc:
// The accumulated undisributed unclaimable reward.
// Reset to 0 when processUnclaimableReward is called and sent to community pool.
//
// - rewardCache:
// The cached per-block reward emitted for this pool.
// Stores new entry only when the reward is changed.
// PoolTier.cacheReward() updates this.
// - rewardCache:
// The cached per-block reward emitted for this pool.
// Stores new entry only when the reward is changed.
// PoolTier.cacheReward() updates this.
//
// - incentives: The external incentives associated with the pool.
//
// - ticks: The Ticks associated with the pool.
//
// - globalRewardRatioAccumulation:
// Global ratio of BlockNumber / TotalStake accumulation(since the pool creation)
// Stores new entry only when tick cross or stake/unstake happens.
// It is used to calculate the reward for a staked position at certain height.
// - globalRewardRatioAccumulation:
// Global ratio of BlockNumber / TotalStake accumulation(since the pool creation)
// Stores new entry only when tick cross or stake/unstake happens.
// It is used to calculate the reward for a staked position at certain height.
//
// - historicalTick:
// The historical tick for the pool at a given height.
// It does not reflect the exact tick at the blockNumber,
// but it provides correct ordering for the staked position's ticks.
// Therefore, you should not compare it for equality, only for ordering.
// Set when tick cross happens or a new position is created.
// - historicalTick:
// The historical tick for the pool at a given height.
// It does not reflect the exact tick at the blockNumber,
// but it provides correct ordering for the staked position's ticks.
// Therefore, you should not compare it for equality, only for ordering.
// Set when tick cross happens or a new position is created.
type Pool struct {
poolPath string

@@ -122,7 +119,7 @@ type Pool struct {
lastUnclaimableHeight int64
unclaimableAcc uint64

rewardCache *UintTree // uint64 blockNumber -> uint64 gnsReward
rewardCache *UintTree // uint64 blockNumber -> uint64 gnsReward

incentives Incentives

@@ -136,15 +133,15 @@ type Pool struct {
// NewPool creates a new pool with the given poolPath and currentHeight.
func NewPool(poolPath string, currentHeight int64) *Pool {
pool := &Pool{
poolPath: poolPath,
stakedLiquidity: NewUintTree(),
lastUnclaimableHeight: currentHeight,
unclaimableAcc: 0,
rewardCache: NewUintTree(),
incentives: NewIncentives(),
ticks: NewTicks(),
poolPath: poolPath,
stakedLiquidity: NewUintTree(),
lastUnclaimableHeight: currentHeight,
unclaimableAcc: 0,
rewardCache: NewUintTree(),
incentives: NewIncentives(),
ticks: NewTicks(),
globalRewardRatioAccumulation: NewUintTree(),
historicalTick: NewUintTree(),
historicalTick: NewUintTree(),
}

pool.globalRewardRatioAccumulation.Set(currentHeight, u256.Zero())
@@ -263,21 +260,21 @@ func (self *Pool) updateGlobalRewardRatioAccumulation(currentHeight int64, curre

// RewardState is a struct for storing the intermediate state for reward calculation.
type RewardState struct {
pool *Pool
deposit *Deposit
pool *Pool
deposit *Deposit

// accumulated rewards for each warmup
rewards []uint64
rewards []uint64
penalties []uint64
}

// RewardStateOf initializes a new RewardState for the given deposit.
func (self *Pool) RewardStateOf(deposit *Deposit) *RewardState {
result := &RewardState{
pool: self,
deposit: deposit,
rewards: make([]uint64, len(deposit.warmups)),
penalties: make([]uint64, len(deposit.warmups)),
pool: self,
deposit: deposit,
rewards: make([]uint64, len(deposit.warmups)),
penalties: make([]uint64, len(deposit.warmups)),
}

for i := range result.rewards {
20 changes: 7 additions & 13 deletions contract/r/gnoswap/staker/reward_calculation_pool_tier.gno
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package staker

import (
"std"

"gno.land/p/demo/avl"
"gno.land/p/demo/ufmt"

en "gno.land/r/gnoswap/v1/emission"
)

const (
AllTierCount = 4 // 0, 1, 2, 3
AllTierCount = 4 // 0, 1, 2, 3
Tier1 = 1
Tier2 = 2
Tier3 = 3
@@ -104,9 +100,8 @@ type PoolTier struct {
getEmission func() uint64

// returns a list of halving blocks within the interval [start, end) in ascending order
// there MUST NOT be any emission amount change between start and end - those had to be handled by the CallbackStakerEmissionChange.
// there MUST NOT be any emission amount change between start and end - those had to be handled by the CallbackStakerEmissionChange.
getHalvingBlocksInRange func(start, end int64) ([]int64, []uint64)

}

// NewPoolTier creates a new PoolTier instance with single initial 1 tier pool.
@@ -122,12 +117,12 @@ type PoolTier struct {
// - *PoolTier: The new PoolTier instance.
func NewPoolTier(pools *Pools, currentHeight int64, initialPoolPath string, getEmission func() uint64, getHalvingBlocksInRange func(start, end int64) ([]int64, []uint64)) *PoolTier {
result := &PoolTier{
membership: avl.NewTree(),
tierRatio: TierRatioFromCounts(1, 0, 0),
lastRewardCacheHeight: currentHeight + 1,
getEmission: getEmission,
membership: avl.NewTree(),
tierRatio: TierRatioFromCounts(1, 0, 0),
lastRewardCacheHeight: currentHeight + 1,
getEmission: getEmission,
getHalvingBlocksInRange: getHalvingBlocksInRange,
currentEmission: getEmission(),
currentEmission: getEmission(),
}

pools.Set(initialPoolPath, NewPool(initialPoolPath, currentHeight+1))
@@ -176,7 +171,6 @@ func (self *PoolTier) CurrentTier(poolPath string) uint64 {
// updated per-pool reward to each of the pools.
func (self *PoolTier) changeTier(currentHeight int64, pools *Pools, poolPath string, nextTier uint64) {
self.cacheReward(currentHeight, pools)

// same as prev. no need to update
currentTier := self.CurrentTier(poolPath)
if currentTier == nextTier {
3 changes: 1 addition & 2 deletions contract/r/gnoswap/staker/reward_calculation_types.gno
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@ import (
"strings"

"gno.land/p/demo/avl"
"gno.land/p/demo/ufmt"
)

// EncodeUint converts a uint64 number into a zero-padded 20-character string.
@@ -101,4 +100,4 @@ func (self *UintTree) ReverseIterate(start, end int64, fn func(key int64, value
self.tree.ReverseIterate(EncodeUint(uint64(start)), EncodeUint(uint64(end)), func(key string, value interface{}) bool {
return fn(int64(DecodeUint(key)), value)
})
}
}
4 changes: 1 addition & 3 deletions contract/r/gnoswap/staker/staker.gno
Original file line number Diff line number Diff line change
@@ -20,8 +20,6 @@ import (

i256 "gno.land/p/gnoswap/int256"
u256 "gno.land/p/gnoswap/uint256"

pusers "gno.land/p/demo/users"
)

type Deposits struct {
@@ -682,4 +680,4 @@ func getTickOf(tokenId uint64) (int32, int32) {
panic(ufmt.Sprintf("tickUpper(%d) is less than tickLower(%d)", tickUpper, tickLower))
}
return tickLower, tickUpper
}
}
32 changes: 32 additions & 0 deletions tests/_info.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# r/demo/wugnot from gno
ADDR_WUGNOT := g1pf6dv9fjk3rn0m4jjcne306ga4he3mzmupfjl6

# based on v1
ADDR_POOL := g148tjamj80yyrm309z7rk690an22thd2l3z8ank
ADDR_POSITION := g1q646ctzhvn60v492x8ucvyqnrj2w30cwh6efk5
ADDR_ROUTER := g1lm2l7tf49h3mykesct7rhfml30yx8dw5xrval7
ADDR_STAKER := g1cceshmzzlmrh7rr3z30j2t5mrvsq9yccysw9nu
ADDR_PROTOCOL_FEE := g1f7wpek7q67tkns27sw495u5yuu3a5wwjxw5l6l
ADDR_GOV_STAKER := g17e3ykyqk9jmqe2y9wxe9zhep3p7cw56davjqwa
ADR_GOV_GOV := g17s8w2ve7k85fwfnrk59lmlhthkjdted8whvqxd
ADDR_LAUNCHPAD := g122mau2lp2rc0scs8d27pkkuys4w54mdy2tuer3
ADDR_GNS := g1jgqwaa2le3yr63d533fj785qkjspumzv22ys5m
ADDR_GNFT := g1wxv2rdfn53qc84nt3nn646f9yh3nly8lm7j89t

# username address
ADDR_GNOSWAP := g1lmvrrrr4er2us84h2732sru76c9zl2nvknha8c

# INCENTIVE_START
TOMORROW_MIDNIGHT := $(shell (gdate -ud 'tomorrow 00:00:00' +%s))
INCENTIVE_END := $(shell expr $(TOMORROW_MIDNIGHT) + 7776000) # 7776000 SECONDS = 90 DAY

MAX_UINT64 := 18446744073709551615
TX_EXPIRE := 9999999999

MAKEFILE := $(shell realpath $(firstword $(MAKEFILE_LIST)))
ROOT_DIR:=$(shell dirname $(MAKEFILE))/../


# TODO: change below 2 values based on which chain to deploy
GNOLAND_RPC_URL ?= localhost:26657
CHAINID ?= dev
Loading