Skip to content

Commit 2d24f08

Browse files
committed
Merge branch 'mconcat/refactor-emission-part-1' of https://github.com/gnoswap-labs/gnoswap into mconcat/refactor-emission-part-1
2 parents 6d67bc5 + 155c50a commit 2d24f08

8 files changed

+439
-437
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
package staker
2+
3+
import (
4+
"math"
5+
"std"
6+
"testing"
7+
8+
"gno.land/p/demo/uassert"
9+
10+
"gno.land/r/gnoswap/v1/consts"
11+
12+
en "gno.land/r/gnoswap/v1/emission"
13+
pl "gno.land/r/gnoswap/v1/pool"
14+
pn "gno.land/r/gnoswap/v1/position"
15+
16+
"gno.land/r/gnoswap/v1/gnft"
17+
"gno.land/r/gnoswap/v1/gns"
18+
19+
"gno.land/r/onbloc/bar"
20+
"gno.land/r/onbloc/baz"
21+
"gno.land/r/onbloc/qux"
22+
)
23+
24+
func TestShortWarmUpChangeTier(t *testing.T) {
25+
testInit(t)
26+
testDoubleMint(t)
27+
testCreatePool(t)
28+
testMintBarQux100_1(t)
29+
testMintBarBaz100_2(t)
30+
testSkip100Height(t)
31+
testStakeToken_1(t)
32+
testSetPoolTier(t)
33+
testStakeToken_2(t)
34+
testNow(t)
35+
testChangePoolTier(t)
36+
testNow2(t)
37+
}
38+
39+
func testInit(t *testing.T) {
40+
t.Run("init pool tiers", func(t *testing.T) {
41+
std.TestSetRealm(adminRealm)
42+
43+
// init pool tiers
44+
// tier 1
45+
deletePoolTier(t, MUST_EXISTS_IN_TIER_1)
46+
addPoolTier(t, `gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100`, 1)
47+
std.TestSkipHeights(1)
48+
49+
// override warm-up period for testing
50+
changeWarmup(t, 0, 150)
51+
changeWarmup(t, 1, 300)
52+
changeWarmup(t, 2, 900)
53+
changeWarmup(t, 3, math.MaxInt64)
54+
55+
// set unstaking fee to 0
56+
SetUnstakingFeeByAdmin(0)
57+
58+
// set pool creation fee to 0
59+
pl.SetPoolCreationFeeByAdmin(0)
60+
61+
// set community pool distribution to 0% (give it to devOps)
62+
en.ChangeDistributionPctByAdmin(
63+
1, 7500,
64+
2, 2500,
65+
3, 0,
66+
4, 0,
67+
)
68+
})
69+
}
70+
71+
func testDoubleMint(t *testing.T) {
72+
t.Run("mint and distribute gns", func(t *testing.T) {
73+
en.MintAndDistributeGns()
74+
en.MintAndDistributeGns()
75+
76+
std.TestSkipHeights(1)
77+
})
78+
}
79+
80+
func testCreatePool(t *testing.T) {
81+
t.Run("create pool", func(t *testing.T) {
82+
std.TestSetRealm(adminRealm)
83+
84+
gns.Approve(a2u(consts.POOL_ADDR), pl.GetPoolCreationFee()*3)
85+
86+
pl.CreatePool(barPath, quxPath, 100, "79228162514264337593543950337")
87+
pl.CreatePool(barPath, bazPath, 3000, "79228162514264337593543950337")
88+
89+
std.TestSkipHeights(1)
90+
})
91+
}
92+
93+
func testMintBarQux100_1(t *testing.T) {
94+
t.Run("mint position 01, bar:qux:100", func(t *testing.T) {
95+
std.TestSetRealm(adminRealm)
96+
97+
bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
98+
qux.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
99+
100+
tokenId, liquidity, amount0, amount1 := pn.Mint(
101+
barPath, // token0
102+
quxPath, // token1
103+
fee100, // fee
104+
int32(-1000), // tickLower
105+
int32(1000), // tickUpper
106+
"50", // amount0Desired
107+
"50", // amount1Desired
108+
"1", // amount0Min
109+
"1", // amount1Min
110+
max_timeout,
111+
adminAddr,
112+
adminAddr,
113+
)
114+
115+
uassert.Equal(t, tokenId, uint64(1))
116+
uassert.Equal(t, gnft.MustOwnerOf(tid(tokenId)), adminAddr)
117+
118+
gpi := getPrintInfo(t)
119+
// {"height":"126","time":"1234567896","gns":{"staker":"32106164","devOps":"10702053","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[]}]}
120+
121+
std.TestSkipHeights(1)
122+
})
123+
}
124+
125+
func testMintBarBaz100_2(t *testing.T) {
126+
t.Run("mint position 02, bar:baz:3000", func(t *testing.T) {
127+
std.TestSetRealm(adminRealm)
128+
129+
bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
130+
baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
131+
132+
tokenId, liquidity, amount0, amount1 := pn.Mint(
133+
barPath, // token0
134+
bazPath, // token1
135+
fee3000, // fee
136+
int32(-1020), // tickLower
137+
int32(1020), // tickUpper
138+
"50", // amount0Desired
139+
"50", // amount1Desired
140+
"1", // amount0Min
141+
"1", // amount1Min
142+
max_timeout,
143+
adminAddr,
144+
adminAddr,
145+
)
146+
147+
uassert.Equal(t, tokenId, uint64(2))
148+
uassert.Equal(t, gnft.MustOwnerOf(tid(tokenId)), adminAddr)
149+
150+
gpi := getPrintInfo(t)
151+
// {"height":"127","time":"1234567898","gns":{"staker":"42808219","devOps":"14269404","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[]}]}
152+
std.TestSkipHeights(1)
153+
})
154+
}
155+
156+
func testSkip100Height(t *testing.T) {
157+
t.Run("skip 100 heights", func(t *testing.T) {
158+
std.TestSkipHeights(100)
159+
160+
gpi := getPrintInfo(t)
161+
// {"height":"228","time":"1234568100","gns":{"staker":"1123715724","devOps":"374571905","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[]}]}
162+
163+
std.TestSkipHeights(1)
164+
})
165+
}
166+
167+
func testStakeToken_1(t *testing.T) {
168+
t.Run("stake token 01", func(t *testing.T) {
169+
std.TestSetRealm(adminRealm)
170+
171+
gnft.Approve(consts.STAKER_ADDR, tid(1))
172+
StakeToken(1)
173+
174+
gpi := getPrintInfo(t)
175+
// {"height":"229","time":"1234568102","gns":{"staker":"1134417779","devOps":"378139256","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"0","fullAmount":"0","ratio":"30","warmUpAmount":"0","full30":"0","give30":"0","penalty30":"0","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
176+
177+
std.TestSkipHeights(1)
178+
})
179+
}
180+
181+
func testSetPoolTier(t *testing.T) {
182+
t.Run("set pool tier", func(t *testing.T) {
183+
std.TestSkipHeights(100) // this reward should go to bar:qux:100
184+
185+
std.TestSetRealm(adminRealm)
186+
187+
addPoolTier(t, `gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000`, 2)
188+
gpi := getPrintInfo(t)
189+
// {"height":"330","time":"1234568304","gns":{"staker":"2215325284","devOps":"738441757","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000","tier":"2","numPoolSameTier":"2","position":[]},{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"101","fullAmount":"1080907453","ratio":"30","warmUpAmount":"324272236","full30":"1080907453","give30":"324272236","penalty30":"756635217","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
190+
std.TestSkipHeights(1)
191+
})
192+
}
193+
194+
func testStakeToken_2(t *testing.T) {
195+
t.Run("stake token 02", func(t *testing.T) {
196+
std.TestSetRealm(adminRealm)
197+
198+
gnft.Approve(consts.STAKER_ADDR, tid(2))
199+
StakeToken(2)
200+
201+
gpi := getPrintInfo(t)
202+
// {"height":"331","time":"1234568306","gns":{"staker":"2226027339","devOps":"742009108","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000","tier":"2","numPoolSameTier":"2","position":[{"lpTokenId":"2","stakedHeight":"331","stakedTimestamp":"1234568306","stakedDuration":"0","fullAmount":"0","ratio":"30","warmUpAmount":"0","full30":"0","give30":"0","penalty30":"0","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]},{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"102","fullAmount":"764126573","ratio":"30","warmUpAmount":"229237972","full30":"764126573","give30":"229237972","penalty30":"534888601","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
203+
std.TestSkipHeights(1)
204+
})
205+
}
206+
207+
func testNow(t *testing.T) {
208+
t.Run("now", func(t *testing.T) {
209+
std.TestSetRealm(adminRealm)
210+
211+
gpi := getPrintInfo(t)
212+
// {"height":"332","time":"1234568308","gns":{"staker":"2236729394","devOps":"745576459","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000","tier":"2","numPoolSameTier":"2","position":[{"lpTokenId":"2","stakedHeight":"331","stakedTimestamp":"1234568306","stakedDuration":"1","fullAmount":"3210615","ratio":"30","warmUpAmount":"963184","full30":"3210615","give30":"963184","penalty30":"2247431","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]},{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"1","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"103","fullAmount":"771618010","ratio":"30","warmUpAmount":"231485403","full30":"771618010","give30":"231485403","penalty30":"540132607","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
213+
214+
std.TestSkipHeights(1)
215+
})
216+
}
217+
218+
func testChangePoolTier(t *testing.T) {
219+
t.Run("change pool tier", func(t *testing.T) {
220+
std.TestSetRealm(adminRealm)
221+
222+
changePoolTier(t, `gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000`, 1)
223+
224+
gpi := getPrintInfo(t)
225+
// {"height":"333","time":"1234568310","gns":{"staker":"2247431449","devOps":"749143810","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000","tier":"1","numPoolSameTier":"2","position":[{"lpTokenId":"2","stakedHeight":"331","stakedTimestamp":"1234568306","stakedDuration":"2","fullAmount":"6421231","ratio":"30","warmUpAmount":"1926369","full30":"6421231","give30":"1926369","penalty30":"4494862","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]},{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"2","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"104","fullAmount":"779109447","ratio":"30","warmUpAmount":"233732834","full30":"779109447","give30":"233732834","penalty30":"545376613","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
226+
227+
std.TestSkipHeights(1)
228+
})
229+
}
230+
231+
func testNow2(t *testing.T) {
232+
std.TestSetRealm(adminRealm)
233+
234+
gpi := getPrintInfo(t)
235+
// {"height":"334","time":"1234568312","gns":{"staker":"2258133504","devOps":"752711161","communityPool":"0","govStaker":"0","protocolFee":"0","GnoswapAdmin":"100000000000000"},"pool":[{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000","tier":"1","numPoolSameTier":"2","position":[{"lpTokenId":"2","stakedHeight":"331","stakedTimestamp":"1234568306","stakedDuration":"3","fullAmount":"5351026","ratio":"30","warmUpAmount":"1605308","full30":"5351026","give30":"1605308","penalty30":"3745718","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]},{"poolPath":"gno.land/r/onbloc/bar:gno.land/r/onbloc/qux:100","tier":"1","numPoolSameTier":"2","position":[{"lpTokenId":"1","stakedHeight":"229","stakedTimestamp":"1234568102","stakedDuration":"105","fullAmount":"399721625","ratio":"30","warmUpAmount":"119916487","full30":"399721625","give30":"119916487","penalty30":"279805138","full50":"0","give50":"0","penalty50":"0","full70":"0","give70":"0","penalty70":"0","full100":"0","give100":"0","penalty100":"0"}]}]}
236+
}

staker/reward_calculation_canonical_test.gno

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package staker
33
// Evaluate against the canonical implementation
44

55
import (
6+
"math"
67
"std"
78
"testing"
89
"strings"
@@ -49,6 +50,73 @@ func TestSimple(t *testing.T) {
4950
canonical.AssertCanonicalRewardOf(0, expected)
5051
}
5152

53+
// To check precision error
54+
func TestLargeStakedLiquidity(t *testing.T) {
55+
canonical := Setup(t)
56+
57+
gnousdc := test_gnousdc
58+
canonical.CreatePool(gnousdc, 1, 150)
59+
60+
canonical.StakeToken(
61+
0,
62+
gnousdc,
63+
std.Address("gno1qyqszqgpqyqszqgpqyqszqgpqyqszqgp"),
64+
100,
65+
200,
66+
q128,
67+
)
68+
69+
canonical.NextBlock()
70+
71+
canonical.AssertCanonicalInternalRewardPerPool(gnousdc, canonical.PerBlockEmission)
72+
73+
expected := canonical.PerBlockEmission * 30 / 100
74+
canonical.AssertEmulatedRewardOf(0, expected)
75+
canonical.AssertCanonicalRewardOf(0, expected)
76+
}
77+
78+
// To check precision error
79+
func TestLargeStakedLiquidity_2(t *testing.T) {
80+
canonical := Setup(t)
81+
82+
gnousdc := test_gnousdc
83+
canonical.CreatePool(gnousdc, 1, 150)
84+
85+
u2_30 := uint64(1073741824)
86+
u2_33 := uint64(17179869184/2)
87+
88+
canonical.SetEmissionUpdate(math.MaxUint64/100)
89+
90+
canonical.StakeToken(
91+
0,
92+
gnousdc,
93+
std.Address("gno1qyqszqgpqyqszqgpqyqszqgpqyqszqgp"),
94+
100,
95+
200,
96+
u256.NewUint(u2_30),
97+
)
98+
99+
canonical.StakeToken(
100+
1,
101+
gnousdc,
102+
std.Address("gno1qyqszqgpqyqszqgpqyqszqgpqyqszqgq"),
103+
100,
104+
200,
105+
u256.NewUint(u2_33),
106+
)
107+
108+
canonical.NextBlock()
109+
110+
canonical.AssertCanonicalInternalRewardPerPool(gnousdc, canonical.PerBlockEmission)
111+
112+
expected := canonical.PerBlockEmission / 100 * 30
113+
canonical.AssertEmulatedRewardOf(0, expected/9)
114+
canonical.AssertCanonicalRewardOf(0, expected/9)
115+
116+
canonical.AssertEmulatedRewardOf(1, expected/9*8)
117+
canonical.AssertCanonicalRewardOf(1, expected/9*8)
118+
}
119+
52120
// Tests simple case with tick crossing
53121
func TestTickCross_0(t *testing.T) {
54122
canonical := Setup(t)
@@ -1036,5 +1104,4 @@ func TestTickCross_9(t *testing.T) {
10361104
}
10371105
canonical.AssertEmulatedRewardMap(canonicalRewardMap)
10381106
}
1039-
1040-
}
1107+
}

0 commit comments

Comments
 (0)