Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v1 source realm

package v1 manages liquidity mining rewards for GnoSwap positions.

Readme View source

Staker

Liquidity mining and reward distribution for LP positions.

Overview

Staker manages distribution of internal (GNS emission) and external (user-provided) rewards to staked LP positions, with time-weighted rewards and warmup periods.

Configuration

  • Deposit GNS Amount: 1,000 GNS for external incentives (default)
  • Minimum Reward Amount: 1,000 tokens (default)
  • Unstaking Fee: 1% (default)
  • Pool Tiers: 1, 2, or 3 (assigned per pool)
  • Warmup Schedule: 30/50/70/100% over 30/60/90 days
  • External Token Whitelist: Approved reward tokens

Core Features

Internal Rewards (GNS Emission)

  • Allocated to tiered pools (tiers 1, 2, 3)
  • Split across tiers by TierRatio
  • Distributed proportionally to in-range liquidity
  • Unclaimed rewards go to community pool

External Rewards (User Incentives)

  • Created for specific pools
  • Constant reward per block
  • Proportional to staked liquidity
  • Unclaimed rewards returned to creator

Warmup Periods

Every staked position progresses through warmup periods:

  • 0-30 days: 30% rewards (70% to community/creator)
  • 30-60 days: 50% rewards (50% to community/creator)
  • 60-90 days: 70% rewards (30% to community/creator)
  • 90+ days: 100% rewards

Key Functions

StakeToken

Stakes LP position NFT to earn rewards.

UnStakeToken

Unstakes position and collects all rewards.

CollectReward

Collects accumulated rewards without unstaking.

CreateExternalIncentive

Creates external reward program for specific pool.

EndExternalIncentive

Ends incentive program and returns unused rewards.

Reward Calculation Logic

Tier Ratio Distribution

Emission split across tiers based on active pools:

If only tier 1 has pools:    [100%, 0%, 0%]
If tiers 1 & 3 have pools:   [80%, 0%, 20%]
If tiers 1 & 2 have pools:   [70%, 30%, 0%]
If all tiers have pools:     [50%, 30%, 20%]

Mathematical representation:

TierRatio(t) = 
  [1, 0, 0]        if Count(2) = 0 ∧ Count(3) = 0
  [0.8, 0, 0.2]    if Count(2) = 0
  [0.7, 0.3, 0]    if Count(3) = 0
  [0.5, 0.3, 0.2]  otherwise

Pool Reward Formula

poolReward(pool) = (emission × TierRatio[tier(pool)]) / Count(tier(pool))

Where emission is calculated as:

emission = GNSEmissionPerSecond × (avgMsPerBlock/1000) × StakerEmissionRatio

Position Reward Calculation

The reward for each position is calculated through:

  1. Cache pool rewards up to current block
  2. Retrieve position state from deposit records
  3. Calculate internal rewards if pool is tiered
  4. Calculate external rewards for active incentives
  5. Apply warmup penalties based on stake duration

Mathematical formula for total reward ratio:

TotalRewardRatio(s,e) = Σ[i=0 to m-1] ΔRaw(αᵢ, βᵢ) × rᵢ

where:
  αᵢ = max(s, Hᵢ₋₁)
  βᵢ = min(e, Hᵢ)
  
ΔRaw(a, b) = CalcRaw(b) - CalcRaw(a)

CalcRaw(h) = 
  L(h) - U(h)           if tick(h) < ℓ
  U(h) - L(h)           if tick(h) ≥ u
  G(h) - (L(h) + U(h))  otherwise

where:
  L(h) = tickLower.OutsideAccumulation(h)
  U(h) = tickUpper.OutsideAccumulation(h)
  G(h) = globalRewardRatioAccumulation(h)
  ℓ = tickLower.id
  u = tickUpper.id

Final position reward:

finalReward = TotalRewardRatio × poolReward × positionLiquidity
            = ∫[s to e] (poolReward × positionLiquidity) / TotalStakedLiquidity(h) dh

Tick Cross Hook

When price crosses an initialized tick with staked positions:

  1. Updates staked liquidity - Adjusts total staked liquidity
  2. Updates reward accumulation - Recalculates globalRewardRatioAccumulation
  3. Manages unclaimable periods - Starts/ends periods with no in-range liquidity
  4. Updates tick accumulation - Adjusts CurrentOutsideAccumulation

The globalRewardRatioAccumulation tracks the integral:

globalRewardRatioAccumulation = ∫ 1/TotalStakedLiquidity(h) dh

This integral is only computed when TotalStakedLiquidity(h) ≠ 0, enabling precise reward calculation even as liquidity changes.

Reward State Tracking

The system maintains:

  • Global accumulation: Tracks reward ratio across all positions
  • Tick accumulation: Tracks rewards "outside" each tick
  • Position state: Individual reward calculation parameters

Usage

 1// Stake existing position
 2StakeToken(123, "g1referrer...")
 3
 4// Create external incentive
 5CreateExternalIncentive(
 6    "gno.land/r/demo/bar:gno.land/r/demo/baz:3000",
 7    "gno.land/r/demo/reward",
 8    "1000000000",  // 1000 tokens
 9    startTime,
10    endTime,
11)
12
13// Collect rewards without unstaking
14CollectReward(123)
15
16// Unstake and collect all rewards
17UnStakeToken(123)

Security

  • Positions locked during staking
  • External incentives require GNS deposit
  • Warmup periods prevent gaming
  • Unclaimed rewards properly redirected
  • Hook integration ensures accurate tracking

Overview

package v1 manages liquidity mining rewards for GnoSwap positions.

The staker distributes GNS emissions and external incentives to liquidity providers based on their position size, price range, and staking duration. It supports both internal GNS rewards and external token incentives.

Rewards are calculated per-tick and accumulate over time, with automatic compounding and fee collection integration.

Constants 5

Functions 17

func DecodeUint

Action
1func DecodeUint(s string) uint64
source

DecodeUint converts a zero-padded string back into a uint64 number.

Parameters: - s (string): The zero-padded string.

Returns: - uint64: The decoded number.

Panics: - If the string cannot be parsed into a uint64.

Example: Input: "00000000000000012345" Output: 12345

func EncodeUint

Action
1func EncodeUint(num uint64) string
source

EncodeUint converts a uint64 number into a zero-padded 20-character string.

Parameters: - num (uint64): The number to encode.

Returns: - string: A zero-padded string representation of the number.

Example: Input: 12345 Output: "00000000000000012345"

func TierRatioFromCounts

Action
1func TierRatioFromCounts(tier1Count, tier2Count, tier3Count uint64) sr.TierRatio
source

TierRatioFromCounts calculates the ratio distribution for each tier based on pool counts.

Parameters: - tier1Count (uint64): Number of pools in tier 1. - tier2Count (uint64): Number of pools in tier 2. - tier3Count (uint64): Number of pools in tier 3.

Returns: - TierRatio: The ratio distribution across tier 1, 2, and 3, scaled up by 100.

func NewPoolResolver

Action
1func NewPoolResolver(pool *sr.Pool) *PoolResolver
source

NewPool creates a new pool with the given poolPath and currentHeight.

func NewPoolTier

Action
1func NewPoolTier(pools *Pools, currentTime int64, initialPoolPath string, getEmission func() int64, getHalvingBlocksInRange func(start, end int64) ([]int64, []int64)) *PoolTier
source

NewPoolTier creates a new PoolTier instance with single initial 1 tier pool.

Parameters: - pools: The pool collection. - currentTime: The current block time. - initialPoolPath: The path of the initial pool. - getEmission: A function that returns the current emission to the staker contract. - getHalvingBlocksInRange: A function that returns a list of halving blocks within the interval [start, end) in ascending order.

Returns: - *PoolTier: The new PoolTier instance.

func NewPoolTierBy

Action
1func NewPoolTierBy(
2	membership *bptree.BPTree,
3	tierRatio sr.TierRatio,
4	counts [AllTierCount]uint64,
5	lastRewardCacheTimestamp int64,
6	currentEmission int64,
7	getEmission func() int64,
8	getHalvingBlocksInRange func(start, end int64) ([]int64, []int64),
9) *PoolTier
source

func NewStakerV1

Action
1func NewStakerV1(stakerStore sr.IStakerStore, poolAccessor sr.PoolAccessor, emissionAccessor sr.EmissionAccessor, nftAccessor sr.NFTAccessor) *stakerV1
source

func NewTickCrossEventInfo

Action
1func NewTickCrossEventInfo(tickID int32, stakedLiquidityGross *u256.Uint, stakedLiquidityDelta *i256.Int, outsideAccumulation *u256.Uint) *tickCrossEventInfo
source

Types 12

type CalcPositionRewardParam

struct
 1type CalcPositionRewardParam struct {
 2	// Environmental variables
 3	CurrentHeight int64
 4	CurrentTime   int64
 5	Deposits      *Deposits
 6	Pools         *Pools
 7	PoolTier      *PoolTier
 8
 9	// Position variables
10	PositionId uint64
11}
source

CalcPositionRewardParam is a struct for calculating position reward

type DepositResolver

struct
1type DepositResolver struct {
2	*sr.Deposit
3}
source

Methods on DepositResolver

func ExternalRewardLastCollectTime

method on DepositResolver
1func (self *DepositResolver) ExternalRewardLastCollectTime(incentiveID string) int64
source

ExternalRewardLastCollectTime returns the last collect time for the external reward for the given incentive ID. If the last collect time is 0, it returns the staked time.

func FindWarmup

method on DepositResolver
1func (self *DepositResolver) FindWarmup(currentTime int64) int
source

func GetWarmup

method on DepositResolver
1func (self *DepositResolver) GetWarmup(index int) sr.Warmup
source

func InternalRewardLastCollectTime

method on DepositResolver
1func (self *DepositResolver) InternalRewardLastCollectTime() int64
source

InternalRewardLastCollectTime returns the last collect time for the internal reward. If the last collect time is 0, it returns the staked time.

type Deposits

struct
1type Deposits struct {
2	tree *bptree.BPTree
3}
source

Deposits manages all staked positions.

Methods on Deposits

func Has

method on Deposits
1func (self *Deposits) Has(positionId uint64) bool
source

Has checks if a position ID exists in deposits.

func Iterate

method on Deposits
1func (self *Deposits) Iterate(start uint64, end uint64, fn func(positionId uint64, deposit *sr.Deposit) bool)
source

Iterate traverses deposits within the specified range.

func IterateByPoolPath

method on Deposits
1func (self *Deposits) IterateByPoolPath(start, end uint64, poolPath string, fn func(positionId uint64, deposit *sr.Deposit) bool)
source

func Size

method on Deposits
1func (self *Deposits) Size() int
source

Size returns the number of deposits.

type ExternalIncentiveResolver

struct
1type ExternalIncentiveResolver struct {
2	*sr.ExternalIncentive
3}
source

Methods on ExternalIncentiveResolver

func IsEnded

method on ExternalIncentiveResolver
1func (self *ExternalIncentiveResolver) IsEnded(currentTimestamp int64) bool
source

func IsStarted

method on ExternalIncentiveResolver
1func (self *ExternalIncentiveResolver) IsStarted(currentTimestamp int64) bool
source

type ExternalIncentives

struct
1type ExternalIncentives struct {
2	tree *bptree.BPTree
3}
source

ExternalIncentives manages external incentive programs.

Methods on ExternalIncentives

func Has

method on ExternalIncentives
1func (self *ExternalIncentives) Has(incentiveId string) bool
source

Has checks if an incentive ID exists.

func Size

method on ExternalIncentives
1func (self *ExternalIncentives) Size() int
source

Size returns the number of external incentives.

type IncentivesResolver

struct
1type IncentivesResolver struct {
2	*sr.Incentives
3}
source

Methods on IncentivesResolver

func Get

method on IncentivesResolver
1func (self *IncentivesResolver) Get(incentiveId string) (*sr.ExternalIncentive, bool)
source

Get incentive by incentiveId

func GetIncentiveResolver

method on IncentivesResolver
1func (self *IncentivesResolver) GetIncentiveResolver(incentiveId string) (*ExternalIncentiveResolver, bool)
source

type PoolResolver

struct
1type PoolResolver struct {
2	*sr.Pool
3}
source

Methods on PoolResolver

func CalculateRawRewardForPosition

method on PoolResolver
1func (self *PoolResolver) CalculateRawRewardForPosition(currentTime int64, currentTick int32, deposit *sr.Deposit) *u256.Uint
source

Calculates reward for a position *without* considering debt or warmup It calculates the theoretical total reward for the position if it has been staked since the pool creation

func CurrentGlobalRewardRatioAccumulation

method on PoolResolver
1func (self *PoolResolver) CurrentGlobalRewardRatioAccumulation(currentTime int64) (time int64, acc string)
source

Get the latest global reward ratio accumulation in [0, currentTime] range. Returns the time and the accumulation.

func CurrentReward

method on PoolResolver
1func (self *PoolResolver) CurrentReward(currentTime int64) (reward int64)
source

Get the latest reward in [0, currentTime] range. Returns the reward.

func CurrentStakedLiquidity

method on PoolResolver
1func (self *PoolResolver) CurrentStakedLiquidity(currentTime int64) (liquidity *u256.Uint)
source

func CurrentTick

method on PoolResolver
1func (self *PoolResolver) CurrentTick(currentTime int64) (tick int32)
source

Get the latest tick in [0, currentTime] range. Returns the tick.

func IncentivesResolver

method on PoolResolver
1func (self *PoolResolver) IncentivesResolver() *IncentivesResolver
source

func IsExternallyIncentivizedPool

method on PoolResolver
1func (self *PoolResolver) IsExternallyIncentivizedPool() bool
source

IsExternallyIncentivizedPool returns true if the pool has any active external incentives.

func RewardStateOf

method on PoolResolver
1func (self *PoolResolver) RewardStateOf(deposit *sr.Deposit) *RewardState
source

RewardStateOf initializes a new RewardState for the given deposit.

func TickResolver

method on PoolResolver
1func (self *PoolResolver) TickResolver(tickId int32) *TickResolver
source

type PoolTier

struct
 1type PoolTier struct {
 2	membership *bptree.BPTree // poolPath -> tier(1, 2, 3)
 3
 4	tierRatio sr.TierRatio
 5
 6	counts [AllTierCount]uint64
 7
 8	lastRewardCacheTimestamp int64
 9
10	currentEmission int64
11
12	// returns current emission.
13	getEmission func() int64
14	// Returns a list of halving timestamps and their emission amounts within the interval [start, end) in ascending order.
15	// The first return value is a list of timestamps where halving occurs.
16	// The second return value is a list of emission amounts corresponding to each halving timestamp.
17	getHalvingBlocksInRange func(start, end int64) ([]int64, []int64)
18}
source

PoolTier manages pool counts, ratios, and rewards for different tiers.

Fields: - membership: Tracks which tier a pool belongs to (poolPath -> blockNumber -> tier).

Methods: - CurrentCount: Returns the current count of pools in a tier at a specific timestamp. - CurrentRatio: Returns the current ratio for a tier at a specific timestamp. - CurrentTier: Returns the tier of a specific pool at a given timestamp. - CurrentReward: Retrieves the reward for a tier at a specific timestamp. - changeTier: Updates the tier of a pool and recalculates ratios.

Methods on PoolTier

func CurrentAllTierCounts

method on PoolTier
1func (self *PoolTier) CurrentAllTierCounts() []uint64
source

CurrentAllTierCounts returns the current count of pools in each tier.

func CurrentCount

method on PoolTier
1func (self *PoolTier) CurrentCount(tier uint64) int
source

CurrentCount returns the current count of pools in the given tier.

func CurrentReward

method on PoolTier
1func (self *PoolTier) CurrentReward(tier uint64) int64
source

CurrentReward returns the current per-pool reward for the given tier.

func CurrentTier

method on PoolTier
1func (self *PoolTier) CurrentTier(poolPath string) (tier uint64)
source

CurrentTier returns the tier of the given pool.

func IsInternallyIncentivizedPool

method on PoolTier
1func (self *PoolTier) IsInternallyIncentivizedPool(poolPath string) bool
source

IsInternallyIncentivizedPool returns true if the pool is in a tier.

type Pools

struct
1type Pools struct {
2	tree *bptree.BPTree // string poolPath -> pool
3}
source

Pools represents the global pool storage

Methods on Pools

func Get

method on Pools
1func (self *Pools) Get(poolPath string) (*sr.Pool, bool)
source

Get returns the pool for the given poolPath

func GetPoolOrNil

method on Pools
1func (self *Pools) GetPoolOrNil(poolPath string) *sr.Pool
source

GetPoolOrNil returns the pool for the given poolPath, or returns nil if it does not exist

func Has

method on Pools
1func (self *Pools) Has(poolPath string) bool
source

Has returns true if the pool exists for the given poolPath

func IterateAll

method on Pools
1func (self *Pools) IterateAll(fn func(key string, pool *sr.Pool) bool)
source

type Reward

struct
1type Reward struct {
2	Internal        int64
3	InternalPenalty int64
4	External        map[string]int64 // Incentive ID -> TokenAmount
5	ExternalPenalty map[string]int64 // Incentive ID -> TokenAmount
6}
source

Reward is a struct for storing reward for a position. Internal reward is the GNS reward, external reward is the reward for other incentives. Penalties are the amount that is deducted from the reward due to the position's warmup.

type RewardState

struct
1type RewardState struct {
2	pool    *PoolResolver
3	deposit *DepositResolver
4
5	// accumulated rewards for each warmup
6	rewards   []int64
7	penalties []int64
8}
source

RewardState is a struct for storing the intermediate state for reward calculation.

type TickResolver

struct
1type TickResolver struct {
2	*sr.Tick
3}
source

Methods on TickResolver

func CurrentOutsideAccumulation

method on TickResolver
1func (self *TickResolver) CurrentOutsideAccumulation(timestamp int64) *u256.Uint
source

CurrentOutsideAccumulation returns the latest outside accumulation for the tick

Imports 25

Source Files 26