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

emission source realm

Package emission manages GNS token emission and distribution for GnoSwap.

Readme 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, pre-minted to the configured ADMIN role address during GNS realm initialization
  • 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 admin or governance):
    • Liquidity Staker: 75% (default)
    • DevOps: 20% (default)
    • Community Pool: 5% (default)
    • Governance Staker: 0% (default)
  • Start Time: Unix timestamp. It may be changed while the configured timestamp is still in the future; once active, it cannot be changed.

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:

  1. Calculates elapsed time since last distribution
  2. Mints GNS based on the current timestamp range and halving-year rates
  3. Distributes to targets per configured ratios
  4. Carries forward any undistributed amounts

If emission is halted, MintAndDistributeGns returns (0, false) without panicking. A caller that requires emission must explicitly handle that result.

Key Functions

MintAndDistributeGns

Mints and distributes GNS tokens automatically.

SetDistributionStartTime

Sets or reschedules the emission start timestamp before distribution is active. The timestamp must be positive and in the future; after the configured start time has been reached, the timestamp is immutable.

ChangeDistributionPct

Updates distribution percentages (admin or governance only).

GetDistributionBpsPct

Returns current distribution percentage in basis points for a target, or an error if the target is invalid.

Gnoweb

Render("") shows distribution dates in UTC, GNS amounts with six decimal places, allocation percentages, and cumulative distributions for the four recipients. Staker and governance-staker counters since their last accounting clear are shown separately: these allocations have already been transferred and are not wallet balances or user-claimable rewards. Unsupported paths return 404.

Technical Details

Timestamp-Based Emission

The following is a conceptual view of the schedule:

emissionPerSecond = baseEmission / (2^halvingCount)
amountToMint = emissionPerSecond * elapsedSeconds

The implementation uses integer, piecewise rates. For each halving year intersecting the inclusive mint range [fromTimestamp, toTimestamp], it initializes yearAmountPerSecond as floor(yearDistributionAmount / SECONDS_IN_YEAR) and multiplies that rate by the inclusive number of seconds. The mint range is clamped to the 12-year schedule end. When a range reaches a year end, the remaining integer amount (including division dust) is added so that the year's allocation is exhausted.

Halving Calculation

Halving years are determined by the schedule's year boundaries; the conceptual form is:

halvingCount = floor(timeSinceStart / halvingPeriod)

Distribution Targets

  1. Liquidity Staker: Rewards for LP providers
  2. DevOps: Development and operations fund
  3. Community Pool: Community-governed treasury
  4. Governance Staker: GNS staking rewards (currently 0%)

Usage

 1// Set emission start (admin/governance; timestamp must be in the future)
 2SetDistributionStartTime(cross(cur), futureStartTimestamp)
 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, err := GetDistributionBpsPct(LIQUIDITY_STAKER)
18if err != nil {
19    panic(err)
20}
21accumulated := GetAccuDistributedToStaker()
22rate, err := GetStakerEmissionAmountPerSecond()
23if err != nil {
24    panic(err)
25}

Security

  • Start time may be rescheduled while still in the future and is immutable once active
  • Distribution percentages must sum to 10000 (100%)
  • A halted MintAndDistributeGns call returns false; no automatic cross-module cascade occurs
  • If staker cache invalidation is required, keep the optional distribution-change callback registered
  • Leftover tracking carries undistributed amounts forward
  • Halving is enforced at protocol level

Overview

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 admin or governance):

  • LIQUIDITY_STAKER: Rewards for LP providers (default 75%)
  • DEVOPS: Development and operations fund (default 20%)
  • COMMUNITY_POOL: Community treasury (default 5%)
  • GOV_STAKER: GNS staking rewards (default 0%)

Key Functions:

  • MintAndDistributeGns: Mints and distributes GNS per emission schedule; returns false only when emission is halted.
  • SetDistributionStartTime: Sets or reschedules the start timestamp while it is still in the future; the timestamp is immutable once active.
  • ChangeDistributionPct: Updates distribution percentages
  • ClearDistributedToStaker/GovStaker: Resets pending distribution amounts

Constants 2

const totalDistributionDuration, DefaultInitialPoolTierPath

1const (
2	totalDistributionDuration = 12 * 365 * 24 * 60 * 60 // 12 years
3
4	// DefaultInitialPoolTierPath is the canonical default initial pool that must
5	// exist before emission distribution can start. The pool contract registers a
6	// checker (SetDefaultInitialPoolChecker) that verifies this pool exists.
7	DefaultInitialPoolTierPath = "gno.land/r/gnoland/wugnot.wugnot:gno.land/r/gnoswap/gns.GNS:3000"
8)
source

Functions 29

func AccumulateDistributedInfo

Action
1func AccumulateDistributedInfo() (toStaker, toDevOps, toCommunityPool, toGovStaker int64)
source

AccumulateDistributedInfo returns the current pending allocation for every distribution target.

Returns:

  • toStaker: pending GNS allocation for liquidity stakers, in token base units.
  • toDevOps: accumulated GNS allocation for DevOps, in token base units.
  • toCommunityPool: accumulated GNS allocation for the community pool, in token base units.
  • toGovStaker: pending GNS allocation for governance stakers, in token base units.

func ChangeDistributionPct

crossing Action
1func ChangeDistributionPct(
2	cur realm,
3	liquidityStakerPct int64,
4	devOpsPct int64,
5	communityPoolPct int64,
6	govStakerPct int64,
7)
source

ChangeDistributionPct 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:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.
  • liquidityStakerPct: percentage for liquidity stakers in basis points (100 = 1%, 10000 = 100%).
  • devOpsPct: percentage for DevOps in basis points (100 = 1%, 10000 = 100%).
  • communityPoolPct: percentage for the community pool in basis points (100 = 1%, 10000 = 100%).
  • govStakerPct: percentage for governance stakers in basis points (100 = 1%, 10000 = 100%).

Requirements:

  • Percentages must sum to exactly 10000 (100%).
  • Each percentage must be between 0 and 10000 inclusive.

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 Action
1func ClearDistributedToGovStaker(cur realm)
source

ClearDistributedToGovStaker resets the pending distribution amount for governance stakers.

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.

Only callable by governance staker contract.

func ClearDistributedToStaker

crossing Action
1func ClearDistributedToStaker(cur realm)
source

ClearDistributedToStaker resets the pending distribution amount for liquidity stakers.

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.

Only callable by staker contract.

func GetAccuDistributedToCommunityPool

Action
1func GetAccuDistributedToCommunityPool() int64
source

GetAccuDistributedToCommunityPool returns the total historical GNS amount allocated to the community pool.

Returns:

  • amount: cumulative community-pool allocation in GNS base units; this value is not cleared.

func GetAccuDistributedToDevOps

Action
1func GetAccuDistributedToDevOps() int64
source

GetAccuDistributedToDevOps returns the total historical GNS amount allocated to DevOps.

Returns:

  • amount: cumulative DevOps allocation in GNS base units; this value is not cleared.

func GetAccuDistributedToGovStaker

Action
1func GetAccuDistributedToGovStaker() int64
source

GetAccuDistributedToGovStaker returns the total historical GNS amount allocated to governance stakers.

Returns:

  • amount: cumulative governance-staker allocation in GNS base units; this value is not cleared.

func GetAccuDistributedToStaker

Action
1func GetAccuDistributedToStaker() int64
source

GetAccuDistributedToStaker returns the total historical GNS amount allocated to liquidity stakers.

Returns:

  • amount: cumulative liquidity-staker allocation in GNS base units; this value is not cleared.

func GetAllDistributionBpsPct

Action
1func GetAllDistributionBpsPct() map[int]int64
source

GetAllDistributionBpsPct returns all distribution percentages in basis points.

Returns:

  • percentages: map of target to percentage in basis points

func GetDistributableAmount

Action
1func GetDistributableAmount(amount, timestamp int64) (map[int]int64, int64)
source

GetDistributableAmount 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.

Parameters:

  • amount: total amount to distribute
  • timestamp: timestamp to check distribution window

Returns:

  • distributions: map of target to distribution amount
  • remainder: undistributed amount

func GetDistributedToCommunityPool

Action
1func GetDistributedToCommunityPool() int64
source

GetDistributedToCommunityPool returns the GNS amount currently accumulated for the community pool.

Returns:

  • amount: accumulated community-pool allocation in GNS base units.

func GetDistributedToDevOps

Action
1func GetDistributedToDevOps() int64
source

GetDistributedToDevOps returns the GNS amount currently accumulated for DevOps.

Returns:

  • amount: accumulated DevOps allocation in GNS base units.

func GetDistributedToGovStaker

Action
1func GetDistributedToGovStaker() int64
source

GetDistributedToGovStaker returns the pending GNS amount allocated to governance stakers.

Returns:

  • amount: pending governance-staker allocation in GNS base units since the last clear.

func GetDistributedToStaker

Action
1func GetDistributedToStaker() int64
source

GetDistributedToStaker returns the pending GNS amount allocated to liquidity stakers.

Returns:

  • amount: pending liquidity-staker allocation in GNS base units since the last clear.

func GetDistributionBpsPct

Action
1func GetDistributionBpsPct(target int) (int64, error)
source

GetDistributionBpsPct returns the configured distribution percentage in basis points for a target.

Parameters:

  • target: distribution target constant whose configured share is queried.

Returns:

  • pct: configured target share in basis points (100 = 1%, 10000 = 100%).
  • error: nil when the target exists in the initialized map; otherwise an invalid-target error.

func GetDistributionEndTimestamp

Action
1func GetDistributionEndTimestamp() int64
source

GetDistributionEndTimestamp returns the timestamp when emission distribution ends.

Returns:

  • timestamp: distribution end timestamp, or 0 if not started

func GetDistributionStartTimestamp

Action
1func GetDistributionStartTimestamp() int64
source

GetDistributionStartTimestamp returns the configured emission start timestamp. The value may be in the future; it is 0 when no start timestamp is configured.

Returns:

  • timestamp: configured distribution start timestamp, or 0 if unconfigured

func GetEmissionAmountPerSecondBy

Action
1func GetEmissionAmountPerSecondBy(timestamp, distributionPct int64) int64
source

GetEmissionAmountPerSecondBy returns the GNS emission rate per second for a timestamp and target share.

Parameters:

  • timestamp: Unix timestamp at which the base emission rate is queried.
  • distributionPct: target share in basis points, from 0 through 10000 inclusive.

Returns:

  • amountPerSecond: target's GNS emission rate in token base units per second, or zero outside the schedule.

func GetLastExecutedTimestamp

Action
1func GetLastExecutedTimestamp() int64
source

GetLastExecutedTimestamp returns the timestamp of the last emission distribution execution.

Returns:

  • timestamp: last execution timestamp

func GetLeftGNSAmount

Action
1func GetLeftGNSAmount() int64
source

GetLeftGNSAmount returns the amount of undistributed GNS tokens from previous distributions.

Returns:

  • amount: undistributed GNS amount

func GetStakerEmissionAmountPerSecond

Action
1func GetStakerEmissionAmountPerSecond() (int64, error)
source

GetStakerEmissionAmountPerSecond returns the current GNS emission rate allocated to liquidity stakers.

Returns:

  • amountPerSecond: current liquidity-staker emission rate in GNS base units per second.
  • error: nil when the liquidity-staker distribution share is available; otherwise the target lookup error.

func GetStakerEmissionAmountPerSecondInRange

Action
1func GetStakerEmissionAmountPerSecondInRange(start, end int64) ([]int64, []int64, error)
source

GetStakerEmissionAmountPerSecondInRange returns liquidity-staker emission-rate change points in a time range.

Parameters:

  • start: inclusive start Unix timestamp for the range.
  • end: inclusive end Unix timestamp for the range.

Returns:

  • timestamps: ordered timestamps in the range where the base emission rate changes.
  • amountsPerSecond: liquidity-staker GNS rates corresponding to timestamps, in token base units per second.
  • error: nil when the liquidity-staker distribution share is available; otherwise the target lookup error.

func GetTotalAccuDistributed

Action
1func GetTotalAccuDistributed() int64
source

GetTotalAccuDistributed returns the total accumulated distributed GNS amount.

Returns:

  • amount: total accumulated distributed GNS

func GetTotalDistributed

Action
1func GetTotalDistributed() int64
source

GetTotalDistributed returns the total pending distributed GNS amount.

Returns:

  • amount: total pending distributed GNS

func MintAndDistributeGns

crossing Action
1func MintAndDistributeGns(cur realm) (int64, bool)
source

MintAndDistributeGns 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.).

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.

Returns:

  • distributedAmount: total amount of GNS distributed in this call
  • success: false only when emission is halted; true when processing completes, even if no tokens are distributed

Note: Distribution only occurs if start timestamp is set and reached. Any undistributed tokens from previous calls are carried forward.

func Render

1func Render(path string) string
source

Render returns the current GNS emission and distribution state.

func SetDefaultInitialPoolChecker

crossing Action
1func SetDefaultInitialPoolChecker(cur realm, checker func(poolPath string) bool)
source

SetDefaultInitialPoolChecker registers the callback that verifies the canonical default initial pool exists before emission starts.

The checker receives the pool path as a parameter so emission owns the canonical path policy (DefaultInitialPoolTierPath) while pool supplies only the generic "does this pool exist" capability.

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.
  • checker: nonnil function returning true when the supplied pool path exists; it is called with DefaultInitialPoolTierPath and nil causes a panic.

Only callable by the pool contract.

func SetDistributionStartTime

crossing Action
1func SetDistributionStartTime(cur realm, startTimestamp int64)
source

SetDistributionStartTime sets the timestamp when emission distribution starts.

This function controls when GNS emission begins. Before the configured timestamp is reached, an admin or governance caller may reschedule it. Once the timestamp is reached, the start time is immutable.

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.
  • startTimestamp: positive future Unix timestamp when emission should begin.

Requirements:

  • Must be called before distribution starts.
  • Timestamp must be in the future and leave room for the 12-year schedule.

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 Action
1func SetOnDistributionPctChangeCallback(cur realm, callback func(cur realm, emissionAmountPerSecond int64))
source

SetOnDistributionPctChangeCallback registers the optional callback invoked when distribution percentages change. A nil callback clears the registration. This allows external contracts (like staker) to update their internal caches when governance or admin changes emission rates.

Parameters:

  • cur: Current realm context; callers use cross(cur) when crossing into this realm.
  • callback: nil to clear the callback, or a function receiving its callback realm context and the current staker GNS emission rate per second; a nonnil callback is invoked immediately after registration.

Imports 14

Source Files 10