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

admin.gno

2.37 Kb · 87 lines
 1// Admin operations — DAO-gated, with a 2-step admin handoff and a hard fee ceiling.
 2// There is intentionally NO Pause() here (see config.gno SAFETY note): pausing the
 3// fee spine would brick every engine at once. Per-engine Pause() is the kill switch.
 4package memba_market_config
 5
 6import (
 7	"strconv"
 8
 9	"chain"
10)
11
12func itoa(n int64) string { return strconv.FormatInt(n, 10) }
13
14func assertAdmin() {
15	if caller() != admin {
16		panic("admin only")
17	}
18}
19
20// SetFeeBPS sets a lane's protocol fee in basis points, clamped to [0, MaxFeeBPS].
21// A value above the 5% ceiling is rejected so a misconfiguration can never overcharge.
22func SetFeeBPS(cur realm, lane string, bps int64) {
23	assertAdmin()
24	if lane == "" {
25		panic("empty lane")
26	}
27	if bps < 0 || bps > MaxFeeBPS {
28		panic("feeBPS out of range")
29	}
30	feeByLane.Set(lane, bps)
31	chain.Emit("FeeBPSChanged", "lane", lane, "bps", itoa(bps))
32}
33
34// SetTreasury repoints where every lane's protocol fee flows.
35func SetTreasury(cur realm, addr address) {
36	assertAdmin()
37	if addr == "" {
38		panic("empty treasury")
39	}
40	treasury = addr
41	chain.Emit("TreasuryChanged", "treasury", addr.String())
42}
43
44// TransferAdmin proposes a new admin (the memba_dao executor). The 2-step handoff
45// requires the new admin to AcceptAdmin, so a transfer to a wrong or uncontrolled
46// address cannot lock the realm.
47func TransferAdmin(cur realm, newAdmin address) {
48	assertAdmin()
49	if newAdmin == "" {
50		panic("empty admin")
51	}
52	if !newAdmin.IsValid() {
53		panic("invalid address: " + newAdmin.String())
54	}
55	if newAdmin == admin {
56		panic("newAdmin is the current admin")
57	}
58	pendingAdmin = newAdmin
59	chain.Emit("AdminTransferProposed", "pending", newAdmin.String())
60}
61
62// CancelAdminTransfer withdraws a staged handoff. Admin only.
63func CancelAdminTransfer(cur realm) {
64	assertAdmin()
65	if pendingAdmin == "" {
66		panic("no pending admin")
67	}
68	cancelled := pendingAdmin
69	pendingAdmin = ""
70	chain.Emit("AdminTransferCancelled", "pending", cancelled.String())
71}
72
73// AcceptAdmin completes the handoff. Only the pending admin can call it.
74func AcceptAdmin(cur realm) {
75	if pendingAdmin == "" {
76		panic("no pending admin")
77	}
78	if caller() != pendingAdmin {
79		panic("not pending admin")
80	}
81	admin = pendingAdmin
82	pendingAdmin = ""
83	chain.Emit("AdminAccepted", "admin", admin.String())
84}
85
86// GetPendingAdmin returns the staged successor, or the empty address.
87func GetPendingAdmin() address { return pendingAdmin }