z_token_keys_copy_test.gno
1.73 Kb · 48 lines
1package test
2
3import (
4 "testing"
5
6 trs_pkg "gno.land/p/nt/treasury/v0"
7 "gno.land/p/nt/uassert/v0"
8
9 "gno.land/r/gov/dao/treasury/v0"
10)
11
12// Named z_* so it runs after the tests that assert exact token counts, since
13// this one replaces the treasury's token key list.
14
15// SetTokenKeys stores its argument into realm state that the grc20Lister
16// closure re-reads on every Balances() and every GRC20 payment. Held
17// uncopied, an allowed DAO realm would keep a write handle on the treasury's
18// live token set for good — able to swap it on any later block, with no
19// proposal and no vote behind it.
20//
21// The govdao_treasury_token_keys_are_immutable.txtar cannot cover this: the
22// copy in NewTreasuryGRC20TokensUpdate means the slice arriving here is
23// already impl's own, so the hazard is only reachable by calling SetTokenKeys
24// directly, as an allowed DAO realm does.
25func TestZSetTokenKeysCopiesItsArgument(cur realm, t *testing.T) {
26 testing.SetRealm(allowedRealm)
27
28 keyed := registerGRC20Tokens(0, cur, t, []string{"CopyTok"}, treasuryAddr)
29 grc20ID := trs_pkg.GRC20Banker{}.ID()
30
31 // The caller's own slice, handed over the way an allowed DAO realm's
32 // executor hands over the keys a proposal carried.
33 keys := []string{keyed[0].key}
34 treasury.SetTokenKeys(cross(cur), keys)
35
36 balances := treasury.Balances(grc20ID)
37 uassert.Equal(t, len(balances), 1)
38 uassert.Equal(t, balances[0].Denom, keyed[0].key)
39
40 // No proposal, no vote: the supplying realm rewrites its own array.
41 keys[0] = "gno.land/r/never/voted.EVIL"
42
43 // The treasury must still resolve the key it was given.
44 after := treasury.Balances(grc20ID)
45 uassert.Equal(t, len(after), 1,
46 "the treasury's token set followed the caller's rewrite")
47 uassert.Equal(t, after[0].Denom, keyed[0].key)
48}