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.

aaabbb_test.gno

4.87 Kb · 127 lines
  1package aaabbb
  2
  3import (
  4	"chain"
  5	"strings"
  6	"testing"
  7
  8	"gno.land/p/nt/testutils/v0"
  9	"gno.land/p/nt/uassert/v0"
 10	"gno.land/r/nym-moultest123/x/pairreg/v0"
 11	"gno.land/r/nym-moultest123/x/pairs/aaa/v0"
 12	"gno.land/r/nym-moultest123/x/pairs/bbb/v0"
 13)
 14
 15const selfPath = "gno.land/r/nym-moultest123/x/pairs/aaabbb/v0"
 16
 17func self() address { return chain.PackageAddress(selfPath) }
 18
 19// fund gives addr both tokens and approves this instance to spend them.
 20func fund(cur realm, addr address) {
 21	testing.SetRealm(testing.NewUserRealm(addr))
 22	aaa.Faucet(cross(cur))
 23	bbb.Faucet(cross(cur))
 24	aaa.Approve(cross(cur), self(), 1_000_000_000)
 25	bbb.Approve(cross(cur), self(), 1_000_000_000)
 26}
 27
 28// Deploying the instance is the whole "factory call": its init builds the pair
 29// and announces it, so one addpkg both creates and lists it.
 30func TestSelfRegisteredAtInit(t *testing.T) {
 31	e := pairreg.Get(selfPath)
 32	uassert.True(t, e != nil, "instance must register itself in init")
 33	uassert.Equal(t, selfPath, e.Path)
 34	uassert.Equal(t, 1, pairreg.Size())
 35
 36	keyA, keyB := Keys()
 37	uassert.Equal(t, "gno.land/r/nym-moultest123/x/pairs/aaa/v0.AAA", keyA)
 38	uassert.Equal(t, "gno.land/r/nym-moultest123/x/pairs/bbb/v0.BBB", keyB)
 39}
 40
 41// The registry holds a live pointer into this realm's storage, so its own
 42// Render shows state it never copied. This is the property that lets one
 43// qrender describe a thousand instances.
 44func TestRegistrySeesLiveState(cur realm, t *testing.T) {
 45	alice := testutils.TestAddress("alice-live")
 46	fund(cur, alice)
 47	AddLiquidity(cross(cur), 1_000_000, 4_000_000)
 48
 49	e := pairreg.Get(selfPath)
 50	resA, resB := e.Pair.Reserves()
 51	uassert.Equal(t, int64(1_000_000), resA)
 52	uassert.Equal(t, int64(4_000_000), resB)
 53
 54	index := pairreg.Render("")
 55	uassert.True(t, strings.Contains(index, "AAA/BBB"), "index lists the couple")
 56	uassert.True(t, strings.Contains(index, "1000000 AAA"), "index shows live reserves")
 57	uassert.True(t, strings.Contains(index, "moul/x/pairs/aaabbb/v0"), "index links the instance")
 58
 59	// Wind the pair back down so the next test starts from an empty pool.
 60	RemoveLiquidity(cross(cur), TotalShares())
 61}
 62
 63// Full lifecycle through the instance's own entry points, which is also the
 64// proof that funds move to and from THIS realm's address while every line of
 65// logic runs in the shared pure package.
 66func TestLifecycle(cur realm, t *testing.T) {
 67	alice := testutils.TestAddress("alice-cycle")
 68	fund(cur, alice)
 69
 70	minted := AddLiquidity(cross(cur), 1_000_000, 4_000_000)
 71	uassert.Equal(t, int64(1_000_000), minted, "first deposit mints amountA, no sqrt")
 72	uassert.Equal(t, int64(1_000_000), aaa.BalanceOf(self()), "tokens land on the instance")
 73	uassert.Equal(t, int64(4_000_000), bbb.BalanceOf(self()))
 74	uassert.Equal(t, minted, SharesOf(alice))
 75
 76	quoted := Quote("gno.land/r/nym-moultest123/x/pairs/aaa/v0.AAA", 100_000)
 77	out := Swap(cross(cur), "gno.land/r/nym-moultest123/x/pairs/aaa/v0.AAA", 100_000, 362_000)
 78	uassert.Equal(t, int64(362_644), out, "same pricing as the single-realm design")
 79	uassert.Equal(t, quoted, out, "Quote matches what Swap pays")
 80
 81	resA, resB := Reserves()
 82	uassert.Equal(t, int64(1_100_000), resA)
 83	uassert.Equal(t, int64(3_637_356), resB)
 84
 85	gotA, gotB := RemoveLiquidity(cross(cur), 500_000)
 86	uassert.Equal(t, int64(550_000), gotA)
 87	uassert.Equal(t, int64(1_818_678), gotB)
 88
 89	// The last provider out is paid the whole reserve, so nothing is stranded.
 90	gotA, gotB = RemoveLiquidity(cross(cur), TotalShares())
 91	uassert.Equal(t, int64(550_000), gotA)
 92	uassert.Equal(t, int64(1_818_678), gotB)
 93	uassert.Equal(t, int64(0), TotalShares())
 94	uassert.Equal(t, int64(0), aaa.BalanceOf(self()), "instance holds nothing afterwards")
 95	uassert.Equal(t, int64(0), bbb.BalanceOf(self()))
 96}
 97
 98// A token this pair does not hold must be refused by name, not silently
 99// treated as one of the two sides. Asserted through Quote, which reaches the
100// same guard without a crossing call: a panic raised inside a crossing call
101// unwinds the whole transaction and is not recoverable by the caller.
102func TestRejectsForeignToken(cur realm, t *testing.T) {
103	alice := testutils.TestAddress("alice-foreign")
104	fund(cur, alice)
105	AddLiquidity(cross(cur), 1_000_000, 4_000_000)
106
107	uassert.PanicsWithMessage(t, cur, "pair: gno.land/r/nope/v0.NOPE is not in this pair", func() {
108		Quote("gno.land/r/nope/v0.NOPE", 1_000)
109	})
110	RemoveLiquidity(cross(cur), TotalShares())
111}
112
113func TestRender(cur realm, t *testing.T) {
114	alice := testutils.TestAddress("alice-render")
115	fund(cur, alice)
116
117	empty := Render("")
118	uassert.True(t, strings.Contains(empty, "# AAA / BBB"))
119	uassert.True(t, strings.Contains(empty, "Empty"), "empty pair says so")
120
121	AddLiquidity(cross(cur), 1_000_000, 4_000_000)
122	full := Render("")
123	uassert.True(t, strings.Contains(full, "| AAA | 1000000 |"), "reserves row")
124	uassert.True(t, strings.Contains(full, "LP shares: **1000000**"))
125	uassert.True(t, strings.Contains(full, "1 AAA buys ~4 BBB"), "spot line")
126	RemoveLiquidity(cross(cur), TotalShares())
127}