admin.gno
1.77 Kb · 64 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 pendingAdmin = newAdmin
53 chain.Emit("AdminTransferProposed", "pending", newAdmin.String())
54}
55
56// AcceptAdmin completes the handoff. Only the pending admin can call it.
57func AcceptAdmin(cur realm) {
58 if caller() != pendingAdmin {
59 panic("not pending admin")
60 }
61 admin = pendingAdmin
62 pendingAdmin = ""
63 chain.Emit("AdminAccepted", "admin", admin.String())
64}