Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

govern.gno

5.47 Kb · 165 lines
  1package sugarproxy
  2
  3import (
  4	"strconv"
  5	"strings"
  6
  7	governor "gno.land/p/g1ecsuj0q572jr0dhu29q9njtnmw03hyu7tyyvv6/governor/v0"
  8	grc20votes "gno.land/p/g1ecsuj0q572jr0dhu29q9njtnmw03hyu7tyyvv6/grc20votes/v0"
  9)
 10
 11// SUGAR, the governance token: kourt's grc20votes ledger (balances checkpointed per epoch of 720 blocks, about an
 12// hour, so a vote weighs what a holder held before the proposal) and kourt's governor over it. Both packages are
 13// deployed under Jae's address on gnoland-1.
 14//
 15// The governor's proposals here are of two kinds of this realm's own: add an item, remove one. Holders propose
 16// with Propose(cur, kind, payload, title), vote with Vote, and anyone may Execute a proposal that passed and
 17// whose delay is over.
 18var (
 19	ledger = grc20votes.NewLedger("sugar proxy", "SUGAR", 6, 720)
 20	engine = governor.New(ledger, ledger)
 21)
 22
 23// InitialSupply is minted to the deployer at init: 1,000,000 SUGAR of 6 decimals.
 24const InitialSupply = int64(1_000_000_000_000)
 25
 26const (
 27	kindAdd    = governor.Reserved + "sugar-add"
 28	kindRemove = governor.Reserved + "sugar-remove"
 29)
 30
 31// rules are kourt's bootstrap rules (a fifth of the supply turns out, two thirds of the votes cast say yes, a week
 32// to vote, two days' delay, two weeks to execute), except that proposing takes 0.1% of the supply: kourt's lets
 33// anyone propose.
 34func rules() governor.Rules {
 35	r := governor.BootstrapRules()
 36	r.ProposeBps = 10
 37	return r
 38}
 39
 40// setupGovernor adopts this realm's two kinds; init calls it.
 41func setupGovernor() {
 42	engine.InstallBuiltin(addKind{}, rules())
 43	engine.InstallBuiltin(removeKind{}, rules())
 44}
 45
 46func mintInitial(to address) { ledger.Mint(to, InitialSupply) }
 47
 48// KindAdd and KindRemove are the names to propose under.
 49func KindAdd() string    { return kindAdd }
 50func KindRemove() string { return kindRemove }
 51
 52type addKind struct{}
 53
 54func (addKind) Name() string { return kindAdd }
 55func (addKind) Describe(payload string) string {
 56	return "Add to sugar proxy's rules: `" + payload + "`. Once executed it waits out the veto window for its kind, " +
 57		"during which GovDAO or the guardian may veto it."
 58}
 59func (addKind) Check(payload string) error {
 60	_, _, err := parse(payload)
 61	return err
 62}
 63func (addKind) Do(_ int, _ realm, payload string) error {
 64	_, err := add(payload, "token")
 65	return err
 66}
 67
 68type removeKind struct{}
 69
 70func (removeKind) Name() string { return kindRemove }
 71func (removeKind) Describe(payload string) string {
 72	return "Remove item " + payload + " from sugar proxy's rules, at once."
 73}
 74func (removeKind) Check(payload string) error {
 75	id, err := strconv.Atoi(strings.TrimSpace(payload))
 76	if err != nil {
 77		return errorf("the payload is an item's number")
 78	}
 79	if it := find(id); it == nil || it.State != StateApproved {
 80		return errorf("item %d isn't approved", id)
 81	}
 82	return nil
 83}
 84func (removeKind) Do(_ int, _ realm, payload string) error {
 85	id, _ := strconv.Atoi(strings.TrimSpace(payload))
 86	return end(id, false, "token")
 87}
 88
 89const errStaleRealm = "sugarproxy: that realm value is not live; pass your own cur"
 90
 91func live(cur realm) {
 92	if !cur.IsCurrent() {
 93		panic(errStaleRealm)
 94	}
 95}
 96
 97// Propose opens a proposal: kind is KindAdd() with a payload "kind|field|...", or KindRemove() with an item's
 98// number. It needs the governor's share of the supply to propose.
 99func Propose(cur realm, kind, payload, title string) int64 {
100	live(cur)
101	return engine.Propose(cur.Previous().Address(), kind, payload, title)
102}
103
104// Vote casts the caller's weight: "yes", "no" or "abstain".
105func Vote(cur realm, id int64, choice string) {
106	live(cur)
107	engine.Vote(cur.Previous().Address(), id, choice)
108}
109
110// Execute carries out a proposal that passed, once its delay is over.
111func Execute(cur realm, id int64) {
112	live(cur)
113	engine.Execute(cur.Previous().Address(), id, func(k governor.Kind, sub, payload string) error {
114		return k.Do(0, cur.Sub(sub), payload)
115	})
116}
117
118// Cancel withdraws the caller's own open proposal.
119func Cancel(cur realm, id int64) {
120	live(cur)
121	engine.Cancel(cur.Previous().Address(), id)
122}
123
124// Settle closes a proposal whose voting is over.
125func Settle(cur realm, id int64) {
126	live(cur)
127	engine.Settle(cur.Previous().Address(), id)
128}
129
130// State, Describe and Tally read a proposal.
131func State(id int64) string                           { return engine.State(id) }
132func DescribeProposal(id int64) string                { return engine.Describe(id) }
133func Tally(id int64) (yes, no, abstain, total int64) { return engine.Tally(id) }
134
135// --- the token ---
136
137func TotalSupply() int64              { return ledger.TotalSupply() }
138func BalanceOf(who address) int64     { return ledger.BalanceOf(who) }
139func VotesOf(who address) int64       { return ledger.VotesOf(who) }
140func DelegateOf(who address) address  { return ledger.DelegateOf(who) }
141func Allowance(o, s address) int64    { return ledger.Allowance(o, s) }
142
143// Transfer sends SUGAR from the caller.
144func Transfer(cur realm, to address, amount int64) {
145	live(cur)
146	ledger.Transfer(cur.Previous().Address(), to, amount)
147}
148
149// Approve lets spender move up to amount of the caller's SUGAR.
150func Approve(cur realm, spender address, amount int64) {
151	live(cur)
152	ledger.Approve(cur.Previous().Address(), spender, amount)
153}
154
155// TransferFrom moves SUGAR the owner approved the caller to move.
156func TransferFrom(cur realm, from, to address, amount int64) {
157	live(cur)
158	ledger.TransferFrom(cur.Previous().Address(), from, to, amount)
159}
160
161// DelegateVotes gives the caller's voting weight to another address (its own, to take it back).
162func DelegateVotes(cur realm, to address) {
163	live(cur)
164	ledger.Delegate(cur.Previous().Address(), to)
165}