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.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}