PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/emission

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
emission
Namespace
gnoswap
Files
10 (README)(gnomod.toml)
Exported functions
n/a — Gnoland RPC unavailable (functions): rpc abci_query: HTTP 500
Module
gno.land/r/gnoswap/emission
gno
0.9

Files (10)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • distribution.gnogno
  • doc.gnogno
  • emission.gnogno
  • errors.gnogno
  • getter.gnogno
  • render.gnogno
  • utils.gnogno
README.mdPreviewRaw
# 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](https://docs.gnoswap.io/gnoswap-token/emission).

## 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

```go
// Set emission start (admin/governance; timestamp must be in the future)
SetDistributionStartTime(cross(cur), futureStartTimestamp)

// Trigger emission (called automatically by protocol flows)
amount, ok := MintAndDistributeGns(cross(cur))

// Update distribution ratios
ChangeDistributionPct(
    cross(cur),
    7000, // 70% to liquidity stakers
    2000, // 20% to devops
    1000, // 10% to community pool
    0,    // 0% to governance stakers
)

// Query distribution info
stakerPct, err := GetDistributionBpsPct(LIQUIDITY_STAKER)
if err != nil {
    panic(err)
}
accumulated := GetAccuDistributedToStaker()
rate, err := GetStakerEmissionAmountPerSecond()
if err != nil {
    panic(err)
}
```

## 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

Functions

Gnoland RPC unavailable (functions): rpc abci_query: HTTP 500

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.