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

4.24 Kb · 154 lines
  1package game
  2
  3import "chain"
  4
  5// Roles: one owner, a set of admins, a set of referees.
  6//
  7//   - The owner manages the admins and the treasury, and can hand the realm
  8//     over. The owner is always an admin.
  9//   - Admins tune the game and manage the referees.
 10//   - Referees are the game servers. They record kills and nothing else.
 11
 12// callerOf returns the verified caller of a crossing function. rlm must be
 13// the cur of the crossing function calling this helper: a stale or forged
 14// realm value fails IsCurrent, and Previous is only meaningful on a live one.
 15//
 16// It takes the realm in second position on purpose, like p/nt/ownable does:
 17// a function whose first parameter is a realm is a crossing function.
 18func callerOf(_ int, rlm realm) address {
 19	if !rlm.IsCurrent() {
 20		panic(errSpoofedRealm)
 21	}
 22	return rlm.Previous().Address()
 23}
 24
 25// assertOwner panics unless the caller is the owner, and returns the caller.
 26func assertOwner(_ int, rlm realm) address {
 27	caller := callerOf(0, rlm)
 28	if !owner.OwnedBy(caller) {
 29		panic(errNotOwner)
 30	}
 31	return caller
 32}
 33
 34// assertAdmin panics unless the caller is an admin, and returns the caller.
 35func assertAdmin(_ int, rlm realm) address {
 36	caller := callerOf(0, rlm)
 37	if !IsAdmin(caller) {
 38		panic(errNotAdmin)
 39	}
 40	return caller
 41}
 42
 43// assertReferee panics unless the caller is a referee, and returns the caller.
 44func assertReferee(_ int, rlm realm) address {
 45	caller := callerOf(0, rlm)
 46	if !IsReferee(caller) {
 47		panic(errNotReferee)
 48	}
 49	return caller
 50}
 51
 52// TransferOwnership hands the realm over to newOwner. Owner only.
 53//
 54// The previous owner keeps no privilege, unless it was also added to the
 55// admin or referee lists.
 56func TransferOwnership(cur realm, newOwner address) {
 57	// ownable checks the caller and the address. It would take the address
 58	// written in capitals though, and an owner under that key could never be
 59	// matched to a caller again: see validAddress.
 60	if newOwner.IsValid() && !validAddress(newOwner) {
 61		panic(errInvalidAddress)
 62	}
 63	if err := owner.TransferOwnership(0, cur, newOwner); err != nil {
 64		panic(err)
 65	}
 66	bump()
 67}
 68
 69// AddAdmin adds addr to the admin list. Owner only.
 70func AddAdmin(cur realm, addr address) {
 71	assertOwner(0, cur)
 72	if !validAddress(addr) {
 73		panic(errInvalidAddress)
 74	}
 75	if admins.Set(addr.String(), nil) {
 76		panic(errAlreadyAdmin)
 77	}
 78	bump()
 79	chain.Emit("AdminAdded", "address", addr.String())
 80}
 81
 82// RemoveAdmin removes addr from the admin list. Owner only.
 83//
 84// The owner is an admin by definition and cannot be demoted this way, use
 85// TransferOwnership.
 86func RemoveAdmin(cur realm, addr address) {
 87	assertOwner(0, cur)
 88	if _, removed := admins.Remove(addr.String()); !removed {
 89		panic(errNoSuchAdmin)
 90	}
 91	bump()
 92	chain.Emit("AdminRemoved", "address", addr.String())
 93}
 94
 95// SetTreasury sets the address the sales of skins and planes are forwarded
 96// to. Owner only.
 97func SetTreasury(cur realm, addr address) {
 98	assertOwner(0, cur)
 99	if !validAddress(addr) {
100		panic(errInvalidAddress)
101	}
102	// Coins sent to the realm's own address would be stuck: nothing here
103	// ever spends the realm balance.
104	if addr == cur.Address() {
105		panic(errTreasurySelf)
106	}
107	treasury = addr
108	bump()
109	chain.Emit("TreasurySet", "address", addr.String())
110}
111
112// AddReferee allows addr to submit kills. Admin only.
113func AddReferee(cur realm, addr address) {
114	assertAdmin(0, cur)
115	if !validAddress(addr) {
116		panic(errInvalidAddress)
117	}
118	if referees.Set(addr.String(), nil) {
119		panic(errAlreadyReferee)
120	}
121	bump()
122	chain.Emit("RefereeAdded", "address", addr.String())
123}
124
125// RemoveReferee stops addr from submitting kills. Admin only.
126func RemoveReferee(cur realm, addr address) {
127	assertAdmin(0, cur)
128	if _, removed := referees.Remove(addr.String()); !removed {
129		panic(errNoSuchReferee)
130	}
131	bump()
132	chain.Emit("RefereeRemoved", "address", addr.String())
133}
134
135// Owner returns the owner of the realm.
136func Owner() address {
137	return owner.Owner()
138}
139
140// Treasury returns the address the sales of skins and planes are forwarded
141// to.
142func Treasury() address {
143	return treasury
144}
145
146// IsAdmin reports whether addr is an admin. The owner always is.
147func IsAdmin(addr address) bool {
148	return owner.OwnedBy(addr) || admins.Has(addr.String())
149}
150
151// IsReferee reports whether addr may submit kills.
152func IsReferee(addr address) bool {
153	return referees.Has(addr.String())
154}