PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

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/gov/staker

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
staker
Namespace
gnoswap / gov
Files
24 (README)(gnomod.toml)
Exported functions
57
Module
gno.land/r/gnoswap/gov/staker
gno
0.9

Files (24)

  • README.mdmarkdown
  • gnomod.tomltoml
  • counter.gnogno
  • delegation_manager.gnogno
  • delegation_withdraw.gnogno
  • delegation.gnogno
  • doc.gnogno
  • emission_reward_manager.gnogno
  • emission_reward_state.gnogno
  • errors.gnogno
  • getter_utils.gnogno
  • getters.gnogno
  • launchpad_project_deposits.gnogno
  • protocol_fee_reward_manager.gnogno
  • protocol_fee_reward_state.gnogno
  • protocol_fee_token_accumulator.gnogno
  • proxy.gnogno
  • render.gnogno
  • state.gnogno
  • store.gnogno
  • tree.gnogno
  • types.gnogno
  • upgrade.gnogno
  • util.gnogno
README.mdPreviewRaw
# Gov Staker

Governance delegation and xGNS-based voting power management.

## Overview

Gov Staker accepts GNS staking, mints and burns xGNS, maintains delegatee balances and timestamped delegation history, tracks undelegation lockups, and settles two reward streams for stakers: GNS emission rewards and protocol-fee rewards in any registered token.

## Configuration

- **Undelegation Lockup**: configurable; the default is 7 days before undelegated GNS can be collected.
- **Reward Sources**: GNS emission (single token) and protocol-fee distribution (one accumulator per fee token).
- **Delegation State**: per-delegator/delegatee records, total and user timestamp histories, and reward stake events.

## Core Features

### Delegation

- Delegate GNS to any valid address; the delegated amount is mirrored as xGNS voting power.
- Redelegate between delegatees without a lockup. Redelegation performs an immediate remove-plus-add for reward accounting.
- Track undelegated balances until the configured lockup expires; collecting then burns the corresponding xGNS and returns GNS.

### Rewards

- `CollectReward` claims both the emission stream and all known protocol-fee tokens.
- `CollectEmissionReward` claims only GNS emission rewards.
- `CollectProtocolFeeReward` claims one protocol-fee token; its bucket and stake-event work is bounded per call, so remaining work is collected later.
- Launchpad can collect the matching emission and protocol-fee rewards for a registered project wallet through launchpad-only entry points.

Protocol-fee rewards are not calculated as a single current-balance share. Each token's fee buckets are divided by the total stake in force during their accrual epochs, accumulated in Q128 fixed point, and settled across each staker's timestamped stake-event segments. Fractional remainders remain in state for later collection.

### History and Snapshots

- Historical delegation snapshots are timestamp lookups used by governance's configured smoothing calculation; they are not block-height snapshots.
- Cleanup functions preserve history needed by active proposals.

## Key Functions

### `Delegate`

Transfers GNS from the caller, mints the same amount of xGNS, and assigns the delegated voting power to a target address. The caller must approve the GNS transfer first.

### `Undelegate`

Removes voting power immediately and creates a withdrawal subject to the configured lockup.

### `Redelegate`

Moves delegated balance from one delegatee to another immediately, without creating a user-facing lockup.

### `CollectReward`

Claims the caller's GNS emission rewards and all known protocol-fee rewards. The all-token path intentionally grows with the number of known fee tokens.

### `CollectEmissionReward`

Claims only the caller's accumulated GNS emission reward.

### `CollectProtocolFeeReward`

Claims one token path's accumulated protocol-fee reward. A later call may be required when pending accrual buckets or stake events exceed the per-call bound.

### `CollectUndelegatedGns`

Collects GNS after the configured undelegation lockup has passed and burns the corresponding xGNS.

### `CollectRewardFromLaunchPad`

Collects both reward streams for a registered launchpad project wallet. This entry point is callable only by the launchpad contract and sends rewards to the supplied project-wallet address.

## Delegation Logic

### Delegation Flow

1. Approve GNS spending by the gov/staker realm.
2. Delegate GNS to a delegatee; xGNS is minted and timestamped history is updated.
3. Governance reads the delegatee's history at proposal-defined timestamps for vote weight.
4. Undelegate to start the lockup, or redelegate immediately to another delegatee.
5. After the lockup expires, collect undelegated GNS.

## Usage

These snippets call the public domain proxy from a realm function with a current `cur` token.
Import the proxy package and qualify its function names in integrating code.

```go
// Delegate GNS to another address; xGNS voting power is minted 1:1.
delegatedAmount := Delegate(cross(cur), delegatee, 1_000_000_000, "g1referrer...")

// Redelegate part of the active balance immediately.
Redelegate(cross(cur), delegatee, newDelegatee, 500_000_000)

// Claim both GNS emission and all known protocol-fee tokens.
CollectReward(cross(cur))

// Or claim only one stream/token.
CollectEmissionReward(cross(cur))
CollectProtocolFeeReward(cross(cur), tokenPath)

// Start undelegation. Collect only after the configured lockup (7 days by default).
Undelegate(cross(cur), delegatee, 250_000_000)
// ...wait until the lockup has expired...
CollectUndelegatedGns(cross(cur))
```

## Security

- Timestamped delegation history and configurable smoothing reduce flash-loan-style voting manipulation; they do not provide a block snapshot.
- Undelegation removes voting power immediately, while the lockup delays GNS withdrawal.
- Protocol-fee stake changes must remain independent of the number of fee tokens; only collection folds fee buckets.
- Launchpad reward entry points are restricted to the launchpad contract and registered project wallets.
- Snapshot cleanup must preserve data still needed by active proposals.

Functions

  • CleanStakerDelegationSnapshotByAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, threshold int64, target string)

  • CollectEmissionReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • CollectEmissionRewardFromLaunchPad(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string)

  • CollectProtocolFeeReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, tokenPath string)

  • CollectProtocolFeeRewardFromLaunchPad(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, tokenPath string)

  • CollectReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • CollectRewardFromLaunchPad(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string)

  • CollectUndelegatedGns(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) int64

  • Delegate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, amount int64, referrer string) int64

  • ExistsDelegation(delegationID int64) bool

  • GetClaimableRewardByAddress(addr string) (int64, map[string]int64, interface {Error func() string})

  • GetClaimableRewardByLaunchpad(addr string) (int64, map[string]int64, interface {Error func() string})

  • GetClaimableRewardByRewardID(rewardID string) (int64, map[string]int64, interface {Error func() string})

  • GetCollectableWithdrawAmount(delegationID int64) int64

  • GetDelegations() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

  • GetDelegationWithdrawCount(delegationID int64) int

  • GetDelegationWithdraws(delegationID int64, offset int, count int) ([]gno.land/r/gnoswap/gov/staker.DelegationWithdraw, interface {Error func() string})

  • GetDelegatorDelegations(delegator string) *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

  • GetEmissionAccumulatedTimestamp() int64

  • GetEmissionAccumulatedX128PerStake() *gno.land/p/gnoswap/uint256/v1.Uint

  • GetEmissionDistributedAmount() int64

  • GetImplementationPackagePath() string

  • GetLaunchpadProjectDeposit(projectAddr string) (int64, bool)

  • GetProtocolFeeAccumulatedTimestamp() int64

  • GetProtocolFeeAccumulatedX128PerStake(tokenPath string) *gno.land/p/gnoswap/uint256/v1.Uint

  • GetProtocolFeeAmount(tokenPath string) int64

  • GetTotalDelegated() int64

  • GetTotalDelegationAmountAtSnapshot(snapshotTime int64) (int64, bool)

  • GetTotalLockedAmount() int64

  • GetTotalxGnsSupply() int64

  • GetUnDelegationLockupPeriod() int64

  • GetUserDelegationAmountAtSnapshot(userAddr string, snapshotTime int64) (int64, bool)

  • GetUserDelegationIDs(delegator string, delegatee string) []int64

  • HasDelegationSnapshotsKey() bool

  • NewCounter() *gno.land/r/gnoswap/gov/staker.Counter

  • NewDelegation(id int64, delegateFrom string, delegateTo string, delegateAmount int64, createdHeight int64, createdAt int64) *gno.land/r/gnoswap/gov/staker.Delegation

  • NewDelegationManager() *gno.land/r/gnoswap/gov/staker.DelegationManager

  • NewDelegationTree() *gno.land/p/nt/bptree/v0.BPTree

  • NewDelegationWithdraw(delegationID int64, unDelegateAmount int64, createdHeight int64, createdAt int64, unDelegationLockupPeriod int64) struct{delegationID int64; unDelegateAmount int64; unDelegatedHeight int64; unDelegatedAt int64; collectedAmount int64; collectableTime int64; collectedAt int64; collected bool}

  • NewDelegationWithdrawWithoutLockup(delegationID int64, unDelegateAmount int64, createdHeight int64, createdAt int64) struct{delegationID int64; unDelegateAmount int64; unDelegatedHeight int64; unDelegatedAt int64; collectedAmount int64; collectableTime int64; collectedAt int64; collected bool}

  • NewEmissionRewardManager() *gno.land/r/gnoswap/gov/staker.EmissionRewardManager

  • NewEmissionRewardState(accumulatedRewardX128PerStake *gno.land/p/gnoswap/uint256/v1.Uint) *gno.land/r/gnoswap/gov/staker.EmissionRewardState

  • NewGovStakerStore(kvStore interface {AddAuthorizedCaller func(int, .uverse.realm, .uverse.address, gno.land/p/gnoswap/store/v1.Permission) .uverse.error; Delete func(int, .uverse.realm, string) .uverse.error; Get func(string) (interface {}, .uverse.error); GetAddress func(string) (.uverse.address, .uverse.error); GetAllKeys func() ([]string, .uverse.error); GetAuthorizedCallers func() (map[.uverse.address]gno.land/p/gnoswap/store/v1.Permission, .uverse.error); GetBPTree func(string) (*gno.land/p/nt/bptree/v0.BPTree, .uverse.error); GetBool func(string) (bool, .uverse.error); GetDomainAddress func() .uverse.address; GetInt64 func(string) (int64, .uverse.error); GetString func(string) (string, .uverse.error); GetUint64 func(string) (uint64, .uverse.error); Has func(string) bool; IsWriteAuthorized func(.uverse.address) bool; RemoveAuthorizedCaller func(int, .uverse.realm, .uverse.address) .uverse.error; Set func(int, .uverse.realm, string, interface {}) .uverse.error; UpdateAuthorizedCaller func(int, .uverse.realm, .uverse.address, gno.land/p/gnoswap/store/v1.Permission) .uverse.error}) interface {GetAllDelegations func() *gno.land/p/nt/bptree/v0.BPTree; GetDelegation func(int64) (*gno.land/r/gnoswap/gov/staker.Delegation, bool); GetDelegationCounter func() *gno.land/r/gnoswap/gov/staker.Counter; GetDelegationManager func() *gno.land/r/gnoswap/gov/staker.DelegationManager; GetEmissionRewardManager func() *gno.land/r/gnoswap/gov/staker.EmissionRewardManager; GetLaunchpadProjectDeposits func() *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits; GetProtocolFeeRewardManager func() *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager; GetTotalDelegatedAmount func() int64; GetTotalDelegationHistory func() *gno.land/r/gnoswap/gov/staker.UintTree; GetTotalLockedAmount func() int64; GetUnDelegationLockupPeriod func() int64; GetUserDelegationHistory func() *gno.land/p/nt/bptree/v0.BPTree; HasDelegation func(int64) bool; HasDelegationCounterStoreKey func() bool; HasDelegationManagerStoreKey func() bool; HasDelegationsStoreKey func() bool; HasEmissionRewardManagerStoreKey func() bool; HasLaunchpadProjectDepositsStoreKey func() bool; HasProtocolFeeRewardManagerStoreKey func() bool; HasTotalDelegatedAmountStoreKey func() bool; HasTotalDelegationHistoryStoreKey func() bool; HasTotalLockedAmountStoreKey func() bool; HasUnDelegationLockupPeriodStoreKey func() bool; HasUserDelegationHistoryStoreKey func() bool; RemoveDelegation func(int, .uverse.realm, int64) .uverse.error; SetDelegation func(int, .uverse.realm, int64, *gno.land/r/gnoswap/gov/staker.Delegation) .uverse.error; SetDelegationCounter func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.Counter) .uverse.error; SetDelegationManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.DelegationManager) .uverse.error; SetDelegations func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetEmissionRewardManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.EmissionRewardManager) .uverse.error; SetLaunchpadProjectDeposits func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits) .uverse.error; SetProtocolFeeRewardManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager) .uverse.error; SetTotalDelegatedAmount func(int, .uverse.realm, int64) .uverse.error; SetTotalDelegationHistory func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.UintTree) .uverse.error; SetTotalLockedAmount func(int, .uverse.realm, int64) .uverse.error; SetUnDelegationLockupPeriod func(int, .uverse.realm, int64) .uverse.error; SetUserDelegationHistory func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error}

  • NewLaunchpadProjectDeposits() *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits

  • NewProtocolFeeRewardManager() *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager

  • NewProtocolFeeRewardState() *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardState

  • NewProtocolFeeTokenAccumulator() *gno.land/r/gnoswap/gov/staker.ProtocolFeeTokenAccumulator

  • NewProtocolFeeTokenRewardState(eventCursor int64, segmentStakedAmount int64, segmentStartX128 *gno.land/p/gnoswap/uint256/v1.Uint) *gno.land/r/gnoswap/gov/staker.ProtocolFeeTokenRewardState

  • NewUintTree() *gno.land/r/gnoswap/gov/staker.UintTree

  • NewUserDelegationTree() *gno.land/p/nt/bptree/v0.BPTree

  • Redelegate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, delegatee string, newDelegatee string, amount int64) int64

  • RegisterInitializer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, initializer func(int, .uverse.realm, gno.land/r/gnoswap/gov/staker.IGovStakerStore) gno.land/r/gnoswap/gov/staker.IGovStaker)

  • Render(path string) string

  • SetAmountByProjectWallet(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string, amount int64, add bool)

  • SetUnDelegationLockupPeriodByAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, period int64)

  • Undelegate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, from string, amount int64) int64

  • UpgradeImpl(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, packagePath string)

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.