Galaxy King Dog / Supporting design document

Charity Governance — token-weighted voting

On-chain implementation of the whitepaper v1.7 charity governance: token-weighted votes that direct the Charity Pool to a whitelisted charity operator. Not yet deployed.

Locked rules (v1.7)

  • Votes happen at two gates only: end_human_emission (gate 0, after season 32 closes) and end_chaos (gate 1, after season 33 closes).
  • Eligibility: voter must hold ≥ 1 whole $420POP.
  • Token-weighted: vote weight = the voter's whole-token $420POP balance.
  • Quorum: 10,000 total weighted votes.
  • Duration: 99 days.
  • Tie: re-vote (admin opens a new round).
  • Failed quorum: funds remain in the Charity Pool.
  • Operator must be a whitelisted verified charity.

Instructions

Instruction Who What
whitelist_charity(operator, name) admin Adds a verified operator (["charity_op", operator] PDA).
open_charity_vote(gate, round) admin Opens a 99-day vote; requires the gate's season closed. Quorum = 10k.
cast_charity_vote() any eligible holder One token-weighted vote per wallet per proposal.
finalize_charity_vote() permissionless After close: routes Charity Pool to the winner, or marks failed-quorum / tie.

Accounts / PDAs

  • CharityProposal["proposal", gate, round]. Tracks window, quorum, total_votes, and the top-two tallies (leading_votes / second_votes) so an exact tie is detectable at finalize.
  • OperatorTally["tally", proposal, operator]. Accumulated weight per operator (init_if_needed).
  • VoteReceipt["vote", proposal, voter]. init ⇒ one vote per wallet per proposal.
  • WhitelistedCharity["charity_op", operator]. Operator + active flag + name.

Voting & finalize

cast_charity_vote reads the voter's $420POP token account (mint must equal config.mint, owner must be the voter), computes weight = amount / 10⁹, requires weight ≥ 1, writes a VoteReceipt, adds the weight to the operator's tally and the proposal total, and updates the top-two tracker.

finalize_charity_vote (after end_ts):

  • total_votes < quorumfailed_quorum = true, funds stay in the Charity Pool;
  • leading_votes == second_votestie = true, admin must open_charity_vote with a new round;
  • otherwise the winner = leading_operator (re-checked against the passed operator + whitelist) and the Charity Pool's distributable balance is transferred to the operator wallet.

Known limitations (documented, pre-audit)

  • Snapshot-less weighting: weight is the current balance, so tokens moved between wallets can be re-used to vote from multiple wallets. A balance snapshot or vote-time token lock/escrow is the hardening step before mainnet.
  • Quorum unit is whole-token weight (10,000), matching the token-weighted default; confirm against the whitepaper if a one-wallet-one-vote interpretation was intended instead.