/r/gnoswap/gov/staker/v1
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
- Open
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.
MintAndStake
Mints new position and stakes in single transaction.
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:
- Cache pool rewards up to current block
- Retrieve position state from deposit records
- Calculate internal rewards if pool is tiered
- Calculate external rewards for active incentives
- 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:
- Updates staked liquidity - Adjusts total staked liquidity
- Updates reward accumulation - Recalculates
globalRewardRatioAccumulation - Manages unclaimable periods - Starts/ends periods with no in-range liquidity
- 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