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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

vestoken_test.gno

3.37 Kb · 119 lines
  1package vestoken
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/testutils/v0"
  8	"gno.land/p/nt/uassert/v0"
  9)
 10
 11// Fixed test addresses. testutils.TestAddress derives real, valid-length
 12// addresses; literal strings would fail address.IsValid() and trip the realm's
 13// zero-address guard.
 14var (
 15	alice = testutils.TestAddress("alice")
 16	bob   = testutils.TestAddress("bob")
 17)
 18
 19// reset clears package state between tests so cases stay independent.
 20func reset() {
 21	balances = map[address]uint64{}
 22	grants = map[address]*grant{}
 23	totalSupply = 0
 24}
 25
 26// TestVestingUnlocksLinearly opens a grant, claims nothing before any
 27// blocks pass, half at the midpoint, and the rest once fully vested.
 28func TestVestingUnlocksLinearly(cur realm, t *testing.T) {
 29	reset()
 30
 31	testing.SetRealm(testing.NewUserRealm(alice))
 32	MintVested(cross(cur), alice, 1000, 100)
 33
 34	if got := TotalSupply(); got != 1000 {
 35		t.Fatalf("total supply = %d, want 1000", got)
 36	}
 37
 38	testing.SetRealm(testing.NewUserRealm(alice))
 39	if got := Claim(cross(cur)); got != 0 {
 40		t.Fatalf("claim at start = %d, want 0", got)
 41	}
 42
 43	testing.SkipHeights(50)
 44	testing.SetRealm(testing.NewUserRealm(alice))
 45	if got := Claim(cross(cur)); got != 500 {
 46		t.Fatalf("claim at midpoint = %d, want 500", got)
 47	}
 48	if got := BalanceOf(alice); got != 500 {
 49		t.Errorf("alice liquid balance = %d, want 500", got)
 50	}
 51
 52	testing.SkipHeights(50)
 53	testing.SetRealm(testing.NewUserRealm(alice))
 54	if got := Claim(cross(cur)); got != 500 {
 55		t.Fatalf("claim at end = %d, want 500", got)
 56	}
 57	if got := BalanceOf(alice); got != 1000 {
 58		t.Errorf("alice liquid balance = %d, want 1000", got)
 59	}
 60
 61	total, claimed, claimable := GrantOf(alice)
 62	if total != 0 || claimed != 0 || claimable != 0 {
 63		t.Errorf("grant should be gone after full claim, got total=%d claimed=%d claimable=%d", total, claimed, claimable)
 64	}
 65}
 66
 67// TestActiveGrantBlocksNewGrant asserts a beneficiary can't be granted twice
 68// while a previous grant is still unclaimed.
 69func TestActiveGrantBlocksNewGrant(cur realm, t *testing.T) {
 70	reset()
 71
 72	testing.SetRealm(testing.NewUserRealm(alice))
 73	MintVested(cross(cur), alice, 100, 10)
 74
 75	// Aborts from a cross(cur) call cannot be caught by a plain recover();
 76	// assert on the abort message instead.
 77	uassert.AbortsWithMessage(t, cur, "vestoken: beneficiary already has an unclaimed grant", func() {
 78		MintVested(cross(cur), alice, 50, 10)
 79	})
 80}
 81
 82// TestTransferClaimedBalance checks claimed tokens behave like a normal
 83// transferable ERC-20 balance.
 84func TestTransferClaimedBalance(cur realm, t *testing.T) {
 85	reset()
 86
 87	testing.SetRealm(testing.NewUserRealm(alice))
 88	MintVested(cross(cur), alice, 200, 10)
 89
 90	testing.SkipHeights(10)
 91	testing.SetRealm(testing.NewUserRealm(alice))
 92	Claim(cross(cur))
 93
 94	testing.SetRealm(testing.NewUserRealm(alice))
 95	Transfer(cross(cur), bob, 80)
 96
 97	if got := BalanceOf(alice); got != 120 {
 98		t.Errorf("alice balance = %d, want 120", got)
 99	}
100	if got := BalanceOf(bob); got != 80 {
101		t.Errorf("bob balance = %d, want 80", got)
102	}
103}
104
105// TestRenderContainsMetadata checks the Markdown view exposes name/symbol
106// and the active grant.
107func TestRenderContainsMetadata(cur realm, t *testing.T) {
108	reset()
109
110	testing.SetRealm(testing.NewUserRealm(alice))
111	MintVested(cross(cur), alice, 42, 10)
112
113	out := Render("")
114	for _, want := range []string{"VestToken", "VEST", "Total supply", "42"} {
115		if !strings.Contains(out, want) {
116			t.Errorf("render output missing %q\n%s", want, out)
117		}
118	}
119}