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

admin.gno

2.47 Kb · 79 lines
 1package memba_arcade_leaderboard_v1
 2
 3import "chain"
 4
 5// Admin surface — owner-gated. The owner is the samcrew multisig at launch and can be handed to
 6// the memba_dao executor via the 2-step TransferOwnership/AcceptOwnership (never a 1-step transfer
 7// to a mistyped/dead address).
 8
 9// AddAttester allowlists an ADDRESS (the backend verifier's dedicated low-privilege key — never the
10// deploy multisig itself) as an authorized result source. Owner only.
11func AddAttester(cur realm, addr address) {
12	assertOwner(cur)
13	if addr == "" {
14		panic("attester address must be non-empty")
15	}
16	attesters.Set(addr.String(), true)
17	chain.Emit("AttesterAdded", "addr", addr.String())
18}
19
20// RemoveAttester revokes an attester key. Owner only.
21func RemoveAttester(cur realm, addr address) {
22	assertOwner(cur)
23	attesters.Remove(addr.String())
24	chain.Emit("AttesterRemoved", "addr", addr.String())
25}
26
27// Pause freezes all attestation + receipt requests (reads stay available). Owner only.
28func Pause(cur realm, state bool) {
29	assertOwner(cur)
30	paused = state
31	chain.Emit("PauseSet", "paused", boolStr(state))
32}
33
34// TransferOwnership stages a new owner; it takes effect only after AcceptOwnership is called BY
35// that address (2-step, so a typo can't brick admin).
36func TransferOwnership(cur realm, newOwner address) {
37	assertOwner(cur)
38	if newOwner == "" {
39		panic("newOwner must be non-empty")
40	}
41	if !newOwner.IsValid() {
42		panic("invalid address: " + newOwner.String())
43	}
44	if newOwner == owner {
45		panic("newOwner is the current owner")
46	}
47	pendingOwner = newOwner
48	chain.Emit("OwnershipTransferStarted", "pending", newOwner.String())
49}
50
51// CancelOwnershipTransfer withdraws a staged handoff. Owner only.
52func CancelOwnershipTransfer(cur realm) {
53	assertOwner(cur)
54	if pendingOwner == "" {
55		panic("no pending ownership transfer")
56	}
57	cancelled := pendingOwner
58	pendingOwner = ""
59	chain.Emit("OwnershipTransferCancelled", "pending", cancelled.String())
60}
61
62// GetPendingOwner returns the staged successor, or the empty address.
63func GetPendingOwner() address { return pendingOwner }
64
65// AcceptOwnership completes the handoff. Only the staged pendingOwner may call it.
66func AcceptOwnership(cur realm) {
67	if !cur.IsCurrent() {
68		panic("spoofed realm")
69	}
70	if pendingOwner == "" {
71		panic("no pending ownership transfer")
72	}
73	if cur.Previous().Address() != pendingOwner {
74		panic("unauthorized: only the pending owner may accept")
75	}
76	owner = pendingOwner
77	pendingOwner = ""
78	chain.Emit("OwnershipTransferAccepted", "owner", owner.String())
79}