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 GNS token staking and delegation functionality. It handles delegation of voting power, distributio...

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 GNS token staking and delegation functionality. It handles delegation of voting power, distribution of protocol rewards, and implements a lockup period (default: 7-days) for unstaking operations (xGNS burned on collect).

Functions 12

func NewDelegation

Action
1func NewDelegation(
2	id int64,
3	delegateFrom, delegateTo address,
4	delegateAmount, createdHeight, createdAt int64,
5) *staker.Delegation
source

NewDelegation creates a new delegation. This is a convenience wrapper around staker.NewDelegation.

Parameters:

  • id: delegation ID
  • delegateFrom: delegator's address
  • delegateTo: delegatee's address
  • delegateAmount: amount to delegate
  • createdHeight: creation block height
  • createdAt: creation timestamp

Returns:

  • *staker.Delegation: new delegation instance

func NewDelegationWithdraw

Action
1func NewDelegationWithdraw(
2	delegationID,
3	unDelegateAmount,
4	createdHeight,
5	createdAt,
6	unDelegationLockupPeriod int64,
7) staker.DelegationWithdraw
source

NewDelegationWithdraw creates a new delegation withdrawal with lockup period. This is a convenience wrapper around staker.NewDelegationWithdraw.

Parameters:

  • delegationID: unique identifier of the associated delegation
  • unDelegateAmount: amount being withdrawn
  • createdHeight: height when the withdrawal was created
  • createdAt: timestamp when the withdrawal was created
  • unDelegationLockupPeriod: duration of the lockup period in seconds

Returns:

  • *staker.DelegationWithdraw: new withdrawal instance with lockup

func NewDelegationWithdrawWithoutLockup

Action
1func NewDelegationWithdrawWithoutLockup(
2	delegationID,
3	unDelegateAmount,
4	createdHeight,
5	createdAt int64,
6) staker.DelegationWithdraw
source

NewDelegationWithdrawWithoutLockup creates a new delegation withdrawal that is immediately collectable. This is a convenience wrapper around staker.NewDelegationWithdrawWithoutLockup.

Parameters:

  • delegationID: unique identifier of the associated delegation
  • unDelegateAmount: amount being withdrawn
  • createdHeight: height when the withdrawal was created
  • createdAt: timestamp when the withdrawal was created

Returns:

  • *staker.DelegationWithdraw: new withdrawal instance that is immediately collected

Types 8

type DelegationManagerResolver

struct
1type DelegationManagerResolver struct {
2	*staker.DelegationManager
3}
source

Methods on DelegationManagerResolver

func GetUserDelegationIDs

method on DelegationManagerResolver
1func (dm *DelegationManagerResolver) GetUserDelegationIDs(delegator address) []int64
source

GetUserDelegationIDs retrieves all delegation IDs for a specific delegator across all delegatees. This method is used to find all delegations made by a specific user.

Parameters:

  • delegator: address of the user whose delegations to retrieve

Returns:

  • []int64: list of all delegation IDs for the delegator

func GetUserDelegationIDsWithDelegatee

method on DelegationManagerResolver
1func (dm *DelegationManagerResolver) GetUserDelegationIDsWithDelegatee(delegator, delegatee address) []int64
source

GetUserDelegationIDsWithDelegatee retrieves all delegation IDs for a specific delegator-delegatee pair. This method is used to find delegations from a specific user to a specific delegate.

Parameters:

  • delegator: address of the user who delegated tokens
  • delegatee: address of the user who received the delegation

Returns:

  • []int64: list of delegation IDs for the specified pair

type DelegationResolver

struct
1type DelegationResolver struct {
2	delegation *staker.Delegation
3}
source

Methods on DelegationResolver

func CollectableAmount

method on DelegationResolver
1func (r *DelegationResolver) CollectableAmount(currentTime int64) (total int64)
source

CollectableAmount calculates the total amount that can be collected at the given time

func DelegatedAmount

method on DelegationResolver
1func (r *DelegationResolver) DelegatedAmount() int64
source

func Get

method on DelegationResolver
1func (r *DelegationResolver) Get() *staker.Delegation
source

func IsEmpty

method on DelegationResolver
1func (r *DelegationResolver) IsEmpty() bool
source

func LockedAmount

method on DelegationResolver
1func (r *DelegationResolver) LockedAmount() int64
source

func UnDelegate

method on DelegationResolver
1func (r *DelegationResolver) UnDelegate(
2	amount, currentHeight, currentTimestamp, unDelegationLockupPeriod int64,
3)
source

UnDelegate processes an undelegation with lockup period

func UnDelegateWithoutLockup

method on DelegationResolver
1func (r *DelegationResolver) UnDelegateWithoutLockup(
2	amount, currentHeight, currentTime int64,
3)
source

UnDelegateWithoutLockup processes an immediate undelegation without lockup

type DelegationWithdrawResolver

struct
1type DelegationWithdrawResolver struct {
2	withdraw *staker.DelegationWithdraw
3}
source

Methods on DelegationWithdrawResolver

func Collect

method on DelegationWithdrawResolver
1func (r *DelegationWithdrawResolver) Collect(amount int64, currentTime int64) error
source

collect processes the collection of the specified amount from this withdrawal. This method validates collectability and updates the collection state.

Parameters:

  • amount: amount to collect
  • currentTime: current timestamp

Returns:

  • error: nil on success, error if collection is not allowed

func CollectableAmount

method on DelegationWithdrawResolver
1func (r *DelegationWithdrawResolver) CollectableAmount(currentTime int64) int64
source

CollectableAmount calculates the amount available for collection at the given time. Returns zero if the withdrawal is not yet collectable or has been fully collected.

Parameters:

  • currentTime: current timestamp to check collectability against

Returns:

  • int64: amount available for collection

func Get

method on DelegationWithdrawResolver
1func (r *DelegationWithdrawResolver) Get() *staker.DelegationWithdraw
source

func IsCollectable

method on DelegationWithdrawResolver
1func (r *DelegationWithdrawResolver) IsCollectable(currentTime int64) bool
source

IsCollectable determines whether the withdrawal can be collected at the given time. A withdrawal is collectable if: - The undelegated amount is positive - There is remaining uncollected amount - The current time is at or after the collectable time

Parameters:

  • currentTime: current timestamp to check against

Returns:

  • bool: true if the withdrawal can be collected, false otherwise

func IsCollected

method on DelegationWithdrawResolver
1func (r *DelegationWithdrawResolver) IsCollected() bool
source

IsCollected returns whether the withdrawal has been fully collected.

Returns:

  • bool: true if fully collected, false otherwise

type EmissionRewardManagerResolver

struct
1type EmissionRewardManagerResolver struct {
2	*staker.EmissionRewardManager
3}
source

Methods on EmissionRewardManagerResolver

func GetClaimableRewardAmount

method on EmissionRewardManagerResolver
1func (self *EmissionRewardManagerResolver) GetClaimableRewardAmount(
2	currentDistributedAmount int64,
3	address string,
4	currentTimestamp int64,
5) (int64, error)
source

GetClaimableRewardAmount calculates the claimable reward amount for a specific address.

type EmissionRewardStateResolver

struct
1type EmissionRewardStateResolver struct {
2	*staker.EmissionRewardState
3}
source

Methods on EmissionRewardStateResolver

func GetClaimableRewardAmount

method on EmissionRewardStateResolver
1func (self *EmissionRewardStateResolver) GetClaimableRewardAmount(
2	accumulatedRewardX128PerStake *u256.Uint,
3	currentTimestamp int64,
4) (int64, error)
source

GetClaimableRewardAmount calculates the total amount of rewards that can be claimed. This includes both accumulated rewards and newly earned rewards based on current state.

Parameters:

  • accumulatedRewardX128PerStake: current system-wide accumulated reward per stake
  • currentTimestamp: current timestamp

Returns:

  • int64: total claimable reward amount

func IsClaimable

method on EmissionRewardStateResolver
1func (self *EmissionRewardStateResolver) IsClaimable(currentTimestamp int64) bool
source

IsClaimable checks if rewards can be claimed at the given timestamp. Rewards are claimable if the current timestamp is greater than the last claimed timestamp.

Parameters:

  • currentTimestamp: current timestamp to check against

Returns:

  • bool: true if rewards can be claimed, false otherwise

type ProtocolFeeRewardManagerResolver

struct
1type ProtocolFeeRewardManagerResolver struct {
2	*staker.ProtocolFeeRewardManager
3}
source

Methods on ProtocolFeeRewardManagerResolver

func GetClaimableRewardAmounts

method on ProtocolFeeRewardManagerResolver
1func (self *ProtocolFeeRewardManagerResolver) GetClaimableRewardAmounts(
2	protocolFeeAmounts map[string]int64,
3	address string,
4	currentTimestamp int64,
5) (map[string]int64, error)
source

GetClaimableRewardAmounts calculates the claimable reward amounts for all tokens for a specific address. This method computes rewards based on current protocol fee distribution state and staking history.

Parameters:

  • protocolFeeAmounts: current protocol fee amounts for all tokens
  • address: staker's address to calculate rewards for
  • currentTimestamp: current timestamp

Returns:

  • map[string]int64: map of token path to claimable reward amount

type ProtocolFeeRewardStateResolver

struct
1type ProtocolFeeRewardStateResolver struct {
2	*staker.ProtocolFeeRewardState
3}
source

Methods on ProtocolFeeRewardStateResolver

func GetClaimableRewardAmounts

method on ProtocolFeeRewardStateResolver
1func (p *ProtocolFeeRewardStateResolver) GetClaimableRewardAmounts(
2	accumulatedRewardsX128PerStake map[string]*u256.Uint,
3	currentTimestamp int64,
4) (map[string]int64, error)
source

GetClaimableRewardAmounts calculates the claimable reward amounts for all tokens. This includes both accumulated rewards and newly earned rewards based on current state.

Parameters:

  • accumulatedRewardsX128PerStake: current system-wide accumulated rewards per stake for all tokens
  • currentTimestamp: current timestamp

Returns:

  • map[string]int64: map of token path to claimable reward amount
  • error: nil on success, error if claiming is not allowed

func IsClaimable

method on ProtocolFeeRewardStateResolver
1func (p *ProtocolFeeRewardStateResolver) IsClaimable(currentTimestamp int64) bool
source

IsClaimable checks if rewards can be claimed at the given timestamp. Rewards are claimable if the current timestamp is greater than the last claimed timestamp.

Parameters:

  • currentTimestamp: current timestamp to check against

Returns:

  • bool: true if rewards can be claimed, false otherwise

Imports 24

Source Files 23