roles.gno
1.84 Kb · 51 lines
1package skins
2
3import "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0"
4
5// The skins realm keeps no roles of its own. Who administers it and where
6// its money goes are the answers of the game realm, asked again at every
7// call: an admin removed there is refused here in the same block, and a
8// treasury moved there receives the next sale.
9
10// authority is the set of questions this realm asks about roles.
11type authority interface {
12 IsAdmin(addr address) bool
13 Treasury() address
14}
15
16// gameRoles answers with the roles of the game realm.
17type gameRoles struct{}
18
19func (gameRoles) IsAdmin(addr address) bool { return game.IsAdmin(addr) }
20func (gameRoles) Treasury() address { return game.Treasury() }
21
22// roles is the authority of this realm: the game realm, always.
23//
24// It is a variable for one reason. Under `gno test` an imported realm is
25// initialized without a deployer, and a test of this package has no way to
26// become an admin of the game realm, so the tests put their own answers
27// here. Nothing outside the test files assigns it, and there is no setter.
28var roles authority = gameRoles{}
29
30// callerOf returns the verified caller of a crossing function. rlm must be
31// the cur of the crossing function calling this helper: a stale or forged
32// realm value fails IsCurrent, and Previous is only meaningful on a live one.
33//
34// It takes the realm in second position on purpose, like p/nt/ownable does:
35// a function whose first parameter is a realm is a crossing function.
36func callerOf(_ int, rlm realm) address {
37 if !rlm.IsCurrent() {
38 panic(errSpoofedRealm)
39 }
40 return rlm.Previous().Address()
41}
42
43// assertAdmin panics unless the caller is an admin of the game realm, and
44// returns the caller.
45func assertAdmin(_ int, rlm realm) address {
46 caller := callerOf(0, rlm)
47 if !roles.IsAdmin(caller) {
48 panic(errNotAdmin)
49 }
50 return caller
51}