Transaction

251283B29472A0…E80F9690D43C

Block 77,260 · index 0 · indexed

Summary

Hash
251283B29472A065F06D4BCE67EA2974874CF3FAB7527A7D0BE7E80F9690D43C
Block
77,260
Size
137633 bytes
Gas used
173,837,506 / 208,604,948
Fee
208605ugnot
Status
success

Messages

#1AddPackagegno.land/r/gnoswap/gov/staker24 arguments

Arguments · 24

  1. #1staker
  2. #2README.md
  3. #3# 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.
  4. #4counter.gno
  5. #5package staker type Counter struct { id int64 } // NewCounter creates a counter initialized before the first allocated identifier. // // Returns: // - *Counter: counter whose current identifier is zero. func NewCounter() *Counter { return &Counter{id: 0} } // Get returns the counter's current identifier without incrementing it. // // Returns: // - int64: most recently allocated identifier, or zero for a new counter. func (c *Counter) Get() int64 { return c.id } // Next increments the counter and returns the newly allocated identifier. // // Returns: // - int64: next identifier after incrementing the counter by one. func (c *Counter) Next() int64 { c.id++ return c.id }
  6. #6delegation.gno
  7. #7package staker import bptree "gno.land/p/nt/bptree/v0" // DelegationType represents the type of delegation operation type DelegationType string const ( DelegateType DelegationType = "DELEGATE" UnDelegateType DelegationType = "UNDELEGATE" ) // String returns the textual operation name represented by the delegation type. // // Returns: // - string: "DELEGATE", "UNDELEGATE", or the underlying value for another type. func (d DelegationType) String() string { return string(d) } // IsDelegate reports whether the operation type is DelegateType. // // Returns: // - bool: true only when d represents a delegation operation. func (d DelegationType) IsDelegate() bool { return d == DelegateType } // IsUnDelegate reports whether the operation type is UnDelegateType. // // Returns: // - bool: true only when d represents an undelegation operation. func (d DelegationType) IsUnDelegate() bool { return d == UnDelegateType } // Delegation represents a delegation between two addresses type Delegation struct { id int64 delegateAmount int64 unDelegateAmount int64 collectedAmount int64 delegateFrom address delegateTo address createdHeight int64 createdAt int64 withdraws []DelegationWithdraw } // NewDelegation creates a delegation record with no undelegated or collected amount. // // Parameters: // - id: unique identifier assigned to this delegation record. // - delegateFrom: address whose tokens are delegated. // - delegateTo: address receiving the delegated voting power. // - delegateAmount: initial delegated token amount in the smallest token unit. // - createdHeight: block height at which the delegation was created. // - createdAt: Unix timestamp at which the delegation was created. // // Returns: // - *Delegation: initialized delegation with empty withdrawal history. func NewDelegation( id int64, delegateFrom, delegateTo address, delegateAmount, createdHeight, createdAt int64, ) *Delegation { return &Delegation{ id: id, delegateFrom: delegateFrom, delegateTo: delegateTo, delegateAmount: delegateAmount, createdHeight: createdHeight, createdAt: createdAt, unDelegateAmount: 0, collectedAmount: 0, withdraws: make([]DelegationWithdraw, 0), } } // Basic getters // ID returns the unique identifier of the delegation record. // // Returns: // - int64: delegation identifier assigned at creation. func (d *Delegation) ID() int64 { return d.id } // DelegateFrom returns the address that supplied the delegated tokens. // // Returns: // - address: delegator address recorded on the delegation. func (d *Delegation) DelegateFrom() address { return d.delegateFrom } // DelegateTo returns the address receiving the delegated voting power. // // Returns: // - address: delegatee address recorded on the delegation. func (d *Delegation) DelegateTo() address { return d.delegateTo } // CreatedAt returns the Unix timestamp recorded when the delegation was created. // // Returns: // - int64: creation timestamp in Unix seconds. func (d *Delegation) CreatedAt() int64 { return d.createdAt } // Amount getters // TotalDelegatedAmount returns the current amount still actively delegated. // // Returns: // - int64: active delegated token amount in the smallest token unit. func (d *Delegation) TotalDelegatedAmount() int64 { return d.delegateAmount } // UnDelegatedAmount returns the amount moved into undelegation lockup. // // Returns: // - int64: token amount awaiting collection after its lockup period. func (d *Delegation) UnDelegatedAmount() int64 { return d.unDelegateAmount } // CollectedAmount returns the amount already collected from undelegation. // // Returns: // - int64: token amount released from this delegation. func (d *Delegation) CollectedAmount() int64 { return d.collectedAmount } // Withdraws getters // Withdraws returns the delegation's withdrawal records. // // Returns: // - []DelegationWithdraw: withdrawal entries tracked for this delegation. func (d *Delegation) Withdraws() []DelegationWithdraw { return d.withdraws } // Setters // SetUnDelegateAmount replaces the amount currently in undelegation lockup. // // Parameters: // - amount: token amount awaiting collection in the smallest token unit. func (d *Delegation) SetUnDelegateAmount(amount int64) { d.unDelegateAmount = amount } // SetCollectedAmount replaces the amount already collected from this delegation. // // Parameters: // - amount: released token amount in the smallest token unit. func (d *Delegation) SetCollectedAmount(amount int64) { d.collectedAmount = amount } // AddWithdraw appends a withdrawal record to the delegation history. // // Parameters: // - withdraw: withdrawal record to append, including its amount and unlock timing. func (d *Delegation) AddWithdraw(withdraw DelegationWithdraw) { d.withdraws = append(d.withdraws, withdraw) } // SetWithdraw replaces one withdrawal record at the supplied slice index. // // Parameters: // - index: zero-based index of the withdrawal entry to replace. // - withdraw: replacement withdrawal record. func (d *Delegation) SetWithdraw(index int, withdraw DelegationWithdraw) { d.withdraws[index] = withdraw } // SetWithdraws replaces the complete withdrawal history. // // Parameters: // - withdraws: withdrawal records to store for this delegation. func (d *Delegation) SetWithdraws(withdraws []DelegationWithdraw) { d.withdraws = withdraws } // Clone returns a deep copy of the delegation and its withdrawal slice. // // Returns: // - *Delegation: copied delegation, or nil when the receiver is nil. func (d *Delegation) Clone() *Delegation { if d == nil { return nil } clonedWithdraws := make([]DelegationWithdraw, len(d.withdraws)) copy(clonedWithdraws, d.withdraws) return &Delegation{ id: d.id, delegateAmount: d.delegateAmount, unDelegateAmount: d.unDelegateAmount, collectedAmount: d.collectedAmount, delegateFrom: d.delegateFrom, delegateTo: d.delegateTo, createdHeight: d.createdHeight, createdAt: d.createdAt, withdraws: clonedWithdraws, } } // NewDelegationTree creates an empty tree for delegatee-to-delegation-ID mappings. // // Returns: // - *bptree.BPTree: empty tree configured for delegation lookup entries. func NewDelegationTree() *bptree.BPTree { return bptree.NewBPTreeN(16) } // NewUserDelegationTree creates an empty tree for user delegation mappings. // Returns: // - *bptree.BPTree: empty tree configured for user delegation entries. func NewUserDelegationTree() *bptree.BPTree { return bptree.NewBPTreeN(16) }
  8. #8delegation_manager.gno
  9. #9package staker import ( bptree "gno.land/p/nt/bptree/v0" ) // DelegationManager manages the mapping between users and their delegation IDs. // It provides efficient lookup and management of user delegations organized by delegator and delegatee addresses. type DelegationManager struct { // userDelegations maps delegator address -> *bptree.BPTree (delegatee address -> list of delegation IDs) // Using BPTree instead of map to handle unbounded growth of delegators efficiently userDelegations *bptree.BPTree } // NewDelegationManager creates a new instance of DelegationManager. // This factory function initializes the BPTree structure for tracking user delegations. // // Returns: // - *DelegationManager: manager ready to track delegator/delegatee ID lists. func NewDelegationManager() *DelegationManager { return &DelegationManager{ userDelegations: bptree.NewBPTreeN(16), } } // GetUserDelegations returns the entire user delegations tree. // // Returns: // - *bptree.BPTree: tree keyed by delegator address string. func (dm *DelegationManager) GetUserDelegations() *bptree.BPTree { return dm.userDelegations } // SetUserDelegations replaces the root delegator-to-delegations tree. // // Parameters: // - userDelegations: tree keyed by delegator address string and containing delegatee trees. func (dm *DelegationManager) SetUserDelegations(userDelegations *bptree.BPTree) { dm.userDelegations = userDelegations } // GetDelegatorDelegations returns the delegatee tree for one delegator. // // Parameters: // - delegator: delegator address string used as the root-tree key. // // Returns: // - *bptree.BPTree: delegatee-to-delegation-ID tree when present and correctly typed. // - bool: true when the delegator entry exists with the expected tree type. func (dm *DelegationManager) GetDelegatorDelegations(delegator string) (*bptree.BPTree, bool) { delegations := dm.userDelegations.Get(delegator) if delegations == nil { return nil, false } delegationsTree, ok := delegations.(*bptree.BPTree) if !ok { return nil, false } return delegationsTree, true } // GetDelegationIDs returns IDs recorded for one delegator/delegatee pair. // // Parameters: // - delegator: delegator address string used to select the nested tree. // - delegatee: delegatee address string used as the nested-tree key. // // Returns: // - []int64: delegation IDs stored for the pair. // - bool: true when the pair exists with a valid ID slice. func (dm *DelegationManager) GetDelegationIDs(delegator, delegatee string) ([]int64, bool) { delegations, exists := dm.GetDelegatorDelegations(delegator) if !exists { return nil, false } ids := delegations.Get(delegatee) if ids == nil { return nil, false } idsSlice, ok := ids.([]int64) if !ok { return nil, false } return idsSlice, true } // SetDelegationIDs stores the complete ID slice for a delegator/delegatee pair. // A missing delegator entry is initialized with a new nested tree. // // Parameters: // - delegator: delegator address string used to select or create the nested tree. // - delegatee: delegatee address string used as the nested-tree key. // - ids: delegation IDs to store for the pair. func (dm *DelegationManager) SetDelegationIDs(delegator, delegatee string, ids []int64) { delegations, exists := dm.GetDelegatorDelegations(delegator) if !exists { delegations = NewDelegationTree() dm.userDelegations.Set(delegator, delegations) } delegations.Set(delegatee, ids) } // AddDelegationID appends a delegation ID to the delegator-delegatee pair, // skipping duplicates. The whole get-modify-set runs inside this domain method // so the nested BPTree mutation never escapes the owning realm. Performing the // lookup in one realm and the write in another (e.g. re-fetching the inner tree // across a realm boundary and mutating it) would hit the cross-realm write // guard for the persisted leaf slot. // // Parameters: // - delegator: delegator address string used to select the nested tree. // - delegatee: delegatee address string used as the nested-tree key. // - delegationID: delegation ID to append when it is not already present. func (dm *DelegationManager) AddDelegationID(delegator, delegatee string, delegationID int64) { ids, _ := dm.GetDelegationIDs(delegator, delegatee) for _, id := range ids { if id == delegationID { return } } ids = append(ids, delegationID) dm.SetDelegationIDs(delegator, delegatee, ids) } // RemoveDelegationID removes a delegation ID from the delegator-delegatee pair. // Like AddDelegationID, the read-modify-write is kept inside this domain method. // RemoveDelegationID removes one ID from a delegator/delegatee pair. // Missing pairs and IDs are left unchanged. // // Parameters: // - delegator: delegator address string used to select the nested tree. // - delegatee: delegatee address string used as the nested-tree key. // - delegationID: delegation ID to remove when it is present. func (dm *DelegationManager) RemoveDelegationID(delegator, delegatee string, delegationID int64) { ids, exists := dm.GetDelegationIDs(delegator, delegatee) if !exists { return } index := -1 for i, id := range ids { if id == delegationID { index = i break } } if index == -1 { return } ids = append(ids[:index], ids[index+1:]...) dm.SetDelegationIDs(delegator, delegatee, ids) }
  10. #10delegation_withdraw.gno
  11. #11package staker import ( gnsmath "gno.land/p/gnoswap/gnsmath/v1" ) // DelegationWithdraw represents a pending withdrawal from a delegation. // This struct tracks undelegated amounts that are subject to lockup periods // and manages the collection process once the lockup period expires. type DelegationWithdraw struct { // delegationID is the unique identifier of the associated delegation delegationID int64 // unDelegateAmount is the total amount that was undelegated unDelegateAmount int64 // unDelegatedHeight is the height when the undelegation occurred unDelegatedHeight int64 // unDelegatedAt is the timestamp when the undelegation occurred unDelegatedAt int64 // collectedAmount is the amount that has already been collected collectedAmount int64 // collectableTime is the timestamp when collection becomes available collectableTime int64 // collectedAt is the timestamp when collection occurred collectedAt int64 // collected indicates whether the withdrawal has been fully collected collected bool } // DelegationID returns the unique identifier of the associated delegation. // // Returns: // - int64: delegation ID func (d *DelegationWithdraw) DelegationID() int64 { return d.delegationID } // UnDelegateAmount returns the total amount that was undelegated. // // Returns: // - int64: undelegated amount func (d *DelegationWithdraw) UnDelegateAmount() int64 { return d.unDelegateAmount } // UnDelegatedAt returns the timestamp when the undelegation occurred. // // Returns: // - int64: undelegation timestamp func (d *DelegationWithdraw) UnDelegatedAt() int64 { return d.unDelegatedAt } // UnDelegatedHeight returns the height when the undelegation occurred. // // Returns: // - int64: undelegation height func (d *DelegationWithdraw) UnDelegatedHeight() int64 { return d.unDelegatedHeight } // CollectedAmount returns the amount that has already been collected. // // Returns: // - int64: collected amount func (d *DelegationWithdraw) CollectedAmount() int64 { return d.collectedAmount } // CollectableTime returns the timestamp when collection becomes available. // // Returns: // - int64: collectable time func (d *DelegationWithdraw) CollectableTime() int64 { return d.collectableTime } // CollectedAt returns the timestamp when collection occurred. // // Returns: // - int64: collection timestamp func (d *DelegationWithdraw) CollectedAt() int64 { return d.collectedAt } // IsCollected returns whether the withdrawal has been fully collected. // // Returns: // - bool: true if fully collected, false otherwise func (d *DelegationWithdraw) IsCollected() bool { return d.collected } // SetCollected sets the collected status. // // Parameters: // - collected: new collected status func (d *DelegationWithdraw) SetCollected(collected bool) { d.collected = collected } // SetCollectedAt sets the collection timestamp. // // Parameters: // - collectedAt: collection timestamp func (d *DelegationWithdraw) SetCollectedAt(collectedAt int64) { d.collectedAt = collectedAt } // SetCollectedAmount sets the collected amount. // // Parameters: // - amount: collected amount func (d *DelegationWithdraw) SetCollectedAmount(amount int64) { d.collectedAmount = amount } // NewDelegationWithdraw creates a new delegation withdrawal with lockup period. // The withdrawal becomes collectable after the lockup period expires. // // Parameters: // - delegationID: Unique identifier of the associated delegation. // - unDelegateAmount: Amount being withdrawn. // - createdHeight: Block height at which the undelegation was created. // - createdAt: Unix timestamp at which the withdrawal was created. // - unDelegationLockupPeriod: Lockup duration in seconds. // // Returns: // - DelegationWithdraw: new withdrawal instance with its collectable time set after the lockup. func NewDelegationWithdraw( delegationID, unDelegateAmount, createdHeight, createdAt, unDelegationLockupPeriod int64, ) DelegationWithdraw { return DelegationWithdraw{ delegationID: delegationID, unDelegateAmount: unDelegateAmount, unDelegatedHeight: createdHeight, unDelegatedAt: createdAt, collectableTime: gnsmath.SafeAddInt64(createdAt, unDelegationLockupPeriod), collectedAmount: 0, collectedAt: 0, collected: false, } } // NewDelegationWithdrawWithoutLockup creates a withdrawal that is immediately collectable. // This is used for special cases such as redelegation where no lockup is required. // // Parameters: // - delegationID: Unique identifier of the associated delegation. // - unDelegateAmount: Amount being withdrawn. // - createdHeight: Block height at which the undelegation was created. // - createdAt: Unix timestamp at which the withdrawal was created. // // Returns: // - DelegationWithdraw: new withdrawal instance marked collected with collectable time equal to createdAt. func NewDelegationWithdrawWithoutLockup( delegationID, unDelegateAmount, createdHeight, createdAt int64, ) DelegationWithdraw { return DelegationWithdraw{ delegationID: delegationID, unDelegateAmount: unDelegateAmount, unDelegatedHeight: createdHeight, unDelegatedAt: createdAt, collectableTime: createdAt, collectedAmount: unDelegateAmount, // Immediately collected collectedAt: createdAt, collected: true, } } // Clone creates a deep copy of the delegation withdraw. // // Returns: // - DelegationWithdraw: independent copy of the withdrawal state. func (d *DelegationWithdraw) Clone() DelegationWithdraw { return DelegationWithdraw{ delegationID: d.delegationID, unDelegateAmount: d.unDelegateAmount, unDelegatedHeight: d.unDelegatedHeight, unDelegatedAt: d.unDelegatedAt, collectedAmount: d.collectedAmount, collectableTime: d.collectableTime, collectedAt: d.collectedAt, collected: d.collected, } }
  12. #12doc.gno
  13. #13package staker
  14. #14emission_reward_manager.gno
  15. #15package staker import ( bptree "gno.land/p/nt/bptree/v0" ufmt "gno.land/p/nt/ufmt/v0" u256 "gno.land/p/gnoswap/uint256/v1" ) const errFailedToCastRewardState = "failed to cast rewardStates's element to *EmissionRewardState: %T" // EmissionRewardManager manages the distribution of emission rewards to stakers. type EmissionRewardManager struct { // rewardStates maps address to EmissionRewardState for tracking individual staker rewards rewardStates *bptree.BPTree // address -> EmissionRewardState // accumulatedRewardX128PerStake tracks the cumulative reward per unit of stake with 128-bit precision accumulatedRewardX128PerStake *u256.Uint // distributedAmount tracks the total amount of rewards distributed distributedAmount int64 // accumulatedTimestamp tracks the last timestamp when rewards were accumulated accumulatedTimestamp int64 // totalStakedAmount tracks the total amount of tokens staked in the system totalStakedAmount int64 } // NewEmissionRewardManager creates and initializes an EmissionRewardManager with empty reward states and zero accounting totals. // Returns: // - *EmissionRewardManager: initialized manager with empty reward states, zero totals, and a zero Q128 accumulator. func NewEmissionRewardManager() *EmissionRewardManager { return &EmissionRewardManager{ accumulatedRewardX128PerStake: u256.NewUint(0), accumulatedTimestamp: 0, totalStakedAmount: 0, distributedAmount: 0, rewardStates: bptree.NewBPTreeN(16), } } // GetAccumulatedRewardX128PerStake returns the accumulated reward per stake with 128-bit precision. // Returns: // - *u256.Uint: accumulated emission reward per unit of stake in Q128 fixed-point form. func (e *EmissionRewardManager) GetAccumulatedRewardX128PerStake() *u256.Uint { return e.accumulatedRewardX128PerStake } // GetAccumulatedTimestamp returns the last timestamp when rewards were accumulated. // Returns: // - int64: Unix timestamp of the latest emission-reward accumulation. func (e *EmissionRewardManager) GetAccumulatedTimestamp() int64 { return e.accumulatedTimestamp } // GetTotalStakedAmount returns the total amount of tokens staked in the system. // Returns: // - int64: total staked token amount tracked by the manager. func (e *EmissionRewardManager) GetTotalStakedAmount() int64 { return e.totalStakedAmount } // GetDistributedAmount returns the total amount of rewards distributed. // Returns: // - int64: total emission reward amount marked as distributed. func (e *EmissionRewardManager) GetDistributedAmount() int64 { return e.distributedAmount } // GetRewardState retrieves the reward state for addr. // // Parameters: // - addr: Address key identifying the staker's emission reward state. // // Returns: // - *EmissionRewardState: stored state, or nil when addr has no state. // - bool: true when a reward state exists for addr; false when absent. // - error: nil on success or absence; non-nil when the stored value has the wrong type. func (e *EmissionRewardManager) GetRewardState(addr string) (*EmissionRewardState, bool, error) { ri := e.rewardStates.Get(addr) if ri == nil { return nil, false, nil } rs, castOk := ri.(*EmissionRewardState) if !castOk { return nil, false, ufmt.Errorf(errFailedToCastRewardState, ri) } return rs, true, nil } /* Setters */ // SetRewardStates replaces the tree containing per-address emission reward states. // // Parameters: // - rewardStates: BPTree mapping staker addresses to emission reward states. func (e *EmissionRewardManager) SetRewardStates(rewardStates *bptree.BPTree) { e.rewardStates = rewardStates } // SetAccumulatedRewardX128PerStake stores the accumulated emission reward per stake. // // Parameters: // - accumulatedRewardX128PerStake: Q128 fixed-point reward-per-stake accumulator to copy into the manager. func (e *EmissionRewardManager) SetAccumulatedRewardX128PerStake(accumulatedRewardX128PerStake *u256.Uint) { e.accumulatedRewardX128PerStake = u256.Zero().Set(accumulatedRewardX128PerStake) } // SetDistributedAmount stores the total emission amount marked as distributed. // // Parameters: // - distributedAmount: Total emission reward amount distributed so far. func (e *EmissionRewardManager) SetDistributedAmount(distributedAmount int64) { e.distributedAmount = distributedAmount } // SetAccumulatedTimestamp stores the latest emission-reward accumulation timestamp. // // Parameters: // - accumulatedTimestamp: Unix timestamp associated with the current accumulator. func (e *EmissionRewardManager) SetAccumulatedTimestamp(accumulatedTimestamp int64) { e.accumulatedTimestamp = accumulatedTimestamp } // SetTotalStakedAmount stores the total amount currently staked. // // Parameters: // - totalStakedAmount: Aggregate token amount participating in emission rewards. func (e *EmissionRewardManager) SetTotalStakedAmount(totalStakedAmount int64) { e.totalStakedAmount = totalStakedAmount } // SetRewardState sets the reward state for a specific address // SetRewardState stores one staker's emission reward state under address. // // Parameters: // - address: Address key for the staker's reward state. // - rewardState: Emission reward state to store for address. func (e *EmissionRewardManager) SetRewardState(address string, rewardState *EmissionRewardState) { e.rewardStates.Set(address, rewardState) }
  16. #16emission_reward_state.gno
  17. #17package staker import ( u256 "gno.land/p/gnoswap/uint256/v1" ) // EmissionRewardState tracks emission reward information for an individual staker. // This struct maintains reward debt, accumulated rewards, and claiming history // to ensure accurate reward calculations and prevent double-claiming. type EmissionRewardState struct { // rewardDebtX128 represents the reward debt with 128-bit precision scaling // Used to calculate rewards earned since the last update rewardDebtX128 *u256.Uint // accumulatedRewardAmount is the total rewards accumulated but not yet claimed accumulatedRewardAmount int64 // accumulatedTimestamp is the last timestamp when rewards were accumulated accumulatedTimestamp int64 // claimedRewardAmount is the total amount of rewards that have been claimed claimedRewardAmount int64 // claimedTimestamp is the last timestamp when rewards were claimed claimedTimestamp int64 // stakedAmount is the current amount of tokens staked by this address stakedAmount int64 } // NewEmissionRewardState creates a new emission reward state for a staker. // This factory function initializes the state with the current system reward debt. // // Parameters: // - accumulatedRewardX128PerStake: current system-wide accumulated reward per stake // // Returns: // - *EmissionRewardState: new emission reward state instance func NewEmissionRewardState(accumulatedRewardX128PerStake *u256.Uint) *EmissionRewardState { return &EmissionRewardState{ // Deep copy the input to snapshot the current accumulator value. rewardDebtX128: accumulatedRewardX128PerStake.Clone(), accumulatedRewardAmount: 0, accumulatedTimestamp: 0, claimedRewardAmount: 0, claimedTimestamp: 0, stakedAmount: 0, } } /* Getters */ // GetRewardDebtX128 returns the scaled reward debt used for accrual calculations. // // Returns: // - *u256.Uint: current reward debt in the protocol's 128-bit fixed-point scale. func (e *EmissionRewardState) GetRewardDebtX128() *u256.Uint { return e.rewardDebtX128 } // GetAccumulatedRewardAmount returns rewards accrued but not yet claimed. // // Returns: // - int64: accumulated reward amount in the smallest token unit. func (e *EmissionRewardState) GetAccumulatedRewardAmount() int64 { return e.accumulatedRewardAmount } // GetAccumulatedTimestamp returns when accumulated rewards were last updated. // // Returns: // - int64: Unix timestamp in seconds of the last accumulation update. func (e *EmissionRewardState) GetAccumulatedTimestamp() int64 { return e.accumulatedTimestamp } // GetClaimedRewardAmount returns the total rewards already claimed. // // Returns: // - int64: claimed reward amount in the smallest token unit. func (e *EmissionRewardState) GetClaimedRewardAmount() int64 { return e.claimedRewardAmount } // GetClaimedTimestamp returns when rewards were last claimed. // // Returns: // - int64: Unix timestamp in seconds of the last claim. func (e *EmissionRewardState) GetClaimedTimestamp() int64 { return e.claimedTimestamp } // GetStakedAmount returns the amount currently staked for this state. // // Returns: // - int64: staked token amount in the smallest token unit. func (e *EmissionRewardState) GetStakedAmount() int64 { return e.stakedAmount } /* Setters */ // SetRewardDebtX128 replaces the reward debt with a copied fixed-point value. // // Parameters: // - rewardDebtX128: reward debt in the protocol's 128-bit fixed-point scale. func (e *EmissionRewardState) SetRewardDebtX128(rewardDebtX128 *u256.Uint) { e.rewardDebtX128 = u256.Zero().Set(rewardDebtX128) } // SetAccumulatedRewardAmount replaces the unclaimed accumulated reward amount. // // Parameters: // - accumulatedRewardAmount: accumulated reward in the smallest token unit. func (e *EmissionRewardState) SetAccumulatedRewardAmount(accumulatedRewardAmount int64) { e.accumulatedRewardAmount = accumulatedRewardAmount } // SetAccumulatedTimestamp records the latest reward accumulation timestamp. // // Parameters: // - accumulatedTimestamp: Unix timestamp in seconds for the accumulation update. func (e *EmissionRewardState) SetAccumulatedTimestamp(accumulatedTimestamp int64) { e.accumulatedTimestamp = accumulatedTimestamp } // SetClaimedRewardAmount replaces the total claimed reward amount. // // Parameters: // - claimedRewardAmount: claimed reward in the smallest token unit. func (e *EmissionRewardState) SetClaimedRewardAmount(claimedRewardAmount int64) { e.claimedRewardAmount = claimedRewardAmount } // SetClaimedTimestamp records the latest reward claim timestamp. // // Parameters: // - claimedTimestamp: Unix timestamp in seconds for the claim. func (e *EmissionRewardState) SetClaimedTimestamp(claimedTimestamp int64) { e.claimedTimestamp = claimedTimestamp } // SetStakedAmount replaces the current staked amount. // Parameters: // - stakedAmount: staked token amount in the smallest token unit. func (e *EmissionRewardState) SetStakedAmount(stakedAmount int64) { e.stakedAmount = stakedAmount }
  18. #18errors.gno
  19. #19package staker // ErrSpoofedRealm is returned by store Set* methods when the supplied realm // token does not match the current crossing frame (rlm.IsCurrent() is false), // rejecting spoofed or stale realm tokens before any write is performed. const ErrSpoofedRealm = "rlm does not match the current crossing frame"
  20. #20getter_utils.gno
  21. #21package staker func cloneInt64Slice(src []int64) []int64 { if src == nil { return nil } cloned := make([]int64, len(src)) copy(cloned, src) return cloned } func cloneStringInt64Map(src map[string]int64) map[string]int64 { if src == nil { return nil } cloned := make(map[string]int64, len(src)) for key, value := range src { cloned[key] = value } return cloned } func cloneDelegationWithdraws(src []DelegationWithdraw) []DelegationWithdraw { if src == nil { return nil } cloned := make([]DelegationWithdraw, len(src)) copy(cloned, src) return cloned }
  22. #22getters.gno
  23. #23package staker import ( u256 "gno.land/p/gnoswap/uint256/v1" rotree "gno.land/p/nt/bptree/rotree/v0" ) // GetTotalxGnsSupply returns total xGNS supply, including launchpad-held xGNS. // Returns: // - int64: total xGNS supply, including xGNS held by launchpad projects. func GetTotalxGnsSupply() int64 { return getImplementation().GetTotalxGnsSupply() } // GetTotalDelegated returns the total amount of GNS delegated. // Returns: // - int64: total GNS amount delegated across all delegators. func GetTotalDelegated() int64 { return getImplementation().GetTotalDelegated() } // GetTotalLockedAmount returns the total amount of GNS locked in undelegation. // Returns: // - int64: total GNS amount currently locked in undelegation withdrawals. func GetTotalLockedAmount() int64 { return getImplementation().GetTotalLockedAmount() } // GetUnDelegationLockupPeriod returns the undelegation lockup period in seconds. // Returns: // - int64: configured undelegation lockup duration in seconds. func GetUnDelegationLockupPeriod() int64 { return getImplementation().GetUnDelegationLockupPeriod() } // GetDelegations returns a read-only view of every delegation, keyed by the // decimal string form of the delegation ID. Callers paginate it themselves // through IterateByOffset. Reading an entry yields a clone, so the view cannot // mutate realm state. // Returns: // - *rotree.ReadOnlyTree: read-only delegation view keyed by decimal delegation ID; entry reads return clones. func GetDelegations() *rotree.ReadOnlyTree { return getImplementation().GetDelegations() } // ExistsDelegation checks if a delegation exists. // Parameters: // - delegationID: Numeric identifier of the delegation to look up. // // Returns: // - bool: true when a delegation with delegationID exists, false otherwise. func ExistsDelegation(delegationID int64) bool { return getImplementation().ExistsDelegation(delegationID) } // GetDelegatorDelegations returns a read-only view of a delegator's delegations, // keyed by delegatee address with that pair's delegation IDs as the value. // Reading an entry yields a copy of the ID slice, so the view cannot mutate // realm state. nil is returned when the delegator has no delegations. // Parameters: // - delegator: Address whose delegations should be listed. // // Returns: // - *rotree.ReadOnlyTree: read-only view keyed by delegatee address, or nil when delegator has no delegations. func GetDelegatorDelegations(delegator address) *rotree.ReadOnlyTree { return getImplementation().GetDelegatorDelegations(delegator) } // GetUserDelegationIDs returns a list of delegation IDs for a specific delegator-delegatee pair. // Parameters: // - delegator: Address that supplied the delegation. // - delegatee: Address receiving that delegation. // // Returns: // - []int64: delegation IDs for the delegator-delegatee pair; the returned slice is independent of realm state. func GetUserDelegationIDs(delegator address, delegatee address) []int64 { return cloneInt64Slice(getImplementation().GetUserDelegationIDs(delegator, delegatee)) } // HasDelegationSnapshotsKey returns true if delegation history exists. // Returns: // - bool: true when delegation history has been initialized in storage. func HasDelegationSnapshotsKey() bool { return getImplementation().HasDelegationSnapshotsKey() } // GetTotalDelegationAmountAtSnapshot returns total delegation at a Unix // timestamp, using the latest history entry at or before that timestamp. // The lookup is timestamp-based rather than a block-height snapshot. // Parameters: // - snapshotTime: Unix timestamp at or before which to select the latest aggregate delegation history entry. // // Returns: // - int64: aggregate delegated amount recorded at or before snapshotTime. // - bool: true when a qualifying history entry exists; false when no entry is available. func GetTotalDelegationAmountAtSnapshot(snapshotTime int64) (int64, bool) { return getImplementation().GetTotalDelegationAmountAtSnapshot(snapshotTime) } // GetUserDelegationAmountAtSnapshot returns one user's delegation at a Unix // timestamp, using that user's latest history entry at or before the timestamp. // The bool is false when no qualifying history entry exists. // Parameters: // - userAddr: Delegator address whose historical delegation is queried. // - snapshotTime: Unix timestamp at or before which to select the user's latest history entry. // // Returns: // - int64: user's delegated amount recorded at or before snapshotTime. // - bool: true when a qualifying user-history entry exists; false otherwise. func GetUserDelegationAmountAtSnapshot(userAddr address, snapshotTime int64) (int64, bool) { return getImplementation().GetUserDelegationAmountAtSnapshot(userAddr, snapshotTime) } // GetClaimableRewardByAddress returns claimable rewards for an address. // // Parameters: // - addr: Address whose emission and protocol-fee rewards are queried. // // Returns: // - int64: emission reward amount available to addr. // - map[string]int64: protocol-fee reward amounts keyed by token path. // - error: nil on success; non-nil when reward state cannot be resolved for addr. func GetClaimableRewardByAddress(addr address) (int64, map[string]int64, error) { emissionReward, protocolFees, err := getImplementation().GetClaimableRewardByAddress(addr) if err != nil { return 0, nil, err } return emissionReward, cloneStringInt64Map(protocolFees), nil } // GetClaimableRewardByLaunchpad returns claimable launchpad rewards for an address. // // Parameters: // - addr: Address whose launchpad and protocol-fee rewards are queried. // // Returns: // - int64: emission reward amount available to addr. // - map[string]int64: protocol-fee reward amounts keyed by token path. // - error: nil on success; non-nil when reward state cannot be resolved for addr. func GetClaimableRewardByLaunchpad(addr address) (int64, map[string]int64, error) { emissionReward, protocolFees, err := getImplementation().GetClaimableRewardByLaunchpad(addr) if err != nil { return 0, nil, err } return emissionReward, cloneStringInt64Map(protocolFees), nil } // GetClaimableRewardByRewardID returns claimable reward details by reward ID. // // Parameters: // - rewardID: Reward-state identifier whose claimable rewards are queried. // // Returns: // - int64: emission reward amount associated with rewardID. // - map[string]int64: protocol-fee reward amounts keyed by token path. // - error: nil on success; non-nil when rewardID cannot be resolved. func GetClaimableRewardByRewardID(rewardID string) (int64, map[string]int64, error) { emissionReward, protocolFees, err := getImplementation().GetClaimableRewardByRewardID(rewardID) if err != nil { return 0, nil, err } return emissionReward, cloneStringInt64Map(protocolFees), nil } // GetLaunchpadProjectDeposit returns the deposit amount for a launchpad project. // Parameters: // - projectAddr: Launchpad project address whose deposited amount is queried. // // Returns: // - int64: recorded launchpad project deposit amount. // - bool: true when a deposit record exists for projectAddr; false otherwise. func GetLaunchpadProjectDeposit(projectAddr string) (int64, bool) { return getImplementation().GetLaunchpadProjectDeposit(projectAddr) } // GetDelegationWithdrawCount returns the total number of delegation withdraws for a specific delegation. // Parameters: // - delegationID: Identifier of the delegation whose withdrawals are counted. // // Returns: // - int: number of withdrawal records associated with delegationID. func GetDelegationWithdrawCount(delegationID int64) int { return getImplementation().GetDelegationWithdrawCount(delegationID) } // GetDelegationWithdraws returns a paginated list of delegation withdraws for a specific delegation. // Parameters: // - delegationID: Identifier of the delegation whose withdrawals are requested. // - offset: Number of matching withdrawal records to skip before collecting results. // - count: Maximum number of withdrawal records to return. // // Returns: // - []DelegationWithdraw: requested page of withdrawal records, copied before returning. // - error: nil on success; non-nil when the requested delegation or page cannot be read. func GetDelegationWithdraws(delegationID int64, offset, count int) ([]DelegationWithdraw, error) { withdraws, err := getImplementation().GetDelegationWithdraws(delegationID, offset, count) if err != nil { return nil, err } return cloneDelegationWithdraws(withdraws), nil } // GetCollectableWithdrawAmount returns the collectable withdraw amount for a specific delegation. // Parameters: // - delegationID: Identifier of the delegation whose collectable amount is queried. // // Returns: // - int64: amount currently available to collect from delegationID. func GetCollectableWithdrawAmount(delegationID int64) int64 { return getImplementation().GetCollectableWithdrawAmount(delegationID) } // GetProtocolFeeAccumulatedX128PerStake returns the accumulated protocol fee per stake (Q128) for a token path. // Parameters: // - tokenPath: Registered token path whose protocol-fee accumulator is queried. // // Returns: // - *u256.Uint: accumulated protocol-fee amount per unit stake in Q128 fixed-point form. func GetProtocolFeeAccumulatedX128PerStake(tokenPath string) *u256.Uint { return getImplementation().GetProtocolFeeAccumulatedX128PerStake(tokenPath).Clone() } // GetProtocolFeeAmount returns the protocol fee amounts for a token path. // Parameters: // - tokenPath: Registered token path whose protocol fees are queried. // // Returns: // - int64: accumulated protocol-fee amount for tokenPath in token base units. func GetProtocolFeeAmount(tokenPath string) int64 { return getImplementation().GetProtocolFeeAmount(tokenPath) } // GetProtocolFeeAccumulatedTimestamp returns the accumulated timestamp for protocol fee rewards. // Returns: // - int64: Unix timestamp at which protocol-fee accumulation was last updated. func GetProtocolFeeAccumulatedTimestamp() int64 { return getImplementation().GetProtocolFeeAccumulatedTimestamp() } // GetEmissionAccumulatedX128PerStake returns the accumulated emission per stake (Q128). // Returns: // - *u256.Uint: accumulated emission reward per unit stake in Q128 fixed-point form. func GetEmissionAccumulatedX128PerStake() *u256.Uint { return getImplementation().GetEmissionAccumulatedX128PerStake().Clone() } // GetEmissionDistributedAmount returns the total distributed emission amount. // Returns: // - int64: total emission amount distributed to stakers. func GetEmissionDistributedAmount() int64 { return getImplementation().GetEmissionDistributedAmount() } // GetEmissionAccumulatedTimestamp returns the accumulated timestamp for emission rewards. // Returns: // - int64: Unix timestamp at which emission accumulation was last updated. func GetEmissionAccumulatedTimestamp() int64 { return getImplementation().GetEmissionAccumulatedTimestamp() }
  24. #24gnomod.toml

Result log

msg:0,success:true,log:,events:[]

← Back to block 77,260