emission source realm
Package emission manages GNS token emission and distribution for GnoSwap.
View source
Emission
GNS token emission and distribution system.
Overview
The emission system controls creation and distribution of new GNS tokens with a deflationary model featuring periodic halvings, ensuring predictable and decreasing supply growth over 12 years. For more details, check out docs.
Token Economics
- Total Supply Cap: 1,000,000,000 GNS
- Initial Minted: 100,000,000 GNS
- To Be Minted: 900,000,000 GNS over 12 years
- Halving Period: Every 2 years (63,072,000 seconds)
- Halving Reduction: 50% decrease in emission rate
- Distribution: Automatic during protocol activity
Configuration
- Distribution Ratios (modifiable by governance):
- Liquidity Staker: 75% (default)
- DevOps: 20% (default)
- Community Pool: 5% (default)
- Governance Staker: 0% (default)
- Start Time: Unix timestamp (immutable once set)
Core Features
Emission Schedule
Implements Bitcoin-style halving model:
- Year 1-2: 100% emission rate
- Year 3-4: 50% emission rate
- Year 5-6: 25% emission rate
- Year 7-8: 12.5% emission rate
- Year 9-12: 6.25% emission rate
Distribution Mechanism
When triggered by protocol activity:
- Calculates elapsed time since last distribution
- Mints GNS based on current emission rate
- Distributes to targets per configured ratios
- Carries forward any undistributed amounts
Key Functions
MintAndDistributeGns
Mints and distributes GNS tokens automatically.
SetDistributionStartTime
One-time setup of emission start timestamp.
ChangeDistributionPct
Updates distribution percentages (admin or governance only).
GetDistributionBpsPct
Returns current distribution percentage in basis points for a target.
Technical Details
Timestamp-Based Emission
emissionPerSecond = baseEmission / (2^halvingCount)
amountToMint = emissionPerSecond * timeSinceLastMint
Halving Calculation
halvingCount = floor(timeSinceStart / halvingPeriod)
Distribution Targets
- Liquidity Staker: Rewards for LP providers
- DevOps: Development and operations fund
- Community Pool: Community-governed treasury
- Governance Staker: GNS staking rewards (currently 0%)
Usage
1// Set emission start (one-time by admin/governance)
2SetDistributionStartTime(cross(cur), 1704067200) // Jan 1, 2024
3
4// Trigger emission (called automatically by protocol flows)
5amount, ok := MintAndDistributeGns(cross(cur))
6
7// Update distribution ratios
8ChangeDistributionPct(
9 cross(cur),
10 7000, // 70% to liquidity stakers
11 2000, // 20% to devops
12 1000, // 10% to community pool
13 0, // 0% to governance stakers
14)
15
16// Query distribution info
17stakerPct := GetDistributionBpsPct(LIQUIDITY_STAKER)
18accumulated := GetAccuDistributedToStaker()
19rate := GetStakerEmissionAmountPerSecond()
Security
- Start time immutable once set and passed
- Distribution percentages must sum to 10000 (100%)
- Automatic triggers prevent manipulation
- Leftover tracking ensures no token loss
- Halving enforced at protocol level
Package emission manages GNS token emission and distribution for GnoSwap.
The emission system controls creation and distribution of new GNS tokens with a deflationary model featuring periodic halvings over 12 years.
Emission Schedule:
- Year 1-2: 100% emission rate (225,000,000 GNS/year)
- Year 3-4: 50% emission rate (112,500,000 GNS/year)
- Year 5-6: 25% emission rate (56,250,000 GNS/year)
- Year 7-8: 12.5% emission rate (28,125,000 GNS/year)
- Year 9-12: 6.25% emission rate (14,062,500 GNS/year)
Distribution Targets (configurable via governance):
- LIQUIDITY_STAKER: Rewards for LP providers (default 75%)
- DEVOPS: Development and operations fund (default 20%)
- COMMUNITY_POOL: Community-governed treasury (default 5%)
- GOV_STAKER: GNS staking rewards (default 0%)
Key Functions:
- MintAndDistributeGns: Mints and distributes GNS per emission schedule
- SetDistributionStartTime: One-time setup of emission start timestamp
- ChangeDistributionPct: Updates distribution percentages
- ClearDistributedToStaker/GovStaker: Resets pending distribution amounts
1
27
func AccumulateDistributedInfo
Actionfunc ChangeDistributionPct
crossing ActionChangeDistributionPct changes distribution percentages for emission targets.
This function redistributes how newly minted GNS tokens are allocated across protocol components. Before applying new ratios, it distributes any accumulated emissions using the current ratios, ensuring emissions are distributed according to the ratios in effect when they were generated. This prevents retroactive application of new ratios to past emissions.
Parameters:
- liquidityStakerPct: Percentage for liquidity stakers in basis points (100 = 1%, 10000 = 100%)
- devOpsPct: Percentage for devops in basis points
- communityPoolPct: Percentage for community pool in basis points
- govStakerPct: Percentage for governance stakers in basis points
Requirements:
- Percentages must sum to exactly 10000 (100%)
- Each percentage must be 0-10000
Example:
Example
1ChangeDistributionPct(
2 7000, // 70% to liquidity stakers
3 2000, // 20% to devops
4 1000, // 10% to community pool
5 0, // 0% to governance stakers
6)
Only callable by admin or governance.
func ClearDistributedToGovStaker
crossing ActionClearDistributedToGovStaker resets the pending distribution amount for governance stakers.
Only callable by governance staker contract.
func ClearDistributedToStaker
crossing ActionClearDistributedToStaker resets the pending distribution amount for liquidity stakers.
Only callable by staker contract.
func GetAccuDistributedToCommunityPool
ActionGetAccuDistributedToCommunityPool returns the total historical GNS distributed to Community Pool.
func GetAccuDistributedToDevOps
ActionGetAccuDistributedToDevOps returns the total historical GNS distributed to DevOps.
func GetAccuDistributedToGovStaker
ActionGetAccuDistributedToGovStaker returns the total historical GNS distributed to governance stakers.
func GetAccuDistributedToStaker
ActionGetAccuDistributedToStaker returns the total historical GNS distributed to liquidity stakers.
func GetAllDistributionBpsPct
ActionGetAllDistributionBpsPct returns all distribution percentages in basis points.
func GetDistributableAmount
ActionGetDistributableAmount returns distribution amounts by target and the remainder. If timestamp is outside the distribution window, it returns an empty map and the full amount as left.
func GetDistributedToCommunityPool
ActionGetDistributedToCommunityPool returns the amount of GNS distributed to Community Pool.
func GetDistributedToDevOps
ActionGetDistributedToDevOps returns accumulated GNS for DevOps.
func GetDistributedToGovStaker
ActionGetDistributedToGovStaker returns the amount of GNS distributed to governance stakers since last clear.
func GetDistributedToStaker
ActionGetDistributedToStaker returns pending GNS for liquidity stakers.
func GetDistributionBpsPct
ActionGetDistributionBpsPct returns the distribution percentage in basis points for a specific target.
func GetDistributionEndTimestamp
ActionGetDistributionEndTimestamp returns the timestamp when emission distribution ends. Returns 0 if distribution has not been started yet.
func GetDistributionStartTimestamp
ActionGetDistributionStartTimestamp returns the timestamp when emission distribution started. Returns 0 if distribution has not been started yet.
func GetEmissionAmountPerSecondBy
ActionGetEmissionAmountPerSecondBy returns the emission amount per second for a given timestamp and distribution percentage.
func GetLastExecutedTimestamp
ActionGetLastExecutedTimestamp returns the timestamp of the last emission distribution execution.
func GetLeftGNSAmount
ActionGetLeftGNSAmount returns the amount of undistributed GNS tokens from previous distributions.
func GetStakerEmissionAmountPerSecond
ActionGetStakerEmissionAmountPerSecond returns the current per-second emission amount allocated to liquidity stakers.
func GetStakerEmissionAmountPerSecondInRange
ActionGetStakerEmissionAmountPerSecondInRange returns emission amounts allocated to liquidity stakers for a time range.
func GetTotalAccuDistributed
ActionGetTotalAccuDistributed returns the total accumulated distributed GNS amount.
func GetTotalDistributed
ActionGetTotalDistributed returns the total pending distributed GNS amount.
func MintAndDistributeGns
crossing ActionMintAndDistributeGns mints and distributes GNS tokens according to the emission schedule.
This function is called automatically by protocol contracts during user interactions to trigger periodic GNS emission. It mints new tokens based on elapsed time since last distribution and distributes them to predefined targets (staker, devops, etc.).
Returns:
- int64: Total amount of GNS distributed in this call
Note: Distribution only occurs if start timestamp is set and reached. Any undistributed tokens from previous calls are carried forward.
func SetDistributionStartTime
crossing ActionSetDistributionStartTime sets the timestamp when emission distribution starts.
This function controls when GNS emission begins. Once set and reached, the protocol starts minting GNS tokens according to the emission schedule. The timestamp can only be set before distribution starts - it becomes immutable once active.
Parameters:
- startTimestamp: Unix timestamp when emission should begin
Requirements:
- Must be called before distribution starts (one-time setup)
- Timestamp must be in the future
- Cannot be negative
Effects:
- Sets global distribution start time
- Initializes GNS emission state if not already started
- Emission begins automatically when timestamp is reached
Only callable by admin or governance.
func SetOnDistributionPctChangeCallback
crossing Action1func SetOnDistributionPctChangeCallback(cur realm, callback func(cur realm, emissionAmountPerSecond int64))SetOnDistributionPctChangeCallback sets a callback function to be called when distribution percentages change. This allows external contracts (like staker) to update their internal caches when governance changes emission rates.
Only callable by the staker contract.
11
- chain stdlib
- chain/runtime stdlib
- gno.land/p/gnoswap/gnsmath package
- gno.land/p/gnoswap/rbac package
- gno.land/p/gnoswap/utils package
- gno.land/p/nt/ufmt/v0 package
- gno.land/r/gnoswap/access realm
- gno.land/r/gnoswap/gns realm
- gno.land/r/gnoswap/halt realm
- math stdlib
- time stdlib