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/governance/v1

Realm
Open in gnoweb ↗

Overview

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

Files (23)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • config.gnogno
  • consts.gnogno
  • doc.gnogno
  • errors.gnogno
  • getter_utils.gnogno
  • getter.gnogno
  • governance_execute.gnogno
  • governance_propose.gnogno
  • governance_vote.gnogno
  • init.gnogno
  • instance.gnogno
  • parameter_registry.gnogno
  • proposal_action_status.gnogno
  • proposal_data.gnogno
  • proposal_schedule_status.gnogno
  • proposal_status.gnogno
  • proposal_vote_status.gnogno
  • proposal.gnogno
  • render.gnogno
  • utils.gnogno
  • governance_vote.gnogno
    1package governance23import (4	"chain"5	"chain/runtime"6	"time"78

    Functions

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

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

    Rendered

    RenderedRawgnoweb ↗

    Render unavailable

    rate limit exceeded — the render query is served by the Gnoland archive RPC.

    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.

    "gno.land/r/gnoswap/access/v1"
    9
    10 gnsmath "gno.land/p/gnoswap/gnsmath/v1"
    11 "gno.land/p/gnoswap/utils/v1"
    12
    13 "gno.land/r/gnoswap/emission"
    14
    15 "gno.land/r/gnoswap/gov/governance"
    16)
    17
    18// Vote casts a vote on a proposal.
    19//
    20// Records an on-chain vote with weight based on delegated xGNS.
    21// Uses the proposal's timestamp anchors and configured smoothing duration to
    22// prevent manipulation. Votes are final and cannot be changed.
    23//
    24// Parameters:
    25// - _: leading realm-call discriminator; callers pass 0 while threading the realm context
    26// - rlm: current realm context; implementation validates it before reading or writing governance state
    27// - proposalID: ID of the proposal to vote on
    28// - yes: true for yes vote, false for no vote
    29//
    30// Vote Weight Calculation:
    31// - Based on the voter's delegated xGNS amount
    32// - Averages delegation at the stored smoothing timestamp and proposal creation time
    33// - Uses Unix timestamp history, not a block-height snapshot
    34// - Includes self-delegation and delegations received by the voter
    35//
    36// Requirements:
    37// - Proposal must be in voting period
    38// - Voter must have xGNS delegated at one of the lookup timestamps
    39// - Cannot vote twice on same proposal
    40// - Voting period is 7 days by default and is configurable
    41//
    42// Returns:
    43// - voteWeight: voting weight applied to the caller's vote, formatted as a string
    44func (gv *governanceV1) Vote(_ int, rlm realm, proposalID int64, yes bool) string {
    45 access.AssertIsRlmCurrent(0, rlm)
    46
    47 assertIsNotHaltedGovernanceForProposal(gv, proposalID)
    48
    49 // Get current blockchain state and caller information
    50 currentHeight := runtime.ChainHeight()
    51 currentAt := time.Now()
    52
    53 // Mint and distribute GNS tokens as part of the voting process
    54 emission.MintAndDistributeGns(cross(rlm))
    55
    56 // Extract voter address from realm context
    57 voterRealm := rlm.Previous()
    58 voter := voterRealm.Address()
    59
    60 // Process the vote and get updated vote tallies
    61 userVote, totalYesVoteWeight, totalNoVoteWeight, err := gv.vote(
    62 0, rlm,
    63 proposalID,
    64 voter,
    65 yes,
    66 currentHeight,
    67 currentAt.Unix(),
    68 )
    69 if err != nil {
    70 panic(err)
    71 }
    72
    73 // Emit voting event for tracking and transparency
    74 voteWeight := utils.FormatInt(userVote.VotedWeight())
    75 voterStr := voter.String()
    76
    77 chain.Emit(
    78 "Vote",
    79 "prevAddr", voterStr,
    80 "prevPkgPath", voterRealm.PkgPath(),
    81 "proposalId", utils.FormatInt(proposalID),
    82 "voter", voterStr,
    83 "yes", userVote.VotingType(),
    84 "voteWeight", voteWeight,
    85 "voteYes", utils.FormatInt(totalYesVoteWeight),
    86 "voteNo", utils.FormatInt(totalNoVoteWeight),
    87 )
    88
    89 return voteWeight
    90}
    91
    92// vote handles core voting logic.
    93func (gv *governanceV1) vote(
    94 _ int, rlm realm,
    95 proposalID int64,
    96 voterAddress address,
    97 votedYes bool,
    98 votedHeight,
    99 votedAt int64,
    100) (governance.VotingInfo, int64, int64, error) {
    101 // Retrieve the proposal from storage
    102 proposal, ok := gv.getProposal(proposalID)
    103 if !ok {
    104 return governance.DefaultVotingInfo(), 0, 0, makeErrorWithDetails(errDataNotFound, "not found proposal")
    105 }
    106
    107 proposalResolver := NewProposalResolver(proposal)
    108
    109 // Check if current time is within voting period
    110 if !proposalResolver.IsVotingPeriod(votedAt) {
    111 return governance.DefaultVotingInfo(), 0, 0, makeErrorWithDetails(errUnableToVoteOutOfPeriod, "cannot vote out of voting period")
    112 }
    113
    114 // Get user's voting weight by averaging timestamp-history values at the
    115 // proposal's stored smoothing anchor and creation time.
    116 snapshotTime := proposal.SnapshotTime()
    117 createdAt := proposal.CreatedAt()
    118
    119 weightAtSnapshot, ok := gv.stakerAccessor.GetUserDelegationAmountAtSnapshot(voterAddress, snapshotTime)
    120 if !ok {
    121 weightAtSnapshot = 0
    122 }
    123
    124 weightAtCreated, ok := gv.stakerAccessor.GetUserDelegationAmountAtSnapshot(voterAddress, createdAt)
    125 if !ok {
    126 weightAtCreated = 0
    127 }
    128
    129 votingWeight := gnsmath.SafeAddInt64(weightAtSnapshot, weightAtCreated) / 2
    130 if votingWeight <= 0 {
    131 return governance.DefaultVotingInfo(), 0, 0, makeErrorWithDetails(
    132 errNotEnoughVotingWeight, "no voting weight at snapshot time")
    133 }
    134
    135 userVote, exists := gv.getProposalUserVotingInfo(proposalID, voterAddress)
    136 if !exists {
    137 userVote = governance.NewVotingInfo(votingWeight)
    138 }
    139
    140 if userVote.IsVoted() {
    141 return governance.DefaultVotingInfo(), 0, 0, makeErrorWithDetails(errAlreadyVoted, "user has already voted")
    142 }
    143 userVote = governance.NewVotedVotingInfo(votingWeight, votedYes, votingWeight, votedHeight, votedAt)
    144
    145 votingInfosTree, _ := gv.getProposalUserVotingInfos(proposalID)
    146 if votingInfosTree == nil {
    147 return governance.DefaultVotingInfo(), 0, 0, makeErrorWithDetails(
    148 errDataNotFound, "voting infos tree not found for proposal")
    149 }
    150
    151 votingInfosTree.Set(voterAddress.String(), userVote)
    152 err := gv.store.SetProposalVotingInfos(0, rlm, proposalID, votingInfosTree)
    153 if err != nil {
    154 return governance.DefaultVotingInfo(), 0, 0, err
    155 }
    156
    157 // Update proposal vote tallies
    158 err = proposalResolver.Vote(votedYes, votingWeight)
    159 if err != nil {
    160 return governance.DefaultVotingInfo(), 0, 0, err
    161 }
    162
    163 return userVote, proposal.VotingYesWeight(), proposal.VotingNoWeight(), nil
    164}
    165