From 55a12bc478da94a7018e11cb80c0039a7492a8be Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 24 Dec 2024 02:24:19 +0900 Subject: [PATCH 01/12] fix: position - use `new` operator to use pointer value from other contract - reposition should update values based on new tick ranges --- position/_RPC_api.gno | 2 +- ...__TEST_fee_collect_with_two_user_test.gnoA | 159 ++++++++++++++++++ .../{tests => }/__TEST_position_api_test.gnoA | 10 +- .../__TEST_position_full_test.gnoA | 4 +- ...TEST_position_full_with_emission_test.gnoA | 4 +- ...osition_increase_burned_position_test.gnoA | 20 +-- ..._TEST_position_increase_decrease_test.gnoA | 26 +-- ...nt_gnot_grc20_in-range_out-range_test.gnoA | 12 +- ...EST_position_mint_swap_burn_left_test.gnoA | 16 +- ...osition_native_increase_decrease_test.gnoA | 66 ++++---- ...T_position_native_mint_swap_burn_test.gnoA | 40 ++--- ...ST_position_reposition_gnot_pair_test.gno} | 53 +++--- ...T_position_reposition_grc20_pair_test.gnoA | 32 ++-- ..._reposition_grc20_pair_with_swap_test.gnoA | 31 ++-- ...iff_range_diff_position_swap_fee_test.gnoA | 12 +- ...ame_range_diff_position_swap_fee_test.gnoA | 12 +- ...st_two_position_used_single_swap_test.gnoA | 12 +- ...owed_left_grc20_pair_more_action_test.gnoA | 67 ++++---- ...owed_left_pair_more_action_exact_test.gnoA | 58 +++---- .../__TEST_position_unclaimed_fee_test.gnoA | 32 ++-- position/_helper_test.gno | 27 ++- position/liquidity_management.gno | 2 +- ...est.gno => liquidity_management_test.gnoA} | 0 position/native_token.gno | 2 +- ..._token_test.gno => native_token_test.gnoA} | 0 position/position.gno | 92 ++++++---- .../{position_test.gno => position_test.gnoA} | 0 .../__TEST_0_INIT_VARS_HELPERS_test.gnoA | 2 +- ...__TEST_fee_collect_with_two_user_test.gnoA | 156 ----------------- position/{utils_test.gno => utils_test.gnoA} | 2 +- staker/staker.gno | 3 +- 31 files changed, 499 insertions(+), 455 deletions(-) create mode 100644 position/__TEST_fee_collect_with_two_user_test.gnoA rename position/{tests => }/__TEST_position_api_test.gnoA (95%) rename position/{tests => }/__TEST_position_full_test.gnoA (98%) rename position/{tests => }/__TEST_position_full_with_emission_test.gnoA (99%) rename position/{tests => }/__TEST_position_increase_burned_position_test.gnoA (89%) rename position/{tests => }/__TEST_position_increase_decrease_test.gnoA (91%) rename position/{tests => }/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA (93%) rename position/{tests => }/__TEST_position_mint_swap_burn_left_test.gnoA (98%) rename position/{tests => }/__TEST_position_native_increase_decrease_test.gnoA (71%) rename position/{tests => }/__TEST_position_native_mint_swap_burn_test.gnoA (84%) rename position/{tests/__TEST_position_reposition_gnot_pair_test.gnoA => __TEST_position_reposition_gnot_pair_test.gno} (86%) rename position/{tests => }/__TEST_position_reposition_grc20_pair_test.gnoA (92%) rename position/{tests => }/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA (96%) rename position/{tests => }/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA (98%) rename position/{tests => }/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA (98%) rename position/{tests => }/__TEST_position_test_two_position_used_single_swap_test.gnoA (97%) rename position/{tests => }/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA (84%) rename position/{tests => }/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA (92%) rename position/{tests => }/__TEST_position_unclaimed_fee_test.gnoA (93%) rename position/{liquidity_management_test.gno => liquidity_management_test.gnoA} (100%) rename position/{native_token_test.gno => native_token_test.gnoA} (100%) rename position/{position_test.gno => position_test.gnoA} (100%) delete mode 100644 position/tests/__TEST_fee_collect_with_two_user_test.gnoA rename position/{utils_test.gno => utils_test.gnoA} (99%) diff --git a/position/_RPC_api.gno b/position/_RPC_api.gno index 5afcdd684..b5b37db1c 100644 --- a/position/_RPC_api.gno +++ b/position/_RPC_api.gno @@ -392,7 +392,7 @@ func rpcMakePosition(lpTokenId uint64) RpcPosition { currentX96, lowerX96, upperX96, - i256.FromUint256(position.liquidity), + position.liquidity, ) unclaimedFee0 := i256.Zero() diff --git a/position/__TEST_fee_collect_with_two_user_test.gnoA b/position/__TEST_fee_collect_with_two_user_test.gnoA new file mode 100644 index 000000000..baa6d7157 --- /dev/null +++ b/position/__TEST_fee_collect_with_two_user_test.gnoA @@ -0,0 +1,159 @@ +package position + +import ( + "std" + "testing" + "time" + + "gno.land/p/demo/testutils" + + "gno.land/r/gnoswap/v1/common" + "gno.land/r/gnoswap/v1/consts" + + "gno.land/r/gnoswap/v1/gns" + "gno.land/r/onbloc/bar" + "gno.land/r/onbloc/baz" + + pl "gno.land/r/gnoswap/v1/pool" +) + +var ( + user1Adderss = testutils.TestAddress("user1") + user1Realm = std.NewUserRealm(user1Adderss) + user2Adderss = testutils.TestAddress("user2") + user2Realm = std.NewUserRealm(user2Adderss) + tickSpacing = int32(60) + minTick = (consts.MIN_TICK / tickSpacing) * tickSpacing + maxTick = (consts.MAX_TICK / tickSpacing) * tickSpacing + + poolCreationFee = uint64(100_000_000) +) + +/* +This test demonstrates a issue(Gnoswap-19) fee collection mechanism. The key steps are: + +· Create a pool and add liquidity from two different users +· Perform swaps to generate fees in the pool +· Burn 0 liquidity to update fees +· Collect fees for both users +· Compare the collected fees between the two users +*/ +func TestCollectFeeWithTwoUser(t *testing.T) { + std.TestSetRealm(adminRealm) + common.SetLimitCaller(true) + gns.Approve(a2u(consts.POOL_ADDR), poolCreationFee) + + // -23028 + pl.CreatePool(barPath, bazPath, 3000, "25054144837504793118641380156") // encodePriceSqrt(1, 10) + poolPath := "gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000" + + // initial balance for user1 & user2 + bar.Transfer(a2u(user1Adderss), 100_000_000) + baz.Transfer(a2u(user1Adderss), 100_000_000) + bar.Transfer(a2u(user2Adderss), 100_000_000) + baz.Transfer(a2u(user2Adderss), 100_000_000) + + t.Run("mint and swap fee should be distributed to user's liquidity", func(t *testing.T) { + std.TestSetRealm(user1Realm) + bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + bar.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) + baz.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) + + tokenId_res1, liquidity_res1, amount0_res1, amount1_res1 := Mint( + barPath, // token0 string, + bazPath, // token1 string, + 3000, // fee uint32, + -43020, // tickLower int32, + 0, // tickUpper int32, + "10000000", // _amount0Desired string, // *u256.Uint // 100e18 + "10000000", // _amount1Desired string, // *u256.Uint // 100e18 + "0", // _amount0Min string, // *u256.Uint + "0", // _amount1Min string, // *u256.Uint + time.Now().Unix()+1000, // deadline int64, + user1Adderss, // mintTo string + user1Adderss, + ) + println("tokenId_res1:", tokenId_res1) + + std.TestSetRealm(user2Realm) + bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + bar.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) + baz.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) + + tokenId_res2, liquidity_res2, amount0_res2, amount1_res2 := Mint( + barPath, // token0 string, + bazPath, // token1 string, + 3000, // fee uint32, + -43020, // tickLower int32, + 0, // tickUpper int32, + "10000000", // _amount0Desired string, // *u256.Uint // 100e18 + "10000000", // _amount1Desired string, // *u256.Uint // 100e18 + "0", // _amount0Min string, // *u256.Uint + "0", // _amount1Min string, // *u256.Uint + time.Now().Unix()+1000, // deadline int64, + user2Adderss, // mintTo string + user2Adderss, + ) + // println("tokenId_res2:", tokenId_res2) + + // ====== Swap to accrue fees ====== + // pr.SwapRoute( + // barPath, //inputToken string, + // bazPath, //outputToken string, + // "10000000", //_amountSpecified string, // int256 + // "EXACT_IN", //swapType string, + // barPath+":"+bazPath+":3000", //strRouteArr string, // []string + // "100", //quoteArr string, // []int + // "0", //_tokenAmountLimit string, // uint256 + // ) + + // pr.SwapRoute( + // bazPath, //inputToken string, + // barPath, //outputToken string, + // "10000000", //_amountSpecified string, // int256 + // "EXACT_IN", //swapType string, + // bazPath+":"+barPath+":3000", //strRouteArr string, // []string + // "100", //quoteArr string, // []int + // "0", //_tokenAmountLimit string, // uint256 + // ) + + // ====== Collect fees and compare ====== + // user1 + // std.TestSetRealm(user1Realm) + // bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // userBarBalanceBeforeCollect_1 := bar.BalanceOf(a2u(user1Adderss)) + // userBazBalanceBeforeCollect_1 := baz.BalanceOf(a2u(user1Adderss)) + // tokenId_res3, withoutFee0_res3, withoutFee1_res3, positionPoolKey_res3, _, _ := CollectFee(tokenId_res1, false) + // userBarBalanceAfterCollect_1 := bar.BalanceOf(a2u(user1Adderss)) + // userBazBalanceAfterCollect_1 := baz.BalanceOf(a2u(user1Adderss)) + + // // user2 + // std.TestSetRealm(user2Realm) + // bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // userBarBalanceBeforeCollect_2 := bar.BalanceOf(a2u(user2Adderss)) + // userBazBalanceBeforeCollect_2 := baz.BalanceOf(a2u(user2Adderss)) + // tokenId_res4, withoutFee0_res4, withoutFee1_res4, positionPoolKey_res4, _, _ := pn.CollectFee(tokenId_res2, false) + // userBarBalanceAfterCollect_2 := bar.BalanceOf(a2u(user2Adderss)) + // userBazBalanceAfterCollect_2 := baz.BalanceOf(a2u(user2Adderss)) + // uassert.Equal(t, (userBarBalanceAfterCollect_1-userBarBalanceBeforeCollect_1)-(userBarBalanceAfterCollect_2-userBarBalanceBeforeCollect_2), uint64(0)) + // uassert.Equal(t, (userBazBalanceAfterCollect_1-userBazBalanceBeforeCollect_1)-(userBazBalanceAfterCollect_2-userBazBalanceBeforeCollect_2), uint64(0)) + }) +} + +func TestCollectTwo(t *testing.T) { + std.TestSetRealm(user1Realm) + bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + CollectFee(uint64(1), false) + + // std.TestSetRealm(user2Realm) + // bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) + // CollectFee(uint64(2), false) + + // tokenId_res3, withoutFee0_res3, withoutFee1_res3, positionPoolKey_res3, _, _ := CollectFee(uint64(1), false) +} diff --git a/position/tests/__TEST_position_api_test.gnoA b/position/__TEST_position_api_test.gnoA similarity index 95% rename from position/tests/__TEST_position_api_test.gnoA rename to position/__TEST_position_api_test.gnoA index 0201c1443..b01673e7c 100644 --- a/position/tests/__TEST_position_api_test.gnoA +++ b/position/__TEST_position_api_test.gnoA @@ -39,10 +39,10 @@ func TestMintFooBar(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // admin mints => will get tid 1 nft - Mint(fooPath, barPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, admin, admin) + Mint(fooPath, barPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, admin) // admin mints => will get tid 2 nft - Mint(fooPath, barPath, fee500, int32(4000), int32(6000), "1000000", "1000000", "0", "0", max_timeout, admin, admin) + Mint(fooPath, barPath, fee500, int32(4000), int32(6000), "1000000", "1000000", "0", "0", max_timeout, adminAddr, admin) } func TestMintBazQux(t *testing.T) { @@ -51,7 +51,7 @@ func TestMintBazQux(t *testing.T) { qux.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // admin mints => will get tid 3 nft - Mint(bazPath, quxPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, admin, admin) + Mint(bazPath, quxPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, admin) } func TestApiGetPositionsUnclaimedFee(t *testing.T) { @@ -82,11 +82,11 @@ func TestSwap(t *testing.T) { fooPath, barPath, fee500, - admin, + adminAddr, true, "123456", consts.MIN_PRICE, - admin, + adminAddr, ) } diff --git a/position/tests/__TEST_position_full_test.gnoA b/position/__TEST_position_full_test.gnoA similarity index 98% rename from position/tests/__TEST_position_full_test.gnoA rename to position/__TEST_position_full_test.gnoA index abf32fa4b..f49b2d064 100644 --- a/position/tests/__TEST_position_full_test.gnoA +++ b/position/__TEST_position_full_test.gnoA @@ -43,8 +43,8 @@ func TestMintPositionFullInRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) } diff --git a/position/tests/__TEST_position_full_with_emission_test.gnoA b/position/__TEST_position_full_with_emission_test.gnoA similarity index 99% rename from position/tests/__TEST_position_full_with_emission_test.gnoA rename to position/__TEST_position_full_with_emission_test.gnoA index 2c8e74399..babffe3fa 100644 --- a/position/tests/__TEST_position_full_with_emission_test.gnoA +++ b/position/__TEST_position_full_with_emission_test.gnoA @@ -72,8 +72,8 @@ func testMintPositionFullInRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(1) diff --git a/position/tests/__TEST_position_increase_burned_position_test.gnoA b/position/__TEST_position_increase_burned_position_test.gnoA similarity index 89% rename from position/tests/__TEST_position_increase_burned_position_test.gnoA rename to position/__TEST_position_increase_burned_position_test.gnoA index 1fcfe4cc7..29d986473 100644 --- a/position/tests/__TEST_position_increase_burned_position_test.gnoA +++ b/position/__TEST_position_increase_burned_position_test.gnoA @@ -46,8 +46,8 @@ func TestMintPosition(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) uassert.Equal(t, getNextId(), uint64(2)) @@ -60,8 +60,8 @@ func TestIncreaseLiquidity(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), 3678979) foo.Approve(a2u(consts.POOL_ADDR), 10000000) - pool := getPoolFromLpTokenId(uint64(1)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t,uint64(1)) + oldLiquidity := pool.Liquidity() _, _, m0, m1, _ := IncreaseLiquidity( uint64(1), // tokenId @@ -75,14 +75,14 @@ func TestIncreaseLiquidity(t *testing.T) { uassert.Equal(t, m0, "3678979") uassert.Equal(t, m1, "10000000") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) } func TestDecreaseLiquidity(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() DecreaseLiquidity( uint64(1), // tokenId @@ -93,7 +93,7 @@ func TestDecreaseLiquidity(t *testing.T) { false, // unwrapResult ) - newLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left @@ -129,8 +129,8 @@ func TestIncreaseLiquidityBurnedPosition(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - pool := getPoolFromLpTokenId(uint64(1)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t,uint64(1)) + oldLiquidity := pool.Liquidity() position := MustGetPosition(uint64(1)) uassert.Equal(t, position.burned, true) // it is burned @@ -147,7 +147,7 @@ func TestIncreaseLiquidityBurnedPosition(t *testing.T) { uassert.Equal(t, m0, "3678979") uassert.Equal(t, m1, "10000000") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) position = MustGetPosition(uint64(1)) diff --git a/position/tests/__TEST_position_increase_decrease_test.gnoA b/position/__TEST_position_increase_decrease_test.gnoA similarity index 91% rename from position/tests/__TEST_position_increase_decrease_test.gnoA rename to position/__TEST_position_increase_decrease_test.gnoA index 5abf8059a..bc1ff69bf 100644 --- a/position/tests/__TEST_position_increase_decrease_test.gnoA +++ b/position/__TEST_position_increase_decrease_test.gnoA @@ -38,8 +38,8 @@ func TestMintPosition(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) uassert.Equal(t, getNextId(), uint64(2)) @@ -52,8 +52,8 @@ func TestIncreaseLiquidity(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), 3678979) foo.Approve(a2u(consts.POOL_ADDR), 10000000) - pool := getPoolFromLpTokenId(uint64(1)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t,uint64(1)) + oldLiquidity := pool.Liquidity() _, _, m0, m1, _ := IncreaseLiquidity( uint64(1), // tokenId @@ -67,7 +67,7 @@ func TestIncreaseLiquidity(t *testing.T) { uassert.Equal(t, m0, "3678979") uassert.Equal(t, m1, "10000000") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) } @@ -92,11 +92,11 @@ func TestSwap(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) } @@ -134,11 +134,11 @@ func TestSwap2(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1000000", consts.MIN_PRICE, - admin, + adminAddr, ) // UNCLAIMED_FEE @@ -158,7 +158,7 @@ func TestSwap2(t *testing.T) { func TestDecreaseLiquidity(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() DecreaseLiquidity( uint64(1), // tokenId @@ -169,7 +169,7 @@ func TestDecreaseLiquidity(t *testing.T) { false, // unwrapResult ) - newLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left @@ -182,7 +182,7 @@ func TestDecreaseLiquidity(t *testing.T) { func TestDecreaseLiquidityAllThenAgainShouldPanic(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() DecreaseLiquidity( uint64(1), // tokenId @@ -193,7 +193,7 @@ func TestDecreaseLiquidityAllThenAgainShouldPanic(t *testing.T) { false, // unwrapResult ) - newLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) uassert.Equal(t, newLiquidity.ToString(), "0") diff --git a/position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA b/position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA similarity index 93% rename from position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA rename to position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA index e0d17d967..e2e4def2a 100644 --- a/position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA +++ b/position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA @@ -39,10 +39,10 @@ func TestFreshUser(t *testing.T) { // fresh users will have... // 100_000_000 ugnot // 100_000_000 gns - uassert.Equal(t, ugnotBalanceOf(fresh01), uint64(100_000_000)) + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(100_000_000)) uassert.Equal(t, gns.BalanceOf(a2u(fresh01)), uint64(100_000_000)) - uassert.Equal(t, ugnotBalanceOf(fresh02), uint64(100_000_000)) + uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(100_000_000)) uassert.Equal(t, gns.BalanceOf(a2u(fresh02)), uint64(100_000_000)) } @@ -111,7 +111,7 @@ func TestOneSideOnlyUgnot(t *testing.T) { std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) - uassert.Equal(t, ugnotBalanceOf(fresh01), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(0)) std.TestSetRealm(fresh01Realm) tokenId, liquidity, amount0, amount1 := Mint( @@ -132,7 +132,7 @@ func TestOneSideOnlyUgnot(t *testing.T) { // send 100_000_000 // mint 900_00_000 // => remain 10_000_000 - uassert.Equal(t, ugnotBalanceOf(fresh01), uint64(10_000_000)) + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(10_000_000)) uassert.Equal(t, wugnot.BalanceOf(a2u(fresh01)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 } @@ -147,7 +147,7 @@ func TestBothWithFresh(t *testing.T) { std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) - uassert.Equal(t, ugnotBalanceOf(fresh02), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(0)) std.TestSetRealm(fresh02Realm) tokenId, liquidity, amount0, amount1 := Mint( @@ -168,7 +168,7 @@ func TestBothWithFresh(t *testing.T) { // send 100_000_000 // mint 70_000_000 // => remain 30_000_000 - uassert.Equal(t, ugnotBalanceOf(fresh02), uint64(30_000_000)) + uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(30_000_000)) uassert.Equal(t, wugnot.BalanceOf(a2u(fresh02)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 } diff --git a/position/tests/__TEST_position_mint_swap_burn_left_test.gnoA b/position/__TEST_position_mint_swap_burn_left_test.gnoA similarity index 98% rename from position/tests/__TEST_position_mint_swap_burn_left_test.gnoA rename to position/__TEST_position_mint_swap_burn_left_test.gnoA index a8360d355..e240c13ce 100644 --- a/position/tests/__TEST_position_mint_swap_burn_left_test.gnoA +++ b/position/__TEST_position_mint_swap_burn_left_test.gnoA @@ -53,8 +53,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -87,8 +87,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -135,11 +135,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") @@ -178,11 +178,11 @@ func TestSwap2(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "20000000", // consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "20000000") diff --git a/position/tests/__TEST_position_native_increase_decrease_test.gnoA b/position/__TEST_position_native_increase_decrease_test.gnoA similarity index 71% rename from position/tests/__TEST_position_native_increase_decrease_test.gnoA rename to position/__TEST_position_native_increase_decrease_test.gnoA index 9b676a9fa..a26971a6a 100644 --- a/position/tests/__TEST_position_native_increase_decrease_test.gnoA +++ b/position/__TEST_position_native_increase_decrease_test.gnoA @@ -42,20 +42,20 @@ func testMintPosition(t *testing.T) { wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // WRAP // prepare 50000005ugnot (5 for refund test) - std.TestIssueCoins(admin, std.Coins{{"ugnot", 50000005}}) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(50000005)) + std.TestIssueCoins(adminAddr, std.Coins{{"ugnot", 50000005}}) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(50000005)) std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 200000000}}) - uassert.Equal(t, ugnotBalanceOf(consts.POSITION_ADDR), uint64(200000000)) + uassert.Equal(t, ugnotBalanceOf(t, consts.POSITION_ADDR), uint64(200000000)) // send & set orig send banker := std.GetBanker(std.BankerTypeRealmIssue) - banker.SendCoins(admin, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) + banker.SendCoins(adminAddr, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) std.TestSetOrigSend(std.Coins{{"ugnot", 50000005}}, nil) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(0)) - adminOldWugnotBalance := wugnot.BalanceOf(a2u(admin)) + adminOldWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, adminOldWugnotBalance, uint64(0)) tokenId, liquidity, amount0, amount1 := Mint( @@ -69,8 +69,8 @@ func testMintPosition(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -82,9 +82,9 @@ func testMintPosition(t *testing.T) { uassert.Equal(t, position.poolKey, "gno.land/r/demo/wugnot:gno.land/r/gnoswap/v1/gns:500") // SPEND ALL WUGNOT - uassert.Equal(t, wugnot.BalanceOf(a2u(admin)), uint64(0)) + uassert.Equal(t, wugnot.BalanceOf(admin), uint64(0)) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(5)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(5)) // 1. 50000005 ugnot sent // 2. 50000005 ugnot wrapped to wugnot // 3. 50000000 wugnot spent to mint (amount1) @@ -101,21 +101,21 @@ func testIncreaseLiquidity(t *testing.T) { wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // WRAP - pool := getPoolFromLpTokenId(uint64(1)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t,uint64(1)) + oldLiquidity := pool.Liquidity() // prepare 10000005ugnot (5 for refund test) - std.TestIssueCoins(admin, std.Coins{{"ugnot", 10000005}}) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(10000010)) - uassert.Equal(t, ugnotBalanceOf(consts.POSITION_ADDR), uint64(200000000)) + std.TestIssueCoins(adminAddr, std.Coins{{"ugnot", 10000005}}) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(10000010)) + uassert.Equal(t, ugnotBalanceOf(t, consts.POSITION_ADDR), uint64(200000000)) // send & set orig send banker := std.GetBanker(std.BankerTypeRealmIssue) - banker.SendCoins(admin, consts.POSITION_ADDR, std.Coins{{"ugnot", 10000005}}) + banker.SendCoins(adminAddr, consts.POSITION_ADDR, std.Coins{{"ugnot", 10000005}}) std.TestSetOrigSend(std.Coins{{"ugnot", 10000005}}, nil) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(5)) - uassert.Equal(t, wugnot.BalanceOf(a2u(admin)), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(5)) + uassert.Equal(t, wugnot.BalanceOf(admin), uint64(0)) _, _, m0, m1, _ := IncreaseLiquidity( // tokenId, liq, a0, a1, poolPath uint64(1), // tokenId @@ -128,14 +128,14 @@ func testIncreaseLiquidity(t *testing.T) { uassert.Equal(t, m0, "10000000") uassert.Equal(t, m1, "3678979") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) // SPEND ALL WUGNOT - uassert.Equal(t, wugnot.BalanceOf(a2u(admin)), uint64(0)) + uassert.Equal(t, wugnot.BalanceOf(admin), uint64(0)) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(10)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(10)) // 1. 10000005 ugnot sent // 2. 10000005 ugnot wrapped to wugnot // 3. 10000000 wugnot spent to mint (amount1) @@ -148,12 +148,12 @@ func testDecreaseLiquidityWrapped(t *testing.T) { t.Run("decrease liquidity wrapped", func(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() - userWugnotBalance := wugnot.BalanceOf(a2u(admin)) + userWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, userWugnotBalance, uint64(0)) - userUgnotBalance := ugnotBalanceOf(admin) + userUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, userUgnotBalance, uint64(10)) _, _, _, _, a0, a1, _ := DecreaseLiquidity( // tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath @@ -165,13 +165,13 @@ func testDecreaseLiquidityWrapped(t *testing.T) { false, // unwrapResult ) - userWugnotBalance = wugnot.BalanceOf(a2u(admin)) // wrapped result, so wunogt increased + userWugnotBalance = wugnot.BalanceOf(admin) // wrapped result, so wunogt increased uassert.Equal(t, userWugnotBalance, uint64(11999999)) - userUgnotBalance = ugnotBalanceOf(admin) // wrapped result, so ugnot didn't change + userUgnotBalance = ugnotBalanceOf(t, adminAddr) // wrapped result, so ugnot didn't change uassert.Equal(t, userUgnotBalance, uint64(10)) - newLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left @@ -187,12 +187,12 @@ func testDecreaseLiquidityUnwrapped(t *testing.T) { t.Run("decrease liquidity unwrapped", func(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() - userWugnotBalance := wugnot.BalanceOf(a2u(admin)) + userWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, userWugnotBalance, uint64(11999999)) - userUgnotBalance := ugnotBalanceOf(admin) + userUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, userUgnotBalance, uint64(10)) _, _, _, _, a0, a1, _ := DecreaseLiquidity( // tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath @@ -204,13 +204,13 @@ func testDecreaseLiquidityUnwrapped(t *testing.T) { true, // unwrapResult ) - userWugnotBalance = wugnot.BalanceOf(a2u(admin)) // unwrapped result, so wugnot didn't change + userWugnotBalance = wugnot.BalanceOf(admin) // unwrapped result, so wugnot didn't change uassert.Equal(t, userWugnotBalance, uint64(11999999)) - userUgnotBalance = ugnotBalanceOf(admin) // unwrapped result, so ugnot decreased + userUgnotBalance = ugnotBalanceOf(t, adminAddr) // unwrapped result, so ugnot decreased uassert.Equal(t, userUgnotBalance, uint64(24000009)) - newLiquidity := getPoolFromLpTokenId(uint64(1)).PoolGetLiquidity() + newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left diff --git a/position/tests/__TEST_position_native_mint_swap_burn_test.gnoA b/position/__TEST_position_native_mint_swap_burn_test.gnoA similarity index 84% rename from position/tests/__TEST_position_native_mint_swap_burn_test.gnoA rename to position/__TEST_position_native_mint_swap_burn_test.gnoA index 0d9c7c2fb..2461786d3 100644 --- a/position/tests/__TEST_position_native_mint_swap_burn_test.gnoA +++ b/position/__TEST_position_native_mint_swap_burn_test.gnoA @@ -45,18 +45,18 @@ func testMintPosition(t *testing.T) { wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // FOR WRAP - std.TestIssueCoins(admin, std.Coins{{"ugnot", 50000005}}) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(50000005)) + std.TestIssueCoins(adminAddr, std.Coins{{"ugnot", 50000005}}) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(50000005)) std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 200000000}}) - uassert.Equal(t, ugnotBalanceOf(consts.POSITION_ADDR), uint64(200000000)) + uassert.Equal(t, ugnotBalanceOf(t, consts.POSITION_ADDR), uint64(200000000)) banker := std.GetBanker(std.BankerTypeRealmIssue) - banker.SendCoins(admin, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) + banker.SendCoins(adminAddr, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) std.TestSetOrigSend(std.Coins{{"ugnot", 50000005}}, nil) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(0)) - adminOldWugnotBalance := wugnot.BalanceOf(a2u(admin)) + adminOldWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, adminOldWugnotBalance, uint64(0)) tokenId, liquidity, amount0, amount1 := Mint( @@ -70,8 +70,8 @@ func testMintPosition(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) @@ -94,8 +94,8 @@ func testMintPosition(t *testing.T) { uassert.Equal(t, position.burned, false) // SPEND ALL WUGNOT - uassert.Equal(t, wugnot.BalanceOf(a2u(admin)), uint64(0)) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(15168)) + uassert.Equal(t, wugnot.BalanceOf(admin), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(15168)) }) } @@ -125,11 +125,11 @@ func testSwap(t *testing.T) { consts.WUGNOT_PATH, consts.GNS_PATH, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") @@ -163,8 +163,8 @@ func testDecreaseWithNoUnwrap(t *testing.T) { t.Run("decrease with no unwrap", func(t *testing.T) { // no unwrap => receive with wugnot - oldWugnotBalance := wugnot.BalanceOf(a2u(admin)) - oldUgnotBalance := ugnotBalanceOf(admin) + oldWugnotBalance := wugnot.BalanceOf(admin) + oldUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, oldWugnotBalance, uint64(0)) uassert.Equal(t, oldUgnotBalance, uint64(15168)) @@ -178,8 +178,8 @@ func testDecreaseWithNoUnwrap(t *testing.T) { false, ) - newWugnotBalance := wugnot.BalanceOf(a2u(admin)) - newUgnotBalance := ugnotBalanceOf(admin) + newWugnotBalance := wugnot.BalanceOf(admin) + newUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, newWugnotBalance, uint64(5122489)) uassert.Equal(t, newUgnotBalance, uint64(15168)) // stays same, we didn't unwrap @@ -190,8 +190,8 @@ func testDecreaseWithUnwrap(t *testing.T) { t.Run("decrease with unwrap", func(t *testing.T) { // unwrap => receive with ugnot - oldWugnotBalance := wugnot.BalanceOf(a2u(admin)) - oldUgnotBalance := ugnotBalanceOf(admin) + oldWugnotBalance := wugnot.BalanceOf(admin) + oldUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, oldWugnotBalance, uint64(5122489)) uassert.Equal(t, oldUgnotBalance, uint64(15168)) @@ -205,8 +205,8 @@ func testDecreaseWithUnwrap(t *testing.T) { true, ) - newWugnotBalance := wugnot.BalanceOf(a2u(admin)) - newUgnotBalance := ugnotBalanceOf(admin) + newWugnotBalance := wugnot.BalanceOf(admin) + newUgnotBalance := ugnotBalanceOf(t, adminAddr) uassert.Equal(t, newWugnotBalance, uint64(5122489)) uassert.Equal(t, newUgnotBalance, uint64(4624858)) diff --git a/position/tests/__TEST_position_reposition_gnot_pair_test.gnoA b/position/__TEST_position_reposition_gnot_pair_test.gno similarity index 86% rename from position/tests/__TEST_position_reposition_gnot_pair_test.gnoA rename to position/__TEST_position_reposition_gnot_pair_test.gno index a0dc361e2..1dc217834 100644 --- a/position/tests/__TEST_position_reposition_gnot_pair_test.gnoA +++ b/position/__TEST_position_reposition_gnot_pair_test.gno @@ -45,18 +45,18 @@ func testMintPosition01InRange(t *testing.T) { wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // FOR WRAP - std.TestIssueCoins(admin, std.Coins{{"ugnot", 50000005}}) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(50000005)) + std.TestIssueCoins(adminAddr, std.Coins{{"ugnot", 50000005}}) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(50000005)) std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 200000000}}) - uassert.Equal(t, ugnotBalanceOf(consts.POSITION_ADDR), uint64(200000000)) + uassert.Equal(t, ugnotBalanceOf(t, consts.POSITION_ADDR), uint64(200000000)) banker := std.GetBanker(std.BankerTypeRealmIssue) - banker.SendCoins(admin, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) + banker.SendCoins(adminAddr, consts.POSITION_ADDR, std.Coins{{"ugnot", 50000005}}) std.TestSetOrigSend(std.Coins{{"ugnot", 50000005}}, nil) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(0)) - adminOldWugnotBalance := wugnot.BalanceOf(a2u(admin)) + adminOldWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, adminOldWugnotBalance, uint64(0)) tokenId, liquidity, amount0, amount1 := Mint( @@ -70,8 +70,8 @@ func testMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) @@ -94,8 +94,8 @@ func testMintPosition01InRange(t *testing.T) { uassert.Equal(t, position.burned, false) // SPEND ALL WUGNOT - uassert.Equal(t, wugnot.BalanceOf(a2u(admin)), uint64(0)) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(31605113)) + uassert.Equal(t, wugnot.BalanceOf(admin), uint64(0)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(31605113)) // 81605113 - 31605113 = 50000000 }) } @@ -110,11 +110,11 @@ func testSwap(t *testing.T) { consts.WUGNOT_PATH, consts.GNS_PATH, fee500, - admin, + adminAddr, false, "1234567", consts.MAX_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "-452903") @@ -161,21 +161,28 @@ func testDecreaseLiquidityInPosition(t *testing.T) { lpTokenId := uint64(1) - ownerOfPosition := gnft.OwnerOf(tid(lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) // approve fee0, fee1 to pool gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity(lpTokenId, 100, "0", "0", max_timeout, false) + tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity( + lpTokenId, + 100, + "0", + "0", + max_timeout, + false, + ) uassert.Equal(t, tokenId, lpTokenId) uassert.Equal(t, amount0, "17941988") uassert.Equal(t, amount1, "51233948") - ownerOfPosition = gnft.OwnerOf(tid(lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) position := MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") @@ -189,10 +196,6 @@ func testDecreaseLiquidityInPosition(t *testing.T) { uassert.Equal(t, position.tokensOwed0.ToString(), "0") uassert.Equal(t, position.tokensOwed1.ToString(), "0") uassert.Equal(t, position.burned, true) - - unclaimedFee0, unclaimedFee1 := unclaimedFee(lpTokenId) - uassert.Equal(t, unclaimedFee0.ToString(), "0") - uassert.Equal(t, unclaimedFee1.ToString(), "0") }) } @@ -217,12 +220,12 @@ func testReposition(t *testing.T) { uassert.Equal(t, position.burned, true) // user ugnot - std.TestIssueCoins(admin, std.Coins{{"ugnot", 50000005}}) - uassert.Equal(t, ugnotBalanceOf(admin), uint64(81605118)) + std.TestIssueCoins(adminAddr, std.Coins{{"ugnot", 50000005}}) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(81605118)) std.TestSetRealm(adminRealm) banker := std.GetBanker(std.BankerTypeRealmIssue) - banker.SendCoins(admin, consts.POSITION_ADDR, std.Coins{{"ugnot", 5000}}) + banker.SendCoins(adminAddr, consts.POSITION_ADDR, std.Coins{{"ugnot", 5000}}) std.TestSetOrigSend(std.Coins{{"ugnot", 5000}}, nil) std.TestSetRealm(adminRealm) @@ -237,7 +240,7 @@ func testReposition(t *testing.T) { ) // user ugnot - uassert.Equal(t, ugnotBalanceOf(admin), uint64(81600118)) + uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(81600118)) position = MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") diff --git a/position/tests/__TEST_position_reposition_grc20_pair_test.gnoA b/position/__TEST_position_reposition_grc20_pair_test.gnoA similarity index 92% rename from position/tests/__TEST_position_reposition_grc20_pair_test.gnoA rename to position/__TEST_position_reposition_grc20_pair_test.gnoA index 44eb7723b..812dcec2a 100644 --- a/position/tests/__TEST_position_reposition_grc20_pair_test.gnoA +++ b/position/__TEST_position_reposition_grc20_pair_test.gnoA @@ -39,8 +39,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -71,11 +71,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") @@ -111,8 +111,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -153,8 +153,8 @@ func TestDecreaseLiquidityInPosition(t *testing.T) { _lpTokenId := uint64(1) - ownerOfPosition := gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) // approve fee0, fee_lpTokenId to pool bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) @@ -166,8 +166,8 @@ func TestDecreaseLiquidityInPosition(t *testing.T) { uassert.Equal(t, amount0, "19628840") uassert.Equal(t, amount1, "46667220") - ownerOfPosition = gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) position := MustGetPosition(_lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") @@ -199,8 +199,8 @@ func TestMintPosition03InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(3)) @@ -223,10 +223,10 @@ func TestMintPosition03InRange(t *testing.T) { } func TestRepositionNotOwner(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(test1)) + std.TestSetRealm(std.NewUserRealm(addr02)) uassert.PanicsWithMessage( t, - `[GNOSWAP-POSITION-001] caller has no permission || only owner(g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d) can reposition for tokenId(1), but called from g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5`, + `[GNOSWAP-POSITION-001] caller has no permission || caller(g1v9jxgu3sxf047h6lta047h6lta047h6l8tv5at) is not owner(g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d) for tokenId(1)`, func() { Reposition(uint64(1), -1000, 1000, "500", "500", "0", "0") }) @@ -246,7 +246,7 @@ func TestRepositionSlippageTooLarge(t *testing.T) { std.TestSetRealm(adminRealm) uassert.PanicsWithMessage( t, - `[GNOSWAP-POSITION-002] slippage failed || LM_Price Slippage Check(amount0(0) >= params.amount0Min(100000000000), amount1(500) >= params.amount1Min(100000000000))`, + `[GNOSWAP-POSITION-002] slippage failed || Price Slippage Check(amount0(0) >= amount0Min(100000000000), amount1(500) >= amount1Min(100000000000))`, func() { Reposition(uint64(1), -1000, 1000, "500", "500", "100000000000", "100000000000") }) @@ -288,7 +288,7 @@ func TestReposition(t *testing.T) { uassert.Equal(t, position.tickLower, int32(-1000)) uassert.Equal(t, position.tickUpper, int32(1000)) uassert.Equal(t, position.liquidity.ToString(), "4998") - uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), "0") + uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), "659841872392960215058365142934185") uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), "0") uassert.Equal(t, position.tokensOwed0.ToString(), "0") uassert.Equal(t, position.tokensOwed1.ToString(), "0") diff --git a/position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA b/position/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA similarity index 96% rename from position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA rename to position/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA index eb14c5f72..2dae15a3c 100644 --- a/position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA +++ b/position/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA @@ -39,8 +39,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -78,8 +78,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -117,8 +117,8 @@ func TestMintPosition03InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(3)) @@ -149,11 +149,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") @@ -199,8 +199,8 @@ func TestDecreaseLiquidity03(t *testing.T) { _lpTokenId := uint64(03) - ownerOfPosition := gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) // approve fee0, fee1 to pool ( for withdrawal protocol fee ) bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) @@ -215,8 +215,8 @@ func TestDecreaseLiquidity03(t *testing.T) { uassert.Equal(t, fee0, "127") uassert.Equal(t, fee1, "0") - ownerOfPosition = gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) position := MustGetPosition(_lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") @@ -277,9 +277,6 @@ func TestReposition(t *testing.T) { func TestAfterReposition03UnclaimedFee(t *testing.T) { amount0, amount1 := unclaimedFee(3) - println("AFTER REPOSITION, POSITION 3 UNCLAIMED FEE") - println("amount0: ", amount0.ToString()) - println("amount1: ", amount1.ToString()) uassert.Equal(t, amount0.ToString(), "0") uassert.Equal(t, amount1.ToString(), "0") @@ -294,11 +291,11 @@ func TestSwap2(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") diff --git a/position/tests/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA b/position/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA similarity index 98% rename from position/tests/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA rename to position/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA index ba58c6ee6..4c34ea6d6 100644 --- a/position/tests/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA +++ b/position/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA @@ -38,8 +38,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -77,8 +77,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -109,11 +109,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") diff --git a/position/tests/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA b/position/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA similarity index 98% rename from position/tests/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA rename to position/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA index 27b864fc6..269e80e18 100644 --- a/position/tests/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA +++ b/position/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA @@ -38,8 +38,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -77,8 +77,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -109,11 +109,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") diff --git a/position/tests/__TEST_position_test_two_position_used_single_swap_test.gnoA b/position/__TEST_position_test_two_position_used_single_swap_test.gnoA similarity index 97% rename from position/tests/__TEST_position_test_two_position_used_single_swap_test.gnoA rename to position/__TEST_position_test_two_position_used_single_swap_test.gnoA index 1d7047539..cc5300952 100644 --- a/position/tests/__TEST_position_test_two_position_used_single_swap_test.gnoA +++ b/position/__TEST_position_test_two_position_used_single_swap_test.gnoA @@ -38,8 +38,8 @@ func TestMintPosition01WideInRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -65,8 +65,8 @@ func TestMintPositionTightInRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -105,11 +105,11 @@ func TestSwap(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) } diff --git a/position/tests/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA b/position/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA similarity index 84% rename from position/tests/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA rename to position/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA index e0edf9179..c60deadb2 100644 --- a/position/tests/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA +++ b/position/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA @@ -40,8 +40,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(1) @@ -73,11 +73,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) std.TestSkipHeights(1) @@ -120,8 +120,8 @@ func TestMintPosition02InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(1) @@ -152,11 +152,11 @@ func TestSwap2(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) std.TestSkipHeights(1) @@ -186,11 +186,11 @@ func TestSwap3(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) std.TestSkipHeights(1) @@ -234,8 +234,8 @@ func TestIncreaseLiquidity02(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - pool := getPoolFromLpTokenId(uint64(2)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t, uint64(2)) + oldLiquidity := pool.Liquidity() _, _, m0, m1, _ := IncreaseLiquidity( uint64(2), // tokenId @@ -250,7 +250,7 @@ func TestIncreaseLiquidity02(t *testing.T) { uassert.Equal(t, m0, "984790") uassert.Equal(t, m1, "10000000") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) } @@ -258,48 +258,41 @@ func TestIncreaseLiquidity02(t *testing.T) { func TestDecreaseLiquidityPosition02(t *testing.T) { std.TestSetRealm(adminRealm) - _lpTokenId := uint64(2) + lpTokenId := uint64(2) - ownerOfPosition := gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) - unclaimedFee0, unclaimedFee1 := unclaimedFee(_lpTokenId) + unclaimedFee0, unclaimedFee1 := unclaimedFee(lpTokenId) uassert.Equal(t, unclaimedFee0.ToString(), "0") uassert.Equal(t, unclaimedFee1.ToString(), "0") - // approve fee0, fee_lpTokenId to pool + // approve fee0, fee1, lpTokenId to pool bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity( - _lpTokenId, + lpTokenId, 100, "0", "0", max_timeout, false, ) - uassert.Equal(t, tokenId, _lpTokenId) + uassert.Equal(t, tokenId, lpTokenId) uassert.Equal(t, amount0, "5459371") uassert.Equal(t, amount1, "55436931") - ownerOfPosition = gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) - unclaimedFee0, unclaimedFee1 = unclaimedFee(tokenId) - uassert.Equal(t, unclaimedFee0.ToString(), "0") - uassert.Equal(t, unclaimedFee1.ToString(), "0") + defer func() { + if r := recover(); r != nil { - position := MustGetPosition(_lpTokenId) - uassert.Equal(t, position.nonce.ToString(), "0") - uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) - uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") - uassert.Equal(t, position.tickLower, int32(9000)) - uassert.Equal(t, position.tickUpper, int32(10000)) - uassert.Equal(t, position.liquidity.ToString(), "0") - uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), "406939137189886314720592672194986") - uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), "0") - uassert.Equal(t, position.tokensOwed0.ToString(), "0") - uassert.Equal(t, position.tokensOwed1.ToString(), "0") - uassert.Equal(t, position.burned, true) + if r != `[GNOSWAP-POOL-008] requested data not found || tick(10000) does not exist` { + panic("unexpected panic") + } + } + }() + unclaimedFee(tokenId) } diff --git a/position/tests/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA b/position/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA similarity index 92% rename from position/tests/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA rename to position/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA index ad3f7d395..306fce987 100644 --- a/position/tests/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA +++ b/position/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA @@ -42,8 +42,8 @@ func TestMintPosition01(t *testing.T) { "1", "1", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(10) @@ -119,8 +119,8 @@ func TestMintPosition02(t *testing.T) { "8412783", "4967538", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(10) @@ -159,8 +159,8 @@ func TestMintPosition03(t *testing.T) { "39800000", "23500902", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(10) @@ -222,8 +222,8 @@ func TestMintPosition04(t *testing.T) { "5073191", "2867352", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) std.TestSkipHeights(10) @@ -275,8 +275,8 @@ func TestIncreaseLiquidity02(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - pool := getPoolFromLpTokenId(uint64(2)) - oldLiquidity := pool.PoolGetLiquidity() + pool := getPoolFromLpTokenId(t, uint64(2)) + oldLiquidity := pool.Liquidity() _, _, m0, m1, _ := IncreaseLiquidity( uint64(2), // tokenId @@ -291,7 +291,7 @@ func TestIncreaseLiquidity02(t *testing.T) { uassert.Equal(t, m0, "4162118") uassert.Equal(t, m1, "2000000") - newLiquidity := pool.PoolGetLiquidity() + newLiquidity := pool.Liquidity() uassert.Equal(t, newLiquidity.Gt(oldLiquidity), true) } @@ -299,37 +299,37 @@ func TestIncreaseLiquidity02(t *testing.T) { func TestDecreaseLiquidityPosition02(t *testing.T) { std.TestSetRealm(adminRealm) - _lpTokenId := uint64(2) + lpTokenId := uint64(2) - ownerOfPosition := gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) - // approve fee0, fee_lpTokenId to pool + // approve fee0, feelpTokenId to pool bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity( - _lpTokenId, + lpTokenId, 31, "2091922", "1005220", max_timeout, false, ) - uassert.Equal(t, tokenId, _lpTokenId) + uassert.Equal(t, tokenId, lpTokenId) uassert.Equal(t, fee0, "2619") uassert.Equal(t, fee1, "0") uassert.Equal(t, amount0, "4183844") uassert.Equal(t, amount1, "2010439") - ownerOfPosition = gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) unclaimedFee0, unclaimedFee1 := unclaimedFee(tokenId) uassert.Equal(t, unclaimedFee0.ToString(), "0") uassert.Equal(t, unclaimedFee1.ToString(), "0") - position := MustGetPosition(_lpTokenId) + position := MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000") @@ -346,37 +346,37 @@ func TestDecreaseLiquidityPosition02(t *testing.T) { func TestDecreaseLiquidityPosition02All(t *testing.T) { std.TestSetRealm(adminRealm) - _lpTokenId := uint64(2) + lpTokenId := uint64(2) - ownerOfPosition := gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) - // approve fee0, fee_lpTokenId to pool + // approve fee0, feelpTokenId to pool bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity( - _lpTokenId, + lpTokenId, 100, "0", "0", max_timeout, false, ) - uassert.Equal(t, tokenId, _lpTokenId) + uassert.Equal(t, tokenId, lpTokenId) uassert.Equal(t, fee0, "0") uassert.Equal(t, fee1, "0") uassert.Equal(t, amount0, "9312428") uassert.Equal(t, amount1, "4474850") - ownerOfPosition = gnft.OwnerOf(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(lpTokenId)) + uassert.Equal(t, ownerOfPosition, adminAddr) unclaimedFee0, unclaimedFee1 := unclaimedFee(tokenId) uassert.Equal(t, unclaimedFee0.ToString(), "0") uassert.Equal(t, unclaimedFee1.ToString(), "0") - position := MustGetPosition(_lpTokenId) + position := MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000") diff --git a/position/tests/__TEST_position_unclaimed_fee_test.gnoA b/position/__TEST_position_unclaimed_fee_test.gnoA similarity index 93% rename from position/tests/__TEST_position_unclaimed_fee_test.gnoA rename to position/__TEST_position_unclaimed_fee_test.gnoA index bdee97195..a3f1634ac 100644 --- a/position/tests/__TEST_position_unclaimed_fee_test.gnoA +++ b/position/__TEST_position_unclaimed_fee_test.gnoA @@ -42,8 +42,8 @@ func TestMintPosition01InRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -68,8 +68,8 @@ func TestMintPosition02LowerRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(2)) @@ -94,8 +94,8 @@ func TestMintPosition03UpperRange(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(3)) @@ -130,11 +130,11 @@ func TestSwap1(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "1234567", consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "1234567") @@ -157,11 +157,11 @@ func TestSwap2(t *testing.T) { barPath, fooPath, fee500, - admin, + adminAddr, true, "20000000", // consts.MIN_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "20000000") @@ -184,11 +184,11 @@ func TestSwap3(t *testing.T) { fooPath, barPath, fee500, - admin, + adminAddr, false, "20000000", // consts.MAX_PRICE, - admin, + adminAddr, ) uassert.Equal(t, amount0, "-8692001") @@ -218,8 +218,8 @@ func TestCollectFeeAfterSwap(t *testing.T) { func TestDecreaseLiquidityUpperPosition(t *testing.T) { std.TestSetRealm(adminRealm) - ownerOfPosition := gnft.OwnerOf(tid(3)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(3)) + uassert.Equal(t, ownerOfPosition, adminAddr) tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity(uint64(3), 100, "0", "0", max_timeout, false) @@ -227,8 +227,8 @@ func TestDecreaseLiquidityUpperPosition(t *testing.T) { uassert.Equal(t, amount0, "49999999") uassert.Equal(t, amount1, "0") - ownerOfPosition = gnft.OwnerOf(tid(3)) - uassert.Equal(t, ownerOfPosition, admin) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(3)) + uassert.Equal(t, ownerOfPosition, adminAddr) } func TestSubIn256(t *testing.T) { diff --git a/position/_helper_test.gno b/position/_helper_test.gno index 41c4c458f..fdcaf2828 100644 --- a/position/_helper_test.gno +++ b/position/_helper_test.gno @@ -24,6 +24,7 @@ import ( "gno.land/r/onbloc/qux" "gno.land/r/onbloc/usdc" + rr "gno.land/r/gnoswap/v1/router" sr "gno.land/r/gnoswap/v1/staker" ) @@ -162,8 +163,20 @@ func (QuxToken) Approve() func(spender pusers.AddressOrName, amount uint64) { return qux.Approve } +func init() { + std.TestSetRealm(std.NewUserRealm("g1er355fkjksqpdtwmhf5penwa82p0rhqxkkyhk5")) + rr.RegisterGRC20Interface(wugnotPath, WugnotToken{}) + rr.RegisterGRC20Interface(gnsPath, GNSToken{}) + rr.RegisterGRC20Interface(barPath, BarToken{}) + rr.RegisterGRC20Interface(bazPath, BazToken{}) + rr.RegisterGRC20Interface(fooPath, FooToken{}) + rr.RegisterGRC20Interface(oblPath, OBLToken{}) + rr.RegisterGRC20Interface(quxPath, QuxToken{}) +} + var ( - admin = pusers.AddressOrName(consts.ADMIN) + adminAddr = std.Address(consts.ADMIN) + admin = pusers.AddressOrName(adminAddr) alice = pusers.AddressOrName(testutils.TestAddress("alice")) bob = pusers.AddressOrName(testutils.TestAddress("bob")) pool = pusers.AddressOrName(consts.POOL_ADDR) @@ -171,6 +184,7 @@ var ( router = pusers.AddressOrName(consts.ROUTER_ADDR) adminRealm = std.NewUserRealm(users.Resolve(admin)) posRealm = std.NewCodeRealm(consts.POSITION_PATH) + rouRealm = std.NewCodeRealm(consts.ROUTER_PATH) // addresses used in tests addrUsedInTest = []std.Address{addr01, addr02} @@ -552,6 +566,13 @@ func LPTokenUnStake(t *testing.T, owner pusers.AddressOrName, tokenId uint64, un sr.UnstakeToken(tokenId, unwrap) } +func getPoolFromLpTokenId(t *testing.T, lpTokenId uint64) *pl.Pool { + t.Helper() + + position := MustGetPosition(lpTokenId) + return pl.GetPoolFromPoolPath(position.poolKey) +} + func wugnotApprove(t *testing.T, owner, spender pusers.AddressOrName, amount uint64) { t.Helper() std.TestSetRealm(std.NewUserRealm(users.Resolve(owner))) @@ -757,6 +778,7 @@ func burnAllNFT(t *testing.T) { } func TestBeforeResetPositionObject(t *testing.T) { + t.Skip("only available for single file(current file) test") // make actual data to test resetting not only position's state but also pool's state std.TestSetRealm(adminRealm) @@ -772,6 +794,7 @@ func TestBeforeResetPositionObject(t *testing.T) { } func TestResetObject(t *testing.T) { + t.Skip("only available for single file(current file) test") resetObject(t) uassert.Equal(t, positions.Size(), 0, "positions should be empty") @@ -779,6 +802,7 @@ func TestResetObject(t *testing.T) { } func TestBurnTokens(t *testing.T) { + t.Skip("only available for single file(current file) test") burnTokens(t) uassert.Equal(t, foo.BalanceOf(a2u(addr01)), uint64(0)) // 100_000_000 -> 0 @@ -786,6 +810,7 @@ func TestBurnTokens(t *testing.T) { } func TestBurnAllNFT(t *testing.T) { + t.Skip("only available for single file(current file) test") burnAllNFT(t) uassert.Equal(t, gnft.TotalSupply(), uint64(0), "gnft total supply should be 0") } diff --git a/position/liquidity_management.gno b/position/liquidity_management.gno index 006c1c8db..4d5eb5155 100644 --- a/position/liquidity_management.gno +++ b/position/liquidity_management.gno @@ -75,7 +75,7 @@ type AddLiquidityParams struct { func addLiquidity(params AddLiquidityParams) (*u256.Uint, *u256.Uint, *u256.Uint) { pool := pl.GetPoolFromPoolPath(params.poolKey) - sqrtPriceX96 := pool.Slot0SqrtPriceX96().Clone() + sqrtPriceX96 := new(u256.Uint).Set(pool.Slot0SqrtPriceX96()) sqrtRatioAX96 := common.TickMathGetSqrtRatioAtTick(params.tickLower) sqrtRatioBX96 := common.TickMathGetSqrtRatioAtTick(params.tickUpper) diff --git a/position/liquidity_management_test.gno b/position/liquidity_management_test.gnoA similarity index 100% rename from position/liquidity_management_test.gno rename to position/liquidity_management_test.gnoA diff --git a/position/native_token.gno b/position/native_token.gno index 392bc0ab6..b4ca707de 100644 --- a/position/native_token.gno +++ b/position/native_token.gno @@ -140,7 +140,7 @@ func safeWrapNativeToken(amountDesired string, userAddress std.Address) uint64 { if sentUgnotAmount > amount { exceed := sentUgnotAmount - amount refundUGNOT(userAddress, exceed) - transferUGNOT(consts.POSITION_ADDR, userAddress, amount) + sentUgnotAmount = amount } diff --git a/position/native_token_test.gno b/position/native_token_test.gnoA similarity index 100% rename from position/native_token_test.gno rename to position/native_token_test.gnoA diff --git a/position/position.gno b/position/position.gno index a913d77d5..314eccd87 100644 --- a/position/position.gno +++ b/position/position.gno @@ -2,12 +2,13 @@ package position import ( "encoding/base64" + "std" + "strconv" + "gno.land/p/demo/avl" "gno.land/p/demo/ufmt" "gno.land/r/demo/wugnot" "gno.land/r/gnoswap/v1/gnft" - "std" - "strconv" u256 "gno.land/p/gnoswap/uint256" @@ -334,10 +335,10 @@ func processMintInput(input MintInput) (ProcessedMintInput, error) { result = ProcessedMintInput{ tokenPair: pair, - amount0Desired: amount0Desired.Clone(), - amount1Desired: amount1Desired.Clone(), - amount0Min: amount0Min.Clone(), - amount1Min: amount1Min.Clone(), + amount0Desired: new(u256.Uint).Set(amount0Desired), + amount1Desired: new(u256.Uint).Set(amount1Desired), + amount0Min: new(u256.Uint).Set(amount0Min), + amount1Min: new(u256.Uint).Set(amount1Min), tickLower: tickLower, tickUpper: tickUpper, poolPath: poolPath, @@ -526,8 +527,6 @@ func mint(params MintParams) (uint64, *u256.Uint, *u256.Uint, *u256.Uint) { pool := pl.GetPoolFromPoolPath(poolKey) positionKey := computePositionKey(GetOrigPkgAddr(), params.tickLower, params.tickUpper) - feeGrowthInside0LastX128 := pool.PositionFeeGrowthInside0LastX128(positionKey).Clone() - feeGrowthInside1LastX128 := pool.PositionFeeGrowthInside1LastX128(positionKey).Clone() position := Position{ nonce: u256.Zero(), @@ -536,8 +535,8 @@ func mint(params MintParams) (uint64, *u256.Uint, *u256.Uint, *u256.Uint) { tickLower: params.tickLower, tickUpper: params.tickUpper, liquidity: liquidity, - feeGrowthInside0LastX128: feeGrowthInside0LastX128, - feeGrowthInside1LastX128: feeGrowthInside1LastX128, + feeGrowthInside0LastX128: new(u256.Uint).Set(pool.PositionFeeGrowthInside0LastX128(positionKey)), + feeGrowthInside1LastX128: new(u256.Uint).Set(pool.PositionFeeGrowthInside1LastX128(positionKey)), tokensOwed0: u256.Zero(), tokensOwed1: u256.Zero(), burned: false, @@ -671,8 +670,8 @@ func calculatePositionFeeUpdate( return PositionFeeUpdate{ tokensOwed0: new(u256.Uint).Add(position.tokensOwed0, tokensOwed0), tokensOwed1: new(u256.Uint).Add(position.tokensOwed1, tokensOwed1), - feeGrowthInside0LastX128: currentFeeGrowth.feeGrowthInside0LastX128.Clone(), - feeGrowthInside1LastX128: currentFeeGrowth.feeGrowthInside1LastX128.Clone(), + feeGrowthInside0LastX128: new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside0LastX128), + feeGrowthInside1LastX128: new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside1LastX128), } } @@ -714,26 +713,26 @@ func increaseLiquidity(params IncreaseLiquidityParams) (uint64, *u256.Uint, *u25 pool := pl.GetPoolFromPoolPath(position.poolKey) positionKey := computePositionKey(GetOrigPkgAddr(), position.tickLower, position.tickUpper) - feeGrowthInside0LastX128 := pool.PositionFeeGrowthInside0LastX128(positionKey).Clone() - feeGrowthInside1LastX128 := pool.PositionFeeGrowthInside1LastX128(positionKey).Clone() + feeGrowthInside0LastX128 := new(u256.Uint).Set(pool.PositionFeeGrowthInside0LastX128(positionKey)) + feeGrowthInside1LastX128 := new(u256.Uint).Set(pool.PositionFeeGrowthInside1LastX128(positionKey)) { diff := new(u256.Uint).Sub(feeGrowthInside0LastX128, position.feeGrowthInside0LastX128) - mulDiv := u256.MulDiv(diff, position.liquidity.Clone(), u256.MustFromDecimal(consts.Q128)) + mulDiv := u256.MulDiv(diff, new(u256.Uint).Set(position.liquidity), u256.MustFromDecimal(consts.Q128)) position.tokensOwed0 = new(u256.Uint).Add(position.tokensOwed0, mulDiv) } { diff := new(u256.Uint).Sub(feeGrowthInside1LastX128, position.feeGrowthInside1LastX128) - mulDiv := u256.MulDiv(diff, position.liquidity.Clone(), u256.MustFromDecimal(consts.Q128)) + mulDiv := u256.MulDiv(diff, new(u256.Uint).Set(position.liquidity), u256.MustFromDecimal(consts.Q128)) position.tokensOwed1 = new(u256.Uint).Add(position.tokensOwed1, mulDiv) } position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128 position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128 - position.liquidity = new(u256.Uint).Add(position.liquidity.Clone(), liquidity) + position.liquidity = new(u256.Uint).Add(new(u256.Uint).Set(position.liquidity), liquidity) position.burned = false updated := setPosition(params.tokenId, position) @@ -751,8 +750,6 @@ func increaseLiquidity(params IncreaseLiquidityParams) (uint64, *u256.Uint, *u25 // It also handles the conversion between GNOT and WUGNOT transparently for the user. // Returns tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath // ref: https://docs.gnoswap.io/contracts/position/position.gno#decreaseliquidity -// TODO: -// 1. liquidityRatio가 맞는지 검토 func DecreaseLiquidity( tokenId uint64, liquidityRatio uint64, @@ -839,8 +836,8 @@ func decreaseLiquidity(params DecreaseLiquidityParams) (uint64, *u256.Uint, *u25 positionKey := computePositionKey(GetOrigPkgAddr(), position.tickLower, position.tickUpper) pool := pl.GetPoolFromPoolPath(position.poolKey) - feeGrowthInside0LastX128 := pool.PositionFeeGrowthInside0LastX128(positionKey).Clone() - feeGrowthInside1LastX128 := pool.PositionFeeGrowthInside1LastX128(positionKey).Clone() + feeGrowthInside0LastX128 := new(u256.Uint).Set(pool.PositionFeeGrowthInside0LastX128(positionKey)) + feeGrowthInside1LastX128 := new(u256.Uint).Set(pool.PositionFeeGrowthInside1LastX128(positionKey)) position.tokensOwed0 = updateTokensOwed( feeGrowthInside0LastX128, @@ -931,7 +928,6 @@ func CollectFee(tokenId uint64, unwrapResult bool) (uint64, string, string, stri ZERO_LIQUIDITY_FOR_FEE_COLLECTION, // burn '0' liquidity to collect fee ) - ////////////// currentFeeGrowth, err := getCurrentFeeGrowth(position, token0, token1, fee) if err != nil { panic(newErrorWithDetail(err, "failed to get current fee growth")) @@ -939,8 +935,8 @@ func CollectFee(tokenId uint64, unwrapResult bool) (uint64, string, string, stri tokensOwed0, tokensOwed1 := calculateFees(position, currentFeeGrowth) - position.feeGrowthInside0LastX128 = currentFeeGrowth.feeGrowthInside0LastX128 - position.feeGrowthInside1LastX128 = currentFeeGrowth.feeGrowthInside1LastX128 + position.feeGrowthInside0LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside0LastX128) + position.feeGrowthInside1LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside1LastX128) // check user wugnot amount // need this value to unwrap fee @@ -962,7 +958,15 @@ func CollectFee(tokenId uint64, unwrapResult bool) (uint64, string, string, stri mustUpdatePosition(tokenId, position) // handle withdrawal fee - withoutFee0, withoutFee1 := pl.HandleWithdrawalFee(tokenId, token0, amount0, token1, amount1, position.poolKey, std.PrevRealm().Addr()) + withoutFee0, withoutFee1 := pl.HandleWithdrawalFee( + tokenId, + token0, + amount0, + token1, + amount1, + position.poolKey, + std.PrevRealm().Addr(), + ) // UNWRAP pToken0, pToken1, _ := splitOf(position.poolKey) @@ -998,8 +1002,8 @@ func calculateFees(position Position, currentFeeGrowth FeeGrowthInside) (*u256.U position.liquidity, ) - tokensOwed0 := new(u256.Uint).Add(position.tokensOwed0.Clone(), fee0) - tokensOwed1 := new(u256.Uint).Add(position.tokensOwed1.Clone(), fee1) + tokensOwed0 := new(u256.Uint).Add(new(u256.Uint).Set(position.tokensOwed0), fee0) + tokensOwed1 := new(u256.Uint).Add(new(u256.Uint).Set(position.tokensOwed1), fee1) return tokensOwed0, tokensOwed1 } @@ -1008,8 +1012,8 @@ func getCurrentFeeGrowth(postion Position, token0, token1 string, fee uint32) (F pool := pl.GetPoolFromPoolPath(postion.poolKey) positionKey := computePositionKey(GetOrigPkgAddr(), postion.tickLower, postion.tickUpper) - feeGrowthInside0 := pool.PositionFeeGrowthInside0LastX128(positionKey).Clone() - feeGrowthInside1 := pool.PositionFeeGrowthInside1LastX128(positionKey).Clone() + feeGrowthInside0 := new(u256.Uint).Set(pool.PositionFeeGrowthInside0LastX128(positionKey)) + feeGrowthInside1 := new(u256.Uint).Set(pool.PositionFeeGrowthInside1LastX128(positionKey)) feeGrowthInside := FeeGrowthInside{ feeGrowthInside0LastX128: feeGrowthInside0, @@ -1055,7 +1059,7 @@ func Reposition( liquidity, amount0, amount1 := addLiquidity( AddLiquidityParams{ - poolKey: position.poolKey, + poolKey: position.poolKey, // TOOD: FIX: 신규 틱 범위로 생성핵서 필요해야 함 tickLower: tickLower, tickUpper: tickUpper, amount0Desired: u256.MustFromDecimal(amount0DesiredStr), @@ -1066,14 +1070,18 @@ func Reposition( }, ) + // update position tickLower, tickUpper to new value + // because getCurrentFeeGrowth() uses tickLower, tickUpper + position.tickLower = tickLower + position.tickUpper = tickUpper + currentFeeGrowth, err := getCurrentFeeGrowth(position, token0, token1, fee) if err != nil { panic(newErrorWithDetail(err, "failed to get current fee growth")) } position.feeGrowthInside0LastX128 = currentFeeGrowth.feeGrowthInside0LastX128 position.feeGrowthInside1LastX128 = currentFeeGrowth.feeGrowthInside1LastX128 - position.tickLower = tickLower - position.tickUpper = tickUpper + position.liquidity = liquidity // OBS: do not reset feeGrowthInside1LastX128 and feeGrowthInside1LastX128 to zero // if so, ( decrease 100% -> reposition ) @@ -1081,11 +1089,27 @@ func Reposition( position.tokensOwed0 = u256.Zero() position.tokensOwed1 = u256.Zero() position.burned = false - mustUpdatePosition(tokenId, position) - poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(position.poolKey) + // // WIP + // pl.Burn( + // token0, + // token1, + // fee, + // tickLower, + // tickUpper, + // ZERO_LIQUIDITY_FOR_FEE_COLLECTION, + // ) + // currentFeeGrowth, err = getCurrentFeeGrowth(position, token0, token1, fee) + // if err != nil { + // panic(newErrorWithDetail(err, "failed to get current fee growth")) + // } + // tokensOwed0, tokensOwed1 := calculateFees(position, currentFeeGrowth) + // position.feeGrowthInside0LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside0LastX128) + // position.feeGrowthInside1LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside1LastX128) + // mustUpdatePosition(tokenId, position) + poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(position.poolKey) prevAddr, prevPkgPath := getPrevAsString() std.Emit( diff --git a/position/position_test.gno b/position/position_test.gnoA similarity index 100% rename from position/position_test.gno rename to position/position_test.gnoA diff --git a/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA b/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA index a3732dab5..871bf5b3a 100644 --- a/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA +++ b/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA @@ -52,7 +52,7 @@ func ugnotBalanceOf(addr std.Address) uint64 { } func isOwner(t *testing.T, tokenId uint64, addr std.Address) bool { - owner := gnft.OwnerOf(tid(tokenId)) + owner := gnft.OwnerOf(tokenIdFrom(tokenId)) if owner == addr { return true diff --git a/position/tests/__TEST_fee_collect_with_two_user_test.gnoA b/position/tests/__TEST_fee_collect_with_two_user_test.gnoA deleted file mode 100644 index 51906879e..000000000 --- a/position/tests/__TEST_fee_collect_with_two_user_test.gnoA +++ /dev/null @@ -1,156 +0,0 @@ -package position - -import ( - "std" - "testing" - "time" - - "gno.land/p/demo/testutils" - "gno.land/p/demo/uassert" - - "gno.land/r/gnoswap/v1/common" - "gno.land/r/gnoswap/v1/consts" - - "gno.land/r/gnoswap/v1/gns" - "gno.land/r/onbloc/bar" - "gno.land/r/onbloc/baz" - - pl "gno.land/r/gnoswap/v1/pool" - pn "gno.land/r/gnoswap/v1/position" - pr "gno.land/r/gnoswap/v1/router" -) - -var ( - user1Adderss = testutils.TestAddress("user1") - user1Realm = std.NewUserRealm(user1Adderss) - user2Adderss = testutils.TestAddress("user2") - user2Realm = std.NewUserRealm(user2Adderss) - tickSpacing = int32(60) - minTick = (consts.MIN_TICK / tickSpacing) * tickSpacing - maxTick = (consts.MAX_TICK / tickSpacing) * tickSpacing - - poolCreationFee = uint64(100_000_000) -) - -/* -This test demonstrates a issue(Gnoswap-19) fee collection mechanism. The key steps are: - -· Create a pool and add liquidity from two different users -· Perform swaps to generate fees in the pool -· Burn 0 liquidity to update fees -· Collect fees for both users -· Compare the collected fees between the two users -*/ -func TestCollectFeeWithTwoUser(t *testing.T) { - std.TestSetRealm(adminRealm) - common.SetLimitCaller(true) - gns.Approve(a2u(consts.POOL_ADDR), poolCreationFee) - - pl.CreatePool(barPath, bazPath, 3000, "25054144837504793118641380156") // encodePriceSqrt(1, 10) - poolPath := "gno.land/r/onbloc/bar:gno.land/r/onbloc/baz:3000" - - // initial balance for user1 & user2 - bar.Transfer(a2u(user1Adderss), 100_000_000) - baz.Transfer(a2u(user1Adderss), 100_000_000) - bar.Transfer(a2u(user2Adderss), 100_000_000) - baz.Transfer(a2u(user2Adderss), 100_000_000) - - t.Run("mint and swap fee should be distributed to user's liquidity", func(t *testing.T) { - std.TestSetRealm(user1Realm) - bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - bar.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) - - tokenId_res1, liquidity_res1, amount0_res1, amount1_res1 := pn.Mint( - barPath, // token0 string, - bazPath, // token1 string, - 3000, // fee uint32, - minTick, // tickLower int32, - maxTick, // tickUpper int32, - "10000000", // _amount0Desired string, // *u256.Uint // 100e18 - "10000000", // _amount1Desired string, // *u256.Uint // 100e18 - "0", // _amount0Min string, // *u256.Uint - "0", // _amount1Min string, // *u256.Uint - time.Now().Unix()+1000, // deadline int64, - user1Adderss, // mintTo string - admin, - ) - - std.TestSetRealm(user2Realm) - bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - bar.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.ROUTER_ADDR), consts.UINT64_MAX) - - tokenId_res2, liquidity_res2, amount0_res2, amount1_res2 := pn.Mint( - barPath, // token0 string, - bazPath, // token1 string, - 3000, // fee uint32, - minTick, // tickLower int32, - maxTick, // tickUpper int32, - "10000000", // _amount0Desired string, // *u256.Uint // 100e18 - "10000000", // _amount1Desired string, // *u256.Uint // 100e18 - "0", // _amount0Min string, // *u256.Uint - "0", // _amount1Min string, // *u256.Uint - time.Now().Unix()+1000, // deadline int64, - user2Adderss, // mintTo string - admin, - ) - - // ====== Swap to accrue fees ====== - pr.SwapRoute( - barPath, //inputToken string, - bazPath, //outputToken string, - "10000000", //_amountSpecified string, // int256 - "EXACT_IN", //swapType string, - barPath+":"+bazPath+":3000", //strRouteArr string, // []string - "100", //quoteArr string, // []int - "0", //_tokenAmountLimit string, // uint256 - ) - - pr.SwapRoute( - bazPath, //inputToken string, - barPath, //outputToken string, - "10000000", //_amountSpecified string, // int256 - "EXACT_IN", //swapType string, - bazPath+":"+barPath+":3000", //strRouteArr string, // []string - "100", //quoteArr string, // []int - "0", //_tokenAmountLimit string, // uint256 - ) - - // ====== Burn 0 to update fee ====== - std.TestSetRealm(posRealm) - pl.Burn( - barPath, // token0Path string, - bazPath, // token1Path string, - uint32(3000), // fee uint32, - minTick, // tickLower int32, - maxTick, // tickUpper int32, - "0", // _liquidityAmount string, // uint128 - ) - - // ====== Collect fees and compare ====== - // user1 - std.TestSetRealm(user1Realm) - bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - userBarBalanceBeforeCollect_1 := bar.BalanceOf(a2u(user1Adderss)) - userBazBalanceBeforeCollect_1 := baz.BalanceOf(a2u(user1Adderss)) - tokenId_res3, withoutFee0_res3, withoutFee1_res3, positionPoolKey_res3, _, _ := pn.CollectFee(tokenId_res1, false) - userBarBalanceAfterCollect_1 := bar.BalanceOf(a2u(user1Adderss)) - userBazBalanceAfterCollect_1 := baz.BalanceOf(a2u(user1Adderss)) - - // user2 - std.TestSetRealm(user2Realm) - bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - baz.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - userBarBalanceBeforeCollect_2 := bar.BalanceOf(a2u(user2Adderss)) - userBazBalanceBeforeCollect_2 := baz.BalanceOf(a2u(user2Adderss)) - tokenId_res4, withoutFee0_res4, withoutFee1_res4, positionPoolKey_res4, _, _ := pn.CollectFee(tokenId_res2, false) - userBarBalanceAfterCollect_2 := bar.BalanceOf(a2u(user2Adderss)) - userBazBalanceAfterCollect_2 := baz.BalanceOf(a2u(user2Adderss)) - uassert.Equal(t, (userBarBalanceAfterCollect_1-userBarBalanceBeforeCollect_1)-(userBarBalanceAfterCollect_2-userBarBalanceBeforeCollect_2), uint64(0)) - uassert.Equal(t, (userBazBalanceAfterCollect_1-userBazBalanceBeforeCollect_1)-(userBazBalanceAfterCollect_2-userBazBalanceBeforeCollect_2), uint64(0)) - }) -} diff --git a/position/utils_test.gno b/position/utils_test.gnoA similarity index 99% rename from position/utils_test.gno rename to position/utils_test.gnoA index 04d33a469..fdc75fdb1 100644 --- a/position/utils_test.gno +++ b/position/utils_test.gnoA @@ -170,7 +170,7 @@ func TestAssertOnlyNotHalted(t *testing.T) { { name: "Failure - Halted", expected: false, - panicMsg: "[GNOSWAP-COMMON-002] halted || gnoswap halted", + panicMsg: "[GNOSWAP-COMMON-002] halted || GnoSwap is halted", }, { name: "Success - Not Halted", diff --git a/staker/staker.gno b/staker/staker.gno index fe95cec3e..7fdb517d0 100644 --- a/staker/staker.gno +++ b/staker/staker.gno @@ -17,7 +17,6 @@ import ( pl "gno.land/r/gnoswap/v1/pool" pn "gno.land/r/gnoswap/v1/position" - i256 "gno.land/p/gnoswap/int256" u256 "gno.land/p/gnoswap/uint256" ) @@ -678,7 +677,7 @@ func getTokenPairBalanceFromPosition(tokenId uint64) (string, string) { currentX96, lowerX96, upperX96, - i256.FromUint256(pn.PositionGetPositionLiquidity(tokenId)), + pn.PositionGetPositionLiquidity(tokenId), ) if token0Balance == "" { From c280aef00a572935c4e511a0edb1852285984140 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 24 Dec 2024 13:18:11 +0900 Subject: [PATCH 02/12] fix: gnoA scenario tests --- ...nt_gnot_grc20_in-range_out-range_test.gnoA | 194 ---------------- ...__TEST_fee_collect_with_two_user_test.gnoA | 0 .../{ => tests}/__TEST_position_api_test.gnoA | 10 +- .../__TEST_position_full_test.gnoA | 0 ...TEST_position_full_with_emission_test.gnoA | 0 ...osition_increase_burned_position_test.gnoA | 0 ..._TEST_position_increase_decrease_test.gnoA | 0 ...nt_gnot_grc20_in-range_out-range_test.gnoA | 211 ++++++++++++++++++ ...EST_position_mint_swap_burn_left_test.gnoA | 0 ...osition_native_increase_decrease_test.gnoA | 15 +- ...T_position_native_mint_swap_burn_test.gnoA | 0 ...T_position_reposition_gnot_pair_test.gnoA} | 0 ...T_position_reposition_grc20_pair_test.gnoA | 36 +-- ..._reposition_grc20_pair_with_swap_test.gnoA | 0 ...iff_range_diff_position_swap_fee_test.gnoA | 0 ...ame_range_diff_position_swap_fee_test.gnoA | 0 ...st_two_position_used_single_swap_test.gnoA | 0 ...owed_left_grc20_pair_more_action_test.gnoA | 0 ...owed_left_pair_more_action_exact_test.gnoA | 0 .../__TEST_position_unclaimed_fee_test.gnoA | 0 20 files changed, 241 insertions(+), 225 deletions(-) delete mode 100644 position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA rename position/{ => tests}/__TEST_fee_collect_with_two_user_test.gnoA (100%) rename position/{ => tests}/__TEST_position_api_test.gnoA (95%) rename position/{ => tests}/__TEST_position_full_test.gnoA (100%) rename position/{ => tests}/__TEST_position_full_with_emission_test.gnoA (100%) rename position/{ => tests}/__TEST_position_increase_burned_position_test.gnoA (100%) rename position/{ => tests}/__TEST_position_increase_decrease_test.gnoA (100%) create mode 100644 position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA rename position/{ => tests}/__TEST_position_mint_swap_burn_left_test.gnoA (100%) rename position/{ => tests}/__TEST_position_native_increase_decrease_test.gnoA (93%) rename position/{ => tests}/__TEST_position_native_mint_swap_burn_test.gnoA (100%) rename position/{__TEST_position_reposition_gnot_pair_test.gno => tests/__TEST_position_reposition_gnot_pair_test.gnoA} (100%) rename position/{ => tests}/__TEST_position_reposition_grc20_pair_test.gnoA (93%) rename position/{ => tests}/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA (100%) rename position/{ => tests}/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA (100%) rename position/{ => tests}/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA (100%) rename position/{ => tests}/__TEST_position_test_two_position_used_single_swap_test.gnoA (100%) rename position/{ => tests}/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA (100%) rename position/{ => tests}/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA (100%) rename position/{ => tests}/__TEST_position_unclaimed_fee_test.gnoA (100%) diff --git a/position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA b/position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA deleted file mode 100644 index e2e4def2a..000000000 --- a/position/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA +++ /dev/null @@ -1,194 +0,0 @@ -package position - -import ( - "std" - "testing" - - "gno.land/p/demo/testutils" - "gno.land/p/demo/uassert" - - "gno.land/r/gnoswap/v1/common" - "gno.land/r/gnoswap/v1/consts" - - "gno.land/r/demo/wugnot" - "gno.land/r/gnoswap/v1/gns" - - pl "gno.land/r/gnoswap/v1/pool" -) - -// fresh users -var ( - fresh01 = testutils.TestAddress("fresh01") // g1veex2umgxqc47h6lta047h6lta047h6lgnrusf - fresh02 = testutils.TestAddress("fresh02") // g1veex2umgxqe97h6lta047h6lta047h6lhqv0lu -) - -func TestPoolInitCreatePool(t *testing.T) { - std.TestSetRealm(adminRealm) - gns.Approve(a2u(consts.POOL_ADDR), pl.GetPoolCreationFee()) - pl.CreatePool(consts.GNOT, consts.GNS_PATH, fee500, common.TickMathGetSqrtRatioAtTick(-10000).ToString()) -} - -func TestFreshUser(t *testing.T) { - std.TestIssueCoins(fresh01, std.Coins{{"ugnot", 100_000_000}}) - std.TestIssueCoins(fresh02, std.Coins{{"ugnot", 100_000_000}}) - - std.TestSetRealm(adminRealm) - gns.Transfer(a2u(fresh01), 100_000_000) - gns.Transfer(a2u(fresh02), 100_000_000) - - // fresh users will have... - // 100_000_000 ugnot - // 100_000_000 gns - uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(100_000_000)) - uassert.Equal(t, gns.BalanceOf(a2u(fresh01)), uint64(100_000_000)) - - uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(100_000_000)) - uassert.Equal(t, gns.BalanceOf(a2u(fresh02)), uint64(100_000_000)) -} - -func TestOneSideOnlyGrc20WithoutSend(t *testing.T) { - fresh01Realm := std.NewUserRealm(fresh01) - std.TestSetRealm(fresh01Realm) - - gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - - wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP - - std.TestSetRealm(fresh01Realm) - tokenId, liquidity, amount0, amount1 := Mint( - consts.GNS_PATH, // token0 - consts.GNOT, // token1 - fee500, // fee - 12000, // tickLower - 14000, // tickUpper - "10000000", // amount0Desired - "10000000", // amount1Desired - "0", // amount0Min - "0", // amount1Min - max_timeout, // deadline - fresh01, // operator - fresh01, - ) -} - -func TestOneSideOnlyGrc20WithSend0Coin(t *testing.T) { - fresh01Realm := std.NewUserRealm(fresh01) - std.TestSetRealm(fresh01Realm) - - gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - - wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP - - std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) - - std.TestSetRealm(fresh01Realm) - tokenId, liquidity, amount0, amount1 := Mint( - consts.GNS_PATH, // token0 - consts.GNOT, // token1 - fee500, // fee - 12000, // tickLower - 14000, // tickUpper - "10000000", // amount0Desired - "10000000", // amount1Desired - "0", // amount0Min - "0", // amount1Min - max_timeout, // deadline - fresh01, // operator - fresh01, - ) -} - -func TestOneSideOnlyUgnot(t *testing.T) { - fresh01Realm := std.NewUserRealm(fresh01) - std.TestSetRealm(fresh01Realm) - - gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - - wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP - - std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) - std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) - uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(0)) - - std.TestSetRealm(fresh01Realm) - tokenId, liquidity, amount0, amount1 := Mint( - consts.GNS_PATH, // token0 - consts.GNOT, // token1 - fee500, // fee - 6000, // tickLower - 8000, // tickUpper - "90000000", // amount0Desired - "90000000", // amount1Desired - "0", // amount0Min - "0", // amount1Min - max_timeout, // deadline - fresh01, // operator - fresh01, - ) - - // send 100_000_000 - // mint 900_00_000 - // => remain 10_000_000 - uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(10_000_000)) - uassert.Equal(t, wugnot.BalanceOf(a2u(fresh01)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 -} - -func TestBothWithFresh(t *testing.T) { - fresh02Realm := std.NewUserRealm(fresh02) - std.TestSetRealm(fresh02Realm) - - gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - - wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP - - std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) - std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) - uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(0)) - - std.TestSetRealm(fresh02Realm) - tokenId, liquidity, amount0, amount1 := Mint( - consts.GNS_PATH, // token0 - consts.GNOT, // token1 - fee500, // fee - 6000, // tickLower - 16000, // tickUpper - "70000000", // amount0Desired - "70000000", // amount1Desired - "0", // amount0Min - "0", // amount1Min - max_timeout, // deadline - fresh02, // operator - fresh02, - ) - - // send 100_000_000 - // mint 70_000_000 - // => remain 30_000_000 - uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(30_000_000)) - uassert.Equal(t, wugnot.BalanceOf(a2u(fresh02)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 -} - -func TestBothWithFreshButNoSend(t *testing.T) { - fresh02Realm := std.NewUserRealm(fresh02) - std.TestSetRealm(fresh02Realm) - - gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT - - wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP - - std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) - - std.TestSetRealm(fresh02Realm) - uassert.PanicsWithMessage( - t, - `insufficient balance`, - func() { - Mint(consts.GNS_PATH, consts.GNOT, fee500, 6000, 16000, "70000000", "70000000", "0", "0", max_timeout, fresh02, fresh02) - }, - ) -} diff --git a/position/__TEST_fee_collect_with_two_user_test.gnoA b/position/tests/__TEST_fee_collect_with_two_user_test.gnoA similarity index 100% rename from position/__TEST_fee_collect_with_two_user_test.gnoA rename to position/tests/__TEST_fee_collect_with_two_user_test.gnoA diff --git a/position/__TEST_position_api_test.gnoA b/position/tests/__TEST_position_api_test.gnoA similarity index 95% rename from position/__TEST_position_api_test.gnoA rename to position/tests/__TEST_position_api_test.gnoA index b01673e7c..bcce61003 100644 --- a/position/__TEST_position_api_test.gnoA +++ b/position/tests/__TEST_position_api_test.gnoA @@ -39,10 +39,10 @@ func TestMintFooBar(t *testing.T) { bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // admin mints => will get tid 1 nft - Mint(fooPath, barPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, admin) + Mint(fooPath, barPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, adminAddr) // admin mints => will get tid 2 nft - Mint(fooPath, barPath, fee500, int32(4000), int32(6000), "1000000", "1000000", "0", "0", max_timeout, adminAddr, admin) + Mint(fooPath, barPath, fee500, int32(4000), int32(6000), "1000000", "1000000", "0", "0", max_timeout, adminAddr, adminAddr) } func TestMintBazQux(t *testing.T) { @@ -51,7 +51,7 @@ func TestMintBazQux(t *testing.T) { qux.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // admin mints => will get tid 3 nft - Mint(bazPath, quxPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, admin) + Mint(bazPath, quxPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, adminAddr) } func TestApiGetPositionsUnclaimedFee(t *testing.T) { @@ -181,7 +181,7 @@ func TestApiGetPositionsByPoolPath(t *testing.T) { } func TestApiGetPositionsByAddress(t *testing.T) { - targetAddress := admin + targetAddress := adminAddr gpss := ApiGetPositionsByAddress(targetAddress) @@ -199,7 +199,7 @@ func TestApiGetPositionsByAddress(t *testing.T) { } func TestApiGetPositionsByAddressNo(t *testing.T) { - targetAddress := test1 + targetAddress := addr02 gpss := ApiGetPositionsByAddress(targetAddress) diff --git a/position/__TEST_position_full_test.gnoA b/position/tests/__TEST_position_full_test.gnoA similarity index 100% rename from position/__TEST_position_full_test.gnoA rename to position/tests/__TEST_position_full_test.gnoA diff --git a/position/__TEST_position_full_with_emission_test.gnoA b/position/tests/__TEST_position_full_with_emission_test.gnoA similarity index 100% rename from position/__TEST_position_full_with_emission_test.gnoA rename to position/tests/__TEST_position_full_with_emission_test.gnoA diff --git a/position/__TEST_position_increase_burned_position_test.gnoA b/position/tests/__TEST_position_increase_burned_position_test.gnoA similarity index 100% rename from position/__TEST_position_increase_burned_position_test.gnoA rename to position/tests/__TEST_position_increase_burned_position_test.gnoA diff --git a/position/__TEST_position_increase_decrease_test.gnoA b/position/tests/__TEST_position_increase_decrease_test.gnoA similarity index 100% rename from position/__TEST_position_increase_decrease_test.gnoA rename to position/tests/__TEST_position_increase_decrease_test.gnoA diff --git a/position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA b/position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA new file mode 100644 index 000000000..271185f64 --- /dev/null +++ b/position/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA @@ -0,0 +1,211 @@ +package position + +import ( + "std" + "testing" + + "gno.land/p/demo/testutils" + "gno.land/p/demo/uassert" + + "gno.land/r/gnoswap/v1/common" + "gno.land/r/gnoswap/v1/consts" + + "gno.land/r/demo/wugnot" + "gno.land/r/gnoswap/v1/gns" + + pl "gno.land/r/gnoswap/v1/pool" +) + +// fresh users +var ( + fresh01 = testutils.TestAddress("fresh01") // g1veex2umgxqc47h6lta047h6lta047h6lgnrusf + fresh02 = testutils.TestAddress("fresh02") // g1veex2umgxqe97h6lta047h6lta047h6lhqv0lu +) + +func TestPoolInitCreatePool(t *testing.T) { + std.TestSetRealm(adminRealm) + gns.Approve(a2u(consts.POOL_ADDR), pl.GetPoolCreationFee()) + pl.CreatePool(consts.GNOT, consts.GNS_PATH, fee500, common.TickMathGetSqrtRatioAtTick(-10000).ToString()) + + singlePool := pl.GetPoolFromPoolPath("gno.land/r/demo/wugnot:gno.land/r/gnoswap/v1/gns:500") +} + +func TestFreshUser(t *testing.T) { + std.TestIssueCoins(fresh01, std.Coins{{"ugnot", 100_000_000}}) + std.TestIssueCoins(fresh02, std.Coins{{"ugnot", 100_000_000}}) + + std.TestSetRealm(adminRealm) + gns.Transfer(a2u(fresh01), 100_000_000) + gns.Transfer(a2u(fresh02), 100_000_000) + + // fresh users will have... + // 100_000_000 ugnot + // 100_000_000 gns + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(100_000_000)) + uassert.Equal(t, gns.BalanceOf(a2u(fresh01)), uint64(100_000_000)) + + uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(100_000_000)) + uassert.Equal(t, gns.BalanceOf(a2u(fresh02)), uint64(100_000_000)) +} + +func TestOneSideOnlyGrc20WithoutSend(t *testing.T) { + fresh01Realm := std.NewUserRealm(fresh01) + std.TestSetRealm(fresh01Realm) + + gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + + wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP + + // should panic + // user is trying to mint position with native coin, but didn't send any native coin + uassert.PanicsWithMessage( + t, + "[GNOSWAP-POSITION-014] No UGNOTs were sent || amount of ugnot is zero", + func() { + std.TestSetRealm(fresh01Realm) + tokenId, liquidity, amount0, amount1 := Mint( + consts.GNS_PATH, // token0 + consts.GNOT, // token1 + fee500, // fee + 12000, // tickLower + 14000, // tickUpper + "10000000", // amount0Desired + "10000000", // amount1Desired + "0", // amount0Min + "0", // amount1Min + max_timeout, // deadline + fresh01, // operator + fresh01, + ) + }, + ) +} + +func TestOneSideOnlyGrc20WithSend0Coin(t *testing.T) { + fresh01Realm := std.NewUserRealm(fresh01) + std.TestSetRealm(fresh01Realm) + + gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + + wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP + + std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) + + // should panic + // user is trying to mint position with native coin, but sent 0 coin + uassert.PanicsWithMessage( + t, + "[GNOSWAP-POSITION-014] No UGNOTs were sent || amount of ugnot is zero", + func() { + std.TestSetRealm(fresh01Realm) + tokenId, liquidity, amount0, amount1 := Mint( + consts.GNS_PATH, // token0 + consts.GNOT, // token1 + fee500, // fee + 12000, // tickLower + 14000, // tickUpper + "10000000", // amount0Desired + "10000000", // amount1Desired + "0", // amount0Min + "0", // amount1Min + max_timeout, // deadline + fresh01, // operator + fresh01, + ) + }, + ) +} + +func TestOneSideOnlyUgnot(t *testing.T) { + fresh01Realm := std.NewUserRealm(fresh01) + std.TestSetRealm(fresh01Realm) + + gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + + wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP + + std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) + std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(0)) + + std.TestSetRealm(fresh01Realm) + tokenId, liquidity, amount0, amount1 := Mint( + consts.GNS_PATH, // token0 + consts.GNOT, // token1 + fee500, // fee + 6000, // tickLower + 8000, // tickUpper + "90000000", // amount0Desired + "90000000", // amount1Desired + "0", // amount0Min + "0", // amount1Min + max_timeout, // deadline + fresh01, // operator + fresh01, + ) + // send 100000000 + // mint 90000000 + // => remain 10000000 + uassert.Equal(t, ugnotBalanceOf(t, fresh01), uint64(10000000)) + uassert.Equal(t, wugnot.BalanceOf(a2u(fresh01)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 +} + +// func TestBothWithFresh(t *testing.T) { +// fresh02Realm := std.NewUserRealm(fresh02) +// std.TestSetRealm(fresh02Realm) + +// gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT +// wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + +// wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP + +// std.TestIssueCoins(consts.POSITION_ADDR, std.Coins{{"ugnot", 100_000_000}}) +// std.TestSetOrigSend(std.Coins{{"ugnot", 100_000_000}}, nil) +// uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(0)) + +// std.TestSetRealm(fresh02Realm) +// tokenId, liquidity, amount0, amount1 := Mint( +// consts.GNS_PATH, // token0 +// consts.GNOT, // token1 +// fee500, // fee +// 6000, // tickLower +// 16000, // tickUpper +// "70000000", // amount0Desired +// "70000000", // amount1Desired +// "0", // amount0Min +// "0", // amount1Min +// max_timeout, // deadline +// fresh02, // operator +// fresh02, +// ) + +// // send 100_000_000 +// // mint 70_000_000 +// // => remain 30_000_000 +// uassert.Equal(t, ugnotBalanceOf(t, fresh02), uint64(30_000_000)) +// uassert.Equal(t, wugnot.BalanceOf(a2u(fresh02)), uint64(0)) // position will unwrap remaining wugnot to ugnot, so wugnot balance should be 0 +// } + +// func TestBothWithFreshButNoSend(t *testing.T) { +// fresh02Realm := std.NewUserRealm(fresh02) +// std.TestSetRealm(fresh02Realm) + +// gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT +// wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) // POOL FOR MINT + +// wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // POSITION FOR WRAP + +// std.TestSetOrigSend(std.Coins{{"ugnot", 0}}, nil) + +// std.TestSetRealm(fresh02Realm) +// uassert.PanicsWithMessage( +// t, +// `insufficient balance`, +// func() { +// Mint(consts.GNS_PATH, consts.GNOT, fee500, 6000, 16000, "70000000", "70000000", "0", "0", max_timeout, fresh02, fresh02) +// }, +// ) +// } diff --git a/position/__TEST_position_mint_swap_burn_left_test.gnoA b/position/tests/__TEST_position_mint_swap_burn_left_test.gnoA similarity index 100% rename from position/__TEST_position_mint_swap_burn_left_test.gnoA rename to position/tests/__TEST_position_mint_swap_burn_left_test.gnoA diff --git a/position/__TEST_position_native_increase_decrease_test.gnoA b/position/tests/__TEST_position_native_increase_decrease_test.gnoA similarity index 93% rename from position/__TEST_position_native_increase_decrease_test.gnoA rename to position/tests/__TEST_position_native_increase_decrease_test.gnoA index a26971a6a..d21b3135f 100644 --- a/position/__TEST_position_native_increase_decrease_test.gnoA +++ b/position/tests/__TEST_position_native_increase_decrease_test.gnoA @@ -20,7 +20,6 @@ func TestCoinIncreaseDecrease(t *testing.T) { testMintPosition(t) testIncreaseLiquidity(t) testDecreaseLiquidityWrapped(t) - // testDecreaseLiquidityUnwrapped(t) } func testPoolInitCreatePool(t *testing.T) { @@ -87,8 +86,8 @@ func testMintPosition(t *testing.T) { uassert.Equal(t, ugnotBalanceOf(t, adminAddr), uint64(5)) // 1. 50000005 ugnot sent // 2. 50000005 ugnot wrapped to wugnot - // 3. 50000000 wugnot spent to mint (amount1) - // 4. refund 50000005 - 50000000 = 5 + // 3. 50000000 wugnot spent to mint (amount) + // 4. refund 5 ugnot ( admin ugnot balance ) }) } @@ -101,7 +100,7 @@ func testIncreaseLiquidity(t *testing.T) { wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX) // WRAP - pool := getPoolFromLpTokenId(t,uint64(1)) + pool := getPoolFromLpTokenId(t, uint64(1)) oldLiquidity := pool.Liquidity() // prepare 10000005ugnot (5 for refund test) @@ -148,7 +147,7 @@ func testDecreaseLiquidityWrapped(t *testing.T) { t.Run("decrease liquidity wrapped", func(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() + oldLiquidity := getPoolFromLpTokenId(t, uint64(1)).Liquidity() userWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, userWugnotBalance, uint64(0)) @@ -171,7 +170,7 @@ func testDecreaseLiquidityWrapped(t *testing.T) { userUgnotBalance = ugnotBalanceOf(t, adminAddr) // wrapped result, so ugnot didn't change uassert.Equal(t, userUgnotBalance, uint64(10)) - newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() + newLiquidity := getPoolFromLpTokenId(t, uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left @@ -187,7 +186,7 @@ func testDecreaseLiquidityUnwrapped(t *testing.T) { t.Run("decrease liquidity unwrapped", func(t *testing.T) { std.TestSetRealm(adminRealm) - oldLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() + oldLiquidity := getPoolFromLpTokenId(t, uint64(1)).Liquidity() userWugnotBalance := wugnot.BalanceOf(admin) uassert.Equal(t, userWugnotBalance, uint64(11999999)) @@ -210,7 +209,7 @@ func testDecreaseLiquidityUnwrapped(t *testing.T) { userUgnotBalance = ugnotBalanceOf(t, adminAddr) // unwrapped result, so ugnot decreased uassert.Equal(t, userUgnotBalance, uint64(24000009)) - newLiquidity := getPoolFromLpTokenId(t,uint64(1)).Liquidity() + newLiquidity := getPoolFromLpTokenId(t, uint64(1)).Liquidity() uassert.Equal(t, true, newLiquidity.Lt(oldLiquidity)) // check fee left diff --git a/position/__TEST_position_native_mint_swap_burn_test.gnoA b/position/tests/__TEST_position_native_mint_swap_burn_test.gnoA similarity index 100% rename from position/__TEST_position_native_mint_swap_burn_test.gnoA rename to position/tests/__TEST_position_native_mint_swap_burn_test.gnoA diff --git a/position/__TEST_position_reposition_gnot_pair_test.gno b/position/tests/__TEST_position_reposition_gnot_pair_test.gnoA similarity index 100% rename from position/__TEST_position_reposition_gnot_pair_test.gno rename to position/tests/__TEST_position_reposition_gnot_pair_test.gnoA diff --git a/position/__TEST_position_reposition_grc20_pair_test.gnoA b/position/tests/__TEST_position_reposition_grc20_pair_test.gnoA similarity index 93% rename from position/__TEST_position_reposition_grc20_pair_test.gnoA rename to position/tests/__TEST_position_reposition_grc20_pair_test.gnoA index 812dcec2a..c26d7a599 100644 --- a/position/__TEST_position_reposition_grc20_pair_test.gnoA +++ b/position/tests/__TEST_position_reposition_grc20_pair_test.gnoA @@ -151,25 +151,25 @@ func TestUnclaimedFee02(t *testing.T) { func TestDecreaseLiquidityInPosition(t *testing.T) { std.TestSetRealm(adminRealm) - _lpTokenId := uint64(1) + lpTokenId := uint64(1) - ownerOfPosition := gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + ownerOfPosition := gnft.OwnerOf(tokenIdFrom(lpTokenId)) uassert.Equal(t, ownerOfPosition, adminAddr) - // approve fee0, fee_lpTokenId to pool + // approve fee0, feelpTokenId to pool bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) foo.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) - tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity(_lpTokenId, 100, "0", "0", max_timeout, false) + tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := DecreaseLiquidity(lpTokenId, 100, "0", "0", max_timeout, false) - uassert.Equal(t, tokenId, _lpTokenId) + uassert.Equal(t, tokenId, lpTokenId) uassert.Equal(t, amount0, "19628840") uassert.Equal(t, amount1, "46667220") - ownerOfPosition = gnft.OwnerOf(tokenIdFrom(_lpTokenId)) + ownerOfPosition = gnft.OwnerOf(tokenIdFrom(lpTokenId)) uassert.Equal(t, ownerOfPosition, adminAddr) - position := MustGetPosition(_lpTokenId) + position := MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") @@ -255,10 +255,10 @@ func TestRepositionSlippageTooLarge(t *testing.T) { func TestReposition(t *testing.T) { std.TestSetRealm(adminRealm) - _lpTokenId := uint64(1) + lpTokenId := uint64(1) // check current state - position := MustGetPosition(_lpTokenId) + position := MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") @@ -272,23 +272,23 @@ func TestReposition(t *testing.T) { uassert.Equal(t, position.burned, true) Reposition( - _lpTokenId, // tokenId - -1000, // tickLower - 1000, // tickUpper - "500", // amount0Desired - "500", // amount1Desired - "0", // amount0Min - "100", // amount1Min + lpTokenId, // tokenId + -1000, // tickLower + 1000, // tickUpper + "500", // amount0Desired + "500", // amount1Desired + "0", // amount0Min + "100", // amount1Min ) - position = MustGetPosition(_lpTokenId) + position = MustGetPosition(lpTokenId) uassert.Equal(t, position.nonce.ToString(), "0") uassert.Equal(t, position.operator, consts.ZERO_ADDRESS) uassert.Equal(t, position.poolKey, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") uassert.Equal(t, position.tickLower, int32(-1000)) uassert.Equal(t, position.tickUpper, int32(1000)) uassert.Equal(t, position.liquidity.ToString(), "4998") - uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), "659841872392960215058365142934185") + uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), "0") uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), "0") uassert.Equal(t, position.tokensOwed0.ToString(), "0") uassert.Equal(t, position.tokensOwed1.ToString(), "0") diff --git a/position/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA b/position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA similarity index 100% rename from position/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA rename to position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA diff --git a/position/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA b/position/tests/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA similarity index 100% rename from position/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA rename to position/tests/__TEST_position_same_user_same_pool_diff_range_diff_position_swap_fee_test.gnoA diff --git a/position/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA b/position/tests/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA similarity index 100% rename from position/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA rename to position/tests/__TEST_position_same_user_same_pool_same_range_diff_position_swap_fee_test.gnoA diff --git a/position/__TEST_position_test_two_position_used_single_swap_test.gnoA b/position/tests/__TEST_position_test_two_position_used_single_swap_test.gnoA similarity index 100% rename from position/__TEST_position_test_two_position_used_single_swap_test.gnoA rename to position/tests/__TEST_position_test_two_position_used_single_swap_test.gnoA diff --git a/position/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA b/position/tests/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA similarity index 100% rename from position/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA rename to position/tests/__TEST_position_tokens_owed_left_grc20_pair_more_action_test.gnoA diff --git a/position/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA b/position/tests/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA similarity index 100% rename from position/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA rename to position/tests/__TEST_position_tokens_owed_left_pair_more_action_exact_test.gnoA diff --git a/position/__TEST_position_unclaimed_fee_test.gnoA b/position/tests/__TEST_position_unclaimed_fee_test.gnoA similarity index 100% rename from position/__TEST_position_unclaimed_fee_test.gnoA rename to position/tests/__TEST_position_unclaimed_fee_test.gnoA From 5689bf00a7e3c4e37b843b5a25862e4a16c151d7 Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 24 Dec 2024 13:18:21 +0900 Subject: [PATCH 03/12] chore: remove deprecated --- .../__TEST_0_INIT_TOKEN_REGISTER_test.gnoA | 176 ------------------ .../__TEST_0_INIT_VARS_HELPERS_test.gnoA | 68 ------- 2 files changed, 244 deletions(-) delete mode 100644 position/tests/__TEST_0_INIT_TOKEN_REGISTER_test.gnoA delete mode 100644 position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA diff --git a/position/tests/__TEST_0_INIT_TOKEN_REGISTER_test.gnoA b/position/tests/__TEST_0_INIT_TOKEN_REGISTER_test.gnoA deleted file mode 100644 index 8da3b3790..000000000 --- a/position/tests/__TEST_0_INIT_TOKEN_REGISTER_test.gnoA +++ /dev/null @@ -1,176 +0,0 @@ -package position - -import ( - "std" - - "gno.land/r/onbloc/foo" - - "gno.land/r/onbloc/bar" - - "gno.land/r/onbloc/baz" - - "gno.land/r/onbloc/qux" - - "gno.land/r/demo/wugnot" - - "gno.land/r/onbloc/obl" - - "gno.land/r/gnoswap/v1/gns" - - "gno.land/r/onbloc/usdc" - - "gno.land/r/gnoswap/v1/consts" - - pusers "gno.land/p/demo/users" - - pl "gno.land/r/gnoswap/v1/pool" - rr "gno.land/r/gnoswap/v1/router" -) - -type FooToken struct{} - -func (FooToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return foo.Transfer -} -func (FooToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return foo.TransferFrom -} -func (FooToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return foo.BalanceOf -} -func (FooToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return foo.Approve -} - -type BarToken struct{} - -func (BarToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return bar.Transfer -} -func (BarToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return bar.TransferFrom -} -func (BarToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return bar.BalanceOf -} -func (BarToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return bar.Approve -} - -type BazToken struct{} - -func (BazToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return baz.Transfer -} -func (BazToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return baz.TransferFrom -} -func (BazToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return baz.BalanceOf -} -func (BazToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return baz.Approve -} - -type QuxToken struct{} - -func (QuxToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return qux.Transfer -} -func (QuxToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return qux.TransferFrom -} -func (QuxToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return qux.BalanceOf -} -func (QuxToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return qux.Approve -} - -type WugnotToken struct{} - -func (WugnotToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return wugnot.Transfer -} -func (WugnotToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return wugnot.TransferFrom -} -func (WugnotToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return wugnot.BalanceOf -} -func (WugnotToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return wugnot.Approve -} - -type OBLToken struct{} - -func (OBLToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return obl.Transfer -} -func (OBLToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return obl.TransferFrom -} -func (OBLToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return obl.BalanceOf -} -func (OBLToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return obl.Approve -} - -type GNSToken struct{} - -func (GNSToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return gns.Transfer -} - -func (GNSToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return gns.TransferFrom -} - -func (GNSToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return gns.BalanceOf -} - -func (GNSToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return gns.Approve -} - -type USDCToken struct{} - -func (USDCToken) Transfer() func(to pusers.AddressOrName, amount uint64) { - return usdc.Transfer -} - -func (USDCToken) TransferFrom() func(from, to pusers.AddressOrName, amount uint64) { - return usdc.TransferFrom -} - -func (USDCToken) BalanceOf() func(owner pusers.AddressOrName) uint64 { - return usdc.BalanceOf -} - -func (USDCToken) Approve() func(spender pusers.AddressOrName, amount uint64) { - return usdc.Approve -} - -func init() { - std.TestSetRealm(std.NewUserRealm(consts.TOKEN_REGISTER)) - - pl.RegisterGRC20Interface("gno.land/r/onbloc/bar", BarToken{}) - pl.RegisterGRC20Interface("gno.land/r/onbloc/foo", FooToken{}) - pl.RegisterGRC20Interface("gno.land/r/onbloc/baz", BazToken{}) - pl.RegisterGRC20Interface("gno.land/r/onbloc/qux", QuxToken{}) - pl.RegisterGRC20Interface("gno.land/r/demo/wugnot", WugnotToken{}) - pl.RegisterGRC20Interface("gno.land/r/onbloc/obl", OBLToken{}) - pl.RegisterGRC20Interface("gno.land/r/gnoswap/v1/gns", GNSToken{}) - pl.RegisterGRC20Interface("gno.land/r/onbloc/usdc", USDCToken{}) - - rr.RegisterGRC20Interface("gno.land/r/onbloc/bar", BarToken{}) - rr.RegisterGRC20Interface("gno.land/r/onbloc/foo", FooToken{}) - rr.RegisterGRC20Interface("gno.land/r/onbloc/baz", BazToken{}) - rr.RegisterGRC20Interface("gno.land/r/onbloc/qux", QuxToken{}) - rr.RegisterGRC20Interface("gno.land/r/demo/wugnot", WugnotToken{}) - rr.RegisterGRC20Interface("gno.land/r/onbloc/obl", OBLToken{}) - rr.RegisterGRC20Interface("gno.land/r/gnoswap/v1/gns", GNSToken{}) - rr.RegisterGRC20Interface("gno.land/r/onbloc/usdc", USDCToken{}) -} diff --git a/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA b/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA deleted file mode 100644 index 871bf5b3a..000000000 --- a/position/tests/__TEST_0_INIT_VARS_HELPERS_test.gnoA +++ /dev/null @@ -1,68 +0,0 @@ -package position - -import ( - "std" - "testing" - - "gno.land/r/gnoswap/v1/consts" - - "gno.land/r/gnoswap/v1/gnft" - - pl "gno.land/r/gnoswap/v1/pool" -) - -var ( - admin std.Address = consts.ADMIN - test1 std.Address = std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") - - fooPath string = "gno.land/r/onbloc/foo" - barPath string = "gno.land/r/onbloc/bar" - bazPath string = "gno.land/r/onbloc/baz" - quxPath string = "gno.land/r/onbloc/qux" - - oblPath string = "gno.land/r/onbloc/obl" - // wugnotPath string = "gno.land/r/demo/wugnot" // from consts - // gnsPath string = "gno.land/r/gnoswap/v1/gns" // from consts - - fee100 uint32 = 100 - fee500 uint32 = 500 - fee3000 uint32 = 3000 - - max_timeout int64 = 9999999999 -) - -// Realms to mock frames -var ( - adminRealm = std.NewUserRealm(admin) - posRealm = std.NewCodeRealm(consts.POSITION_PATH) - rouRealm = std.NewCodeRealm(consts.ROUTER_PATH) - stkRealm = std.NewCodeRealm(consts.STAKER_PATH) -) - -/* HELPER */ -func ugnotBalanceOf(addr std.Address) uint64 { - testBanker := std.GetBanker(std.BankerTypeRealmIssue) - - coins := testBanker.GetCoins(addr) - if len(coins) == 0 { - return 0 - } - - return uint64(coins.AmountOf("ugnot")) -} - -func isOwner(t *testing.T, tokenId uint64, addr std.Address) bool { - owner := gnft.OwnerOf(tokenIdFrom(tokenId)) - - if owner == addr { - return true - } - - t.Errorf("expected owner %v, got %v", addr, owner) - return false -} - -func getPoolFromLpTokenId(lpTokenId uint64) *pl.Pool { - position := MustGetPosition(lpTokenId) - return pl.GetPoolFromPoolPath(position.poolKey) -} From 09cff7bdd1feb351c1e3fe99ff47991b187518ea Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 24 Dec 2024 13:18:50 +0900 Subject: [PATCH 04/12] fix: mint params should use updated value --- position/type.gno | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/position/type.gno b/position/type.gno index 7a5383745..a52f25439 100644 --- a/position/type.gno +++ b/position/type.gno @@ -58,8 +58,8 @@ func newMintParams(input ProcessedMintInput, mintInput MintInput) MintParams { token0: input.tokenPair.token0, token1: input.tokenPair.token1, fee: mintInput.fee, - tickLower: mintInput.tickLower, - tickUpper: mintInput.tickUpper, + tickLower: input.tickLower, + tickUpper: input.tickUpper, amount0Desired: input.amount0Desired, amount1Desired: input.amount1Desired, amount0Min: input.amount0Min, From 72c631b51cb360f61215935ba73d5df37ae6d69a Mon Sep 17 00:00:00 2001 From: n3wbie Date: Tue, 24 Dec 2024 13:23:00 +0900 Subject: [PATCH 05/12] chore: revert unittest file extension changes --- ...quidity_management_test.gnoA => liquidity_management_test.gno} | 0 position/{native_token_test.gnoA => native_token_test.gno} | 0 position/{position_test.gnoA => position_test.gno} | 0 position/{utils_test.gnoA => utils_test.gno} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename position/{liquidity_management_test.gnoA => liquidity_management_test.gno} (100%) rename position/{native_token_test.gnoA => native_token_test.gno} (100%) rename position/{position_test.gnoA => position_test.gno} (100%) rename position/{utils_test.gnoA => utils_test.gno} (100%) diff --git a/position/liquidity_management_test.gnoA b/position/liquidity_management_test.gno similarity index 100% rename from position/liquidity_management_test.gnoA rename to position/liquidity_management_test.gno diff --git a/position/native_token_test.gnoA b/position/native_token_test.gno similarity index 100% rename from position/native_token_test.gnoA rename to position/native_token_test.gno diff --git a/position/position_test.gnoA b/position/position_test.gno similarity index 100% rename from position/position_test.gnoA rename to position/position_test.gno diff --git a/position/utils_test.gnoA b/position/utils_test.gno similarity index 100% rename from position/utils_test.gnoA rename to position/utils_test.gno From 2dcf834ea56687c1d627c455129e0fe4ea5fc2ed Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Tue, 24 Dec 2024 14:10:43 +0900 Subject: [PATCH 06/12] fix: testing fail issue --- emission/emission.gno | 1 + emission/mint_gns.gno | 2 +- router/comptue_routes.gno | 4 ++-- staker/staker.gno | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/emission/emission.gno b/emission/emission.gno index f781acc48..0170deb91 100644 --- a/emission/emission.gno +++ b/emission/emission.gno @@ -7,6 +7,7 @@ import ( "gno.land/p/demo/ufmt" "gno.land/r/gnoswap/v1/common" + "gno.land/r/gnoswap/v1/consts" "gno.land/r/gnoswap/v1/gns" ) diff --git a/emission/mint_gns.gno b/emission/mint_gns.gno index 6c848a277..2de98dc78 100644 --- a/emission/mint_gns.gno +++ b/emission/mint_gns.gno @@ -11,5 +11,5 @@ var emissionAddr std.Address = consts.EMISSION_ADDR // mintGns mints GNS to emission address func mintGns() uint64 { - return gns.Mint(a2u(emissionAddr)) + return gns.MintGns(a2u(emissionAddr)) } diff --git a/router/comptue_routes.gno b/router/comptue_routes.gno index cddb40984..d80ce973e 100644 --- a/router/comptue_routes.gno +++ b/router/comptue_routes.gno @@ -3,8 +3,8 @@ package router import ( "sort" - pl "gno.land/r/gnoswap/v1/pool" u256 "gno.land/p/gnoswap/uint256" + pl "gno.land/r/gnoswap/v1/pool" "gno.land/p/demo/ufmt" ) @@ -175,7 +175,7 @@ func findCandidatePools() []PoolWithMeta { token0Path, token1Path, pFee := poolPathWithFeeDivide(poolPath) pool := pl.GetPoolFromPoolPath(poolPath) - liquidity := pool.PoolGetLiquidity() + liquidity := pool.Liquidity() poolWithMetas = append(poolWithMetas, PoolWithMeta{ poolPath, token0Path, diff --git a/staker/staker.gno b/staker/staker.gno index 7fdb517d0..e1c0d2dc0 100644 --- a/staker/staker.gno +++ b/staker/staker.gno @@ -669,7 +669,7 @@ func getTokenPairBalanceFromPosition(tokenId uint64) (string, string) { poolKey := pn.PositionGetPositionPoolKey(tokenId) pool := pl.GetPoolFromPoolPath(poolKey) - currentX96 := pool.PoolGetSlot0SqrtPriceX96() + currentX96 := pool.Slot0SqrtPriceX96() lowerX96 := common.TickMathGetSqrtRatioAtTick(pn.PositionGetPositionTickLower(tokenId)) upperX96 := common.TickMathGetSqrtRatioAtTick(pn.PositionGetPositionTickUpper(tokenId)) From 8c6a5ceea2355b514422f6a84e3ecf6dedfabc0a Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Tue, 24 Dec 2024 18:48:27 +0900 Subject: [PATCH 07/12] test : Add missing test code --- position/_helper_test.gno | 7 + position/liquidity_management_test.gno | 5 - position/native_token_test.gno | 40 +- position/position.gno | 21 - position/position_test.gno | 834 ++++++++++++++++++++++++- position/utils.gno | 10 - position/utils_test.gno | 61 +- 7 files changed, 908 insertions(+), 70 deletions(-) diff --git a/position/_helper_test.gno b/position/_helper_test.gno index fdcaf2828..30ccacef0 100644 --- a/position/_helper_test.gno +++ b/position/_helper_test.gno @@ -518,6 +518,13 @@ func MintPositionAll(t *testing.T, caller std.Address) { } +func CreatePoolWithoutFee(t *testing.T) { + std.TestSetRealm(adminRealm) + // set pool create fee to 0 for testing + pl.SetPoolCreationFeeByAdmin(0) + CreatePool(t, barPath, fooPath, fee500, common.TickMathGetSqrtRatioAtTick(0).ToString(), users.Resolve(admin)) +} + func MakeMintPositionWithoutFee(t *testing.T) (uint64, string, string, string) { t.Helper() diff --git a/position/liquidity_management_test.gno b/position/liquidity_management_test.gno index d78debd57..5662fbd61 100644 --- a/position/liquidity_management_test.gno +++ b/position/liquidity_management_test.gno @@ -108,8 +108,3 @@ func TestAddLiquidity(t *testing.T) { }) } } - -func TestSplitOf(t *testing.T) { - // TODO: - -} diff --git a/position/native_token_test.gno b/position/native_token_test.gno index 1a1e935ca..dfface380 100644 --- a/position/native_token_test.gno +++ b/position/native_token_test.gno @@ -289,7 +289,45 @@ func TestIsNative(t *testing.T) { } func TestIsWrappedToken(t *testing.T) { - // TODO: + tests := []struct { + name string + tokenPath string + expected bool + }{ + { + name: "Success - Token is Wrapped WUGNOT", + tokenPath: consts.WRAPPED_WUGNOT, + expected: true, + }, + { + name: "Fail - Token is not Wrapped WUGNOT", + tokenPath: "gno.land/r/demo/ugnot", + expected: false, + }, + { + name: "Fail - Empty tokenPath", + tokenPath: "", + expected: false, + }, + { + name: "Fail - Similar but Different Token Path", + tokenPath: "gno.land/r/demo/Wugnot", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := isWrappedToken(tt.tokenPath) + if result != tt.expected { + t.Errorf( + "expected %s but got %s", + strconv.FormatBool(tt.expected), + strconv.FormatBool(result), + ) + } + }) + } } func TestSafeWrapNativeToken(t *testing.T) { diff --git a/position/position.gno b/position/position.gno index 314eccd87..0b054e5c8 100644 --- a/position/position.gno +++ b/position/position.gno @@ -216,7 +216,6 @@ func Mint( mintParams := newMintParams(processedInput, mintInput) tokenId, liquidity, amount0, amount1 := mint(mintParams) - if processedInput.tokenPair.token0IsNative && processedInput.tokenPair.wrappedAmount > amount0.Uint64() { // unwrap leftover wugnot err = unwrap(processedInput.tokenPair.wrappedAmount-amount0.Uint64(), caller) @@ -231,11 +230,9 @@ func Mint( panic(newErrorWithDetail(errWrapUnwrap, err.Error())) } } - poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(processedInput.poolPath) prevAddr, prevPkgPath := getPrevAsString() - std.Emit( "Mint", "prevAddr", prevAddr, @@ -1091,24 +1088,6 @@ func Reposition( position.burned = false mustUpdatePosition(tokenId, position) - // // WIP - // pl.Burn( - // token0, - // token1, - // fee, - // tickLower, - // tickUpper, - // ZERO_LIQUIDITY_FOR_FEE_COLLECTION, - // ) - // currentFeeGrowth, err = getCurrentFeeGrowth(position, token0, token1, fee) - // if err != nil { - // panic(newErrorWithDetail(err, "failed to get current fee growth")) - // } - // tokensOwed0, tokensOwed1 := calculateFees(position, currentFeeGrowth) - // position.feeGrowthInside0LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside0LastX128) - // position.feeGrowthInside1LastX128 = new(u256.Uint).Set(currentFeeGrowth.feeGrowthInside1LastX128) - // mustUpdatePosition(tokenId, position) - poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(position.poolKey) prevAddr, prevPkgPath := getPrevAsString() diff --git a/position/position_test.gno b/position/position_test.gno index 3a6e2666e..5ccce3279 100644 --- a/position/position_test.gno +++ b/position/position_test.gno @@ -4,6 +4,7 @@ import ( "std" "strconv" "testing" + "time" "gno.land/p/demo/testutils" "gno.land/p/demo/uassert" @@ -11,6 +12,7 @@ import ( "gno.land/r/demo/users" "gno.land/r/gnoswap/v1/consts" + "gno.land/r/gnoswap/v1/gnft" ) var ( @@ -38,24 +40,134 @@ func IsRegistered(t *testing.T, tokenPath string) error { return errInvalidTokenPath } +func newDummyPosition(tokenId uint64) Position { + return Position{ + nonce: u256.NewUint(tokenId), + operator: "user1", + poolKey: "poolKey1", + tickLower: -500, + tickUpper: 500, + liquidity: u256.NewUint(1000), + feeGrowthInside0LastX128: u256.NewUint(10), + feeGrowthInside1LastX128: u256.NewUint(20), + tokensOwed0: u256.NewUint(30), + tokensOwed1: u256.NewUint(40), + burned: false, + } +} + func TestMustGetPosition(t *testing.T) { - t.Skip("TODO: Implement") + tokenId := uint64(1) + position := newDummyPosition(tokenId) + setPosition(tokenId, position) + + t.Run("Success - Get existing position", func(t *testing.T) { + result := MustGetPosition(tokenId) + uassert.Equal(t, position.nonce.ToString(), result.nonce.ToString()) + uassert.Equal(t, position.operator, result.operator) + uassert.Equal(t, position.poolKey, result.poolKey) + uassert.Equal(t, position.tickLower, result.tickLower) + uassert.Equal(t, position.tickUpper, result.tickUpper) + uassert.Equal(t, position.liquidity.ToString(), result.liquidity.ToString()) + uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), result.feeGrowthInside0LastX128.ToString()) + uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), result.feeGrowthInside1LastX128.ToString()) + uassert.Equal(t, position.tokensOwed0.ToString(), result.tokensOwed0.ToString()) + uassert.Equal(t, position.tokensOwed1.ToString(), result.tokensOwed1.ToString()) + uassert.Equal(t, position.burned, result.burned) + }) + + t.Run("Fail - Non-existent position", func(t *testing.T) { + uassert.PanicsWithMessage(t, + "[GNOSWAP-POSITION-013] position does not exist || position with tokenId(999) doesn't exist", + func() { + MustGetPosition(999) + }) + }) } func TestGetPosition(t *testing.T) { - t.Skip("TODO: Implement") + tokenId := uint64(1) + position := newDummyPosition(tokenId) + t.Run("Success - Get existing position", func(t *testing.T) { + result := MustGetPosition(tokenId) + uassert.Equal(t, position.nonce.ToString(), result.nonce.ToString()) + uassert.Equal(t, position.operator, result.operator) + uassert.Equal(t, position.poolKey, result.poolKey) + uassert.Equal(t, position.tickLower, result.tickLower) + uassert.Equal(t, position.tickUpper, result.tickUpper) + uassert.Equal(t, position.liquidity.ToString(), result.liquidity.ToString()) + uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), result.feeGrowthInside0LastX128.ToString()) + uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), result.feeGrowthInside1LastX128.ToString()) + uassert.Equal(t, position.tokensOwed0.ToString(), result.tokensOwed0.ToString()) + uassert.Equal(t, position.tokensOwed1.ToString(), result.tokensOwed1.ToString()) + uassert.Equal(t, position.burned, result.burned) + removePosition(tokenId) + }) } func TestSetPosition(t *testing.T) { - t.Skip("TODO: Implement") + tokenId := uint64(2) + position := newDummyPosition(tokenId) + + t.Run("Success - Create new position", func(t *testing.T) { + isNew := setPosition(tokenId, position) + uassert.False(t, isNew) + + storedPosition, _ := GetPosition(tokenId) + uassert.Equal(t, position.nonce.ToString(), storedPosition.nonce.ToString()) + uassert.Equal(t, position.operator, storedPosition.operator) + uassert.Equal(t, position.poolKey, storedPosition.poolKey) + uassert.Equal(t, position.tickLower, storedPosition.tickLower) + uassert.Equal(t, position.tickUpper, storedPosition.tickUpper) + uassert.Equal(t, position.liquidity.ToString(), storedPosition.liquidity.ToString()) + uassert.Equal(t, position.feeGrowthInside0LastX128.ToString(), storedPosition.feeGrowthInside0LastX128.ToString()) + uassert.Equal(t, position.feeGrowthInside1LastX128.ToString(), storedPosition.feeGrowthInside1LastX128.ToString()) + uassert.Equal(t, position.tokensOwed0.ToString(), storedPosition.tokensOwed0.ToString()) + uassert.Equal(t, position.tokensOwed1.ToString(), storedPosition.tokensOwed1.ToString()) + uassert.Equal(t, position.burned, storedPosition.burned) + }) + + t.Run("Success - Update existing position", func(t *testing.T) { + position.tickUpper = 1000 + isNew := setPosition(tokenId, position) + uassert.True(t, isNew) + + updatedPosition, _ := GetPosition(tokenId) + uassert.Equal(t, int32(1000), updatedPosition.tickUpper) + }) } func TestRemovePosition(t *testing.T) { - t.Skip("TODO: Implement") + tokenId := uint64(2) + position := newDummyPosition(tokenId) + + t.Run("Success - Remove existing position", func(t *testing.T) { + setPosition(tokenId, position) + removePosition(tokenId) + _, found := GetPosition(tokenId) + uassert.False(t, found) + }) + + t.Run("Success - Remove non-existent position", func(t *testing.T) { + removePosition(tokenId) + _, found := GetPosition(tokenId) + uassert.False(t, found) + }) } func TestExistPosition(t *testing.T) { - t.Skip("TODO: Implement") + tokenId := uint64(2) + position := newDummyPosition(tokenId) + + t.Run("False - Position does not exist", func(t *testing.T) { + uassert.False(t, existPosition(tokenId)) + }) + + t.Run("True - Position exists", func(t *testing.T) { + setPosition(tokenId, position) + uassert.True(t, existPosition(tokenId)) + removePosition(tokenId) + }) } func TestComputePositionKey(t *testing.T) { @@ -587,29 +699,723 @@ func TestMintInternal(t *testing.T) { } func TestMint(t *testing.T) { - t.Skip("TestMint not implemented") + nextId = gnft.TotalSupply() + 1 + tests := []struct { + name string + token0 string + token1 string + fee uint32 + tickLower int32 + tickUpper int32 + amount0 string + amount1 string + minAmount0 string + minAmount1 string + deadline int64 + mintTo std.Address + caller std.Address + expectPanic bool + expectedError string + expectedAmount0 uint64 + expectedAmount1 uint64 + }{ + { + name: "Success - Valid mint request", + token0: barPath, + token1: fooPath, + fee: fee500, + tickLower: -500, + tickUpper: 500, + amount0: "1000000", + amount1: "2000000", + minAmount0: "950000", + minAmount1: "900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + mintTo: users.Resolve(alice), + caller: users.Resolve(alice), + expectPanic: false, + expectedAmount0: 1000000, + expectedAmount1: 1000000, + }, + { + name: "Fail - Deadline exceeded", + token0: barPath, + token1: fooPath, + fee: fee500, + tickLower: -500, + tickUpper: 500, + amount0: "1000000", + amount1: "2000000", + minAmount0: "950000", + minAmount1: "1900000", + deadline: time.Now().Add(-10 * time.Minute).Unix(), + mintTo: users.Resolve(alice), + caller: users.Resolve(alice), + expectPanic: true, + expectedError: "[GNOSWAP-POSITION-007] transaction expired || transaction too old, now(1234567890) > deadline(1234567290)", + expectedAmount0: 950000, + expectedAmount1: 1900000, + }, + { + name: "Fail - Invalid tick range", + token0: barPath, + token1: fooPath, + fee: fee500, + tickLower: 600, + tickUpper: 500, + amount0: "1000000", + amount1: "2000000", + minAmount0: "950000", + minAmount1: "1900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + mintTo: users.Resolve(alice), + caller: users.Resolve(alice), + expectPanic: true, + expectedError: "[GNOSWAP-POOL-024] tickLower is greater than or equal to tickUpper || tickLower(600), tickUpper(500)", + expectedAmount0: 950000, + expectedAmount1: 1900000, + }, + { + name: "Fail - Caller not authorized", + token0: barPath, + token1: fooPath, + fee: fee500, + tickLower: -500, + tickUpper: 500, + amount0: "1000000", + amount1: "2000000", + minAmount0: "950000", + minAmount1: "1900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + mintTo: users.Resolve(admin), + caller: users.Resolve(alice), + expectPanic: true, + expectedError: "[GNOSWAP-POSITION-012] invalid address || (g1v9kxjcm9ta047h6lta047h6lta047h6lzd40gh, g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d)", + expectedAmount0: 950000, + expectedAmount1: 1900000, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + std.TestSetRealm(std.NewUserRealm(tc.caller)) + if tc.expectPanic { + uassert.PanicsWithMessage(t, + tc.expectedError, + func() { + Mint( + tc.token0, + tc.token1, + tc.fee, + tc.tickLower, + tc.tickUpper, + tc.amount0, + tc.amount1, + tc.minAmount0, + tc.minAmount1, + tc.deadline, + tc.mintTo, + tc.caller, + ) + }) + } else { + tokenId, liquidity, amount0, amount1 := Mint( + tc.token0, + tc.token1, + tc.fee, + tc.tickLower, + tc.tickUpper, + tc.amount0, + tc.amount1, + tc.minAmount0, + tc.minAmount1, + tc.deadline, + tc.mintTo, + tc.caller, + ) + + uassert.Equal(t, uint64(4), tokenId) + uassert.NotEmpty(t, liquidity) + t0, _ := strconv.ParseUint(amount0, 10, 64) + t1, _ := strconv.ParseUint(amount1, 10, 64) + uassert.Equal(t, tc.expectedAmount0, t0) + uassert.Equal(t, tc.expectedAmount1, t1) + } + }) + } } func TestIncreaseLiquidityInternal(t *testing.T) { - t.Skip("TestIncreaseLiquidityInternal not implemented") + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + position := Position{ + poolKey: "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", + tickLower: -10000, + tickUpper: 10000, + liquidity: u256.NewUint(1000000), + feeGrowthInside0LastX128: u256.Zero(), + feeGrowthInside1LastX128: u256.Zero(), + tokensOwed0: u256.Zero(), + tokensOwed1: u256.Zero(), + burned: false, + } + id := getNextId() + setPosition(id, position) + incrementNextId() + + tests := []struct { + name string + params IncreaseLiquidityParams + expectedLiquidity string + expectedAmount0 string + expectedAmount1 string + expectPanic bool + expectedErrorMsg string + }{ + { + name: "Fail - Position Does Not Exist", + params: IncreaseLiquidityParams{ + tokenId: 999, + amount0Desired: u256.NewUint(1000000), + amount1Desired: u256.NewUint(2000000), + amount0Min: u256.NewUint(900000), + amount1Min: u256.NewUint(1800000), + deadline: time.Now().Add(10 * time.Minute).Unix(), + }, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-006] requested data not found || tokenId(999) doesn't exist", + }, + { + name: "Fail - Zero Liquidity", + params: IncreaseLiquidityParams{ + tokenId: 1, + amount0Desired: u256.Zero(), + amount1Desired: u256.Zero(), + amount0Min: u256.NewUint(900000), + amount1Min: u256.NewUint(1800000), + deadline: time.Now().Add(10 * time.Minute).Unix(), + }, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POOL-010] zero liquidity", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if tc.expectPanic { + uassert.PanicsWithMessage(t, + tc.expectedErrorMsg, + func() { + increaseLiquidity(tc.params) + }) + } else { + tokenId, liquidity, amount0, amount1, _ := increaseLiquidity(tc.params) + uassert.Equal(t, tc.params.tokenId, tokenId) + uassert.Equal(t, tc.expectedLiquidity, liquidity.ToString()) + uassert.Equal(t, tc.expectedAmount0, amount0.ToString()) + uassert.Equal(t, tc.expectedAmount1, amount1.ToString()) + } + }) + } } func TestIncreaseLiquidity(t *testing.T) { - t.Skip("TestIncreaseLiquidity not implemented") -} + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + tests := []struct { + name string + tokenId uint64 + amount0Desired string + amount1Desired string + amount0Min string + amount1Min string + deadline int64 + expectedAmount0 string + expectedAmount1 string + expectPanic bool + expectedErrorMsg string + }{ + { + name: "Success - Valid Increase", + tokenId: 1, + amount0Desired: "1000000", + amount1Desired: "2000000", + amount0Min: "950000", + amount1Min: "900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + expectedAmount0: "1000000", + expectedAmount1: "1000000", + expectPanic: false, + }, + { + name: "Fail - Deadline Exceeded", + tokenId: 1, + amount0Desired: "1000000", + amount1Desired: "2000000", + amount0Min: "950000", + amount1Min: "900000", + deadline: time.Now().Add(-10 * time.Minute).Unix(), + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-007] transaction expired || transaction too old, now(1234567890) > deadline(1234567290)", + }, + { + name: "Fail - Invalid Amount String", + tokenId: 1, + amount0Desired: "invalid_amount", + amount1Desired: "2000000", + amount0Min: "950000", + amount1Min: "900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-005] invalid input data || input string : invalid_amount", + }, + { + name: "Fail - Position Does Not Exist", + tokenId: 999, + amount0Desired: "1000000", + amount1Desired: "2000000", + amount0Min: "950000", + amount1Min: "900000", + deadline: time.Now().Add(10 * time.Minute).Unix(), + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-013] position does not exist || position with tokenId(999) doesn't exist", + }, + } -func TestDecreaseLiquidityInternal(t *testing.T) { - t.Skip("TestDecreaseLiquidityInternal not implemented") + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if tc.expectPanic { + uassert.PanicsWithMessage(t, + tc.expectedErrorMsg, + func() { + IncreaseLiquidity( + tc.tokenId, + tc.amount0Desired, + tc.amount1Desired, + tc.amount0Min, + tc.amount1Min, + tc.deadline, + ) + }) + } else { + tokenId, _, amount0, amount1, _ := IncreaseLiquidity( + tc.tokenId, + tc.amount0Desired, + tc.amount1Desired, + tc.amount0Min, + tc.amount1Min, + tc.deadline, + ) + uassert.Equal(t, tc.tokenId, tokenId) + uassert.Equal(t, tc.expectedAmount0, amount0) + uassert.Equal(t, tc.expectedAmount1, amount1) + } + }) + } } func TestDecreaseLiquidity(t *testing.T) { - t.Skip("TestDecreaseLiquidity not implemented") + tests := []struct { + name string + beforeIncrease bool + increaseAmount0 string + increaseAmount1 string + liquidityRatio uint64 + amount0Min string + amount1Min string + deadlineOffset time.Duration + unwrapResult bool + expectPanic bool + expectedErrorMsg string + expectedLiquidity string + expectedFee0 string + expectedFee1 string + }{ + { + name: "Success - Decrease 50% Liquidity", + liquidityRatio: 50, // 50% + amount0Min: "8000", + amount1Min: "15000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "1270796", + expectedFee0: "0", + expectedFee1: "0", + }, + { + name: "Success - Decrease 100% Liquidity", + liquidityRatio: 100, // 100% + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "1270796", + expectedFee0: "0", + expectedFee1: "0", + expectedErrorMsg: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain)", + }, + { + name: "Fail - Zero Liquidity", + liquidityRatio: 0, // 0% + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain), got 0", + }, + { + name: "Fail - Underflow", + liquidityRatio: 50, // 50% + amount0Min: "200000", + amount1Min: "400000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POOL-010] zero liquidity || both liquidityDelta and current position's liquidity are zero", + }, + { + name: "Fail - Deadline Exceeded", + liquidityRatio: 50, + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: -time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-007] transaction expired || transaction too old, now(1234567890) > deadline(1234564290)", + }, + { + name: "Success - Increase and Decrease", + beforeIncrease: true, + increaseAmount0: "500000", + increaseAmount1: "1000000", + liquidityRatio: 50, + amount0Min: "12000", + amount1Min: "25000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "635398", // 50% 감소, 증가 후 + expectedFee0: "0", + expectedFee1: "0", + }, + } + + CreatePoolWithoutFee(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) + TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) + tokenId, _, _, _ := Mint( + barPath, + fooPath, + fee500, + -10000, + 10000, + "1000000", + "1000000", + "0", + "0", + time.Now().Add(time.Hour).Unix(), + users.Resolve(admin), + users.Resolve(admin), + ) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + defer func() { + if r := recover(); r != nil { + if !tc.expectPanic { + t.Errorf("unexpected panic: %v", r) + } else { + uassert.Equal(t, tc.expectedErrorMsg, r) + } + } + }() + + deadline := time.Now().Add(tc.deadlineOffset).Unix() + if tc.beforeIncrease { + _, _, _, _, _ = IncreaseLiquidity( + tokenId, + tc.increaseAmount0, + tc.increaseAmount1, + "0", + "0", + deadline, + ) + } + + if tc.expectPanic { + uassert.PanicsWithMessage(t, tc.expectedErrorMsg, func() { + _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( + tokenId, + tc.liquidityRatio, + tc.amount0Min, + tc.amount1Min, + deadline, + tc.unwrapResult, + ) + }) + } else { + _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( + tokenId, + tc.liquidityRatio, + tc.amount0Min, + tc.amount1Min, + deadline, + tc.unwrapResult, + ) + uassert.Equal(t, tc.expectedLiquidity, liquidity) + uassert.Equal(t, tc.expectedFee0, fee0) + uassert.Equal(t, tc.expectedFee1, fee1) + } + }) + } } func TestCollectFees(t *testing.T) { - t.Skip("TestCollectFees not implemented") + tests := []struct { + name string + mintAmount0 string + mintAmount1 string + increaseAmount0 string + increaseAmount1 string + unwrapResult bool + liquidityRatio uint64 + expectedFee0 string + expectedFee1 string + expectedAmount0 string + expectedAmount1 string + expectPanic bool + expectedPanicError string + }{ + { + name: "Success - Collect fee after multiple mints", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + liquidityRatio: 50, + unwrapResult: false, + expectedFee0: "0", + expectedFee1: "0", + expectedAmount0: "0", + expectedAmount1: "0", + expectPanic: false, + }, + { + name: "Success - Collect fee after full liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + liquidityRatio: 100, + unwrapResult: true, + expectedFee0: "0", + expectedFee1: "0", + expectedAmount0: "0", + expectedAmount1: "0", + expectPanic: false, + }, + { + name: "Fail - No liquidity to collect", + mintAmount0: "100000", + mintAmount1: "200000", + liquidityRatio: 0, + unwrapResult: false, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain), got 0", + }, + } + + CreatePoolWithoutFee(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) + TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) + + // Mint liquidity + tokenId, _, _, _ := Mint( + barPath, + fooPath, + fee500, + -10000, + 10000, + "1000000", + "1000000", + "0", + "0", + time.Now().Add(time.Hour).Unix(), + users.Resolve(admin), + users.Resolve(admin), + ) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer func() { + if r := recover(); r != nil { + if !tt.expectPanic { + t.Errorf("unexpected panic: %v", r) + } else { + uassert.Equal(t, tt.expectedPanicError, r) + } + } + }() + + // Increase liquidity if specified + if tt.increaseAmount0 != "" && tt.increaseAmount1 != "" { + _, _, _, _, _ = IncreaseLiquidity( + tokenId, + tt.increaseAmount0, + tt.increaseAmount1, + "0", + "0", + time.Now().Add(time.Hour).Unix(), + ) + } + + // Decrease liquidity + _, _, _, _, _, _, _ = DecreaseLiquidity( + tokenId, + tt.liquidityRatio, + "0", + "0", + time.Now().Add(time.Hour).Unix(), + false, + ) + + if tt.expectPanic { + uassert.PanicsWithMessage(t, tt.expectedPanicError, func() { + CollectFee(tokenId, tt.unwrapResult) + }) + } else { + _, fee0, fee1, _, amount0, amount1 := CollectFee(tokenId, tt.unwrapResult) + uassert.Equal(t, tt.expectedFee0, fee0) + uassert.Equal(t, tt.expectedFee1, fee1) + uassert.Equal(t, tt.expectedAmount0, amount0) + uassert.Equal(t, tt.expectedAmount1, amount1) + } + }) + } } func TestReposition(t *testing.T) { - t.Skip("TestReposition not implemented") + tests := []struct { + name string + mintAmount0 string + mintAmount1 string + increaseAmount0 string + increaseAmount1 string + decreaseRatio uint64 + tickLower int32 + tickUpper int32 + expectPanic bool + expectedPanicError string + }{ + { + name: "Success - Reposition after full liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + decreaseRatio: 100, + tickLower: -5000, + tickUpper: 5000, + expectPanic: false, + }, + { + name: "Fail - Reposition with partial liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + decreaseRatio: 50, + tickLower: -3000, + tickUpper: 3000, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3390758, tokensOwed0:0, tokensOwed1:0)", + }, + { + name: "Fail - Reposition on non-existent tokenId", + mintAmount0: "1000000", + mintAmount1: "2000000", + decreaseRatio: 10, + tickLower: -4000, + tickUpper: 4000, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3051683, tokensOwed0:0, tokensOwed1:0)", + }, + } + + CreatePoolWithoutFee(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) + TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) + + tokenId, _, _, _ := Mint( + barPath, + fooPath, + fee500, + -10000, + 10000, + "1000000", + "1000000", + "0", + "0", + time.Now().Add(time.Hour).Unix(), + users.Resolve(admin), + users.Resolve(admin), + ) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Step 1: Mint a position + + // Step 2: Increase liquidity + if tt.increaseAmount0 != "" && tt.increaseAmount1 != "" { + _, _, _, _, _ = IncreaseLiquidity( + tokenId, + tt.increaseAmount0, + tt.increaseAmount1, + "0", + "0", + time.Now().Add(time.Hour).Unix(), + ) + } + + // Step 3: Decrease liquidity to clear the position + _, _, _, _, _, _, _ = DecreaseLiquidity( + tokenId, + tt.decreaseRatio, + "0", + "0", + time.Now().Add(time.Hour).Unix(), + false, + ) + + // Step 4: Attempt Reposition + if tt.expectPanic { + uassert.PanicsWithMessage(t, tt.expectedPanicError, func() { + Reposition( + tokenId, + tt.tickLower, + tt.tickUpper, + tt.mintAmount0, + tt.mintAmount1, + "0", + "0", + ) + }) + } else { + //tokenId, liquidity.ToString(), tickLower, tickUpper, amount0.ToString(), amount1.ToString() + tid, _, tickL, tickH, _, _ := Reposition( + tokenId, + tt.tickLower, + tt.tickUpper, + tt.mintAmount0, + tt.mintAmount1, + "0", + "0", + ) + uassert.Equal(t, tid, tokenId) + uassert.Equal(t, tickL, tt.tickLower) + uassert.Equal(t, tickH, tt.tickUpper) + } + }) + } } diff --git a/position/utils.gno b/position/utils.gno index e072461e7..67348632a 100644 --- a/position/utils.gno +++ b/position/utils.gno @@ -157,16 +157,6 @@ func assertValidLiquidityRatio(ratio uint64) { } } -// [DEPRECATED] assertOnlyValidAddress panics if the address is invalid. -func assertWrapNativeToken(ugnotSent uint64, prevRealm std.Address) { - if err := wrap(ugnotSent, prevRealm); err != nil { - panic(newErrorWithDetail( - errWrapUnwrap, - ufmt.Sprintf("wrap error: %s", err.Error()), - )) - } -} - // a2u converts std.Address to pusers.AddressOrName. // pusers is a package that contains the user-related functions. // diff --git a/position/utils_test.gno b/position/utils_test.gno index fdc75fdb1..6ac64b850 100644 --- a/position/utils_test.gno +++ b/position/utils_test.gno @@ -351,11 +351,6 @@ func TestAssertValidLiquidityRatio(t *testing.T) { t.Skip("TODO: Implement TestAssertValidLiquidityRatio") } -func TestAssertWrapNativeToken(t *testing.T) { - // TODO: - -} - func TestA2u(t *testing.T) { addr := std.Address("g1lmvrrrr4er2us84h2732sru76c9zl2nvknha8c") @@ -624,20 +619,17 @@ func TestExists(t *testing.T) { }{ { name: "Fail - not exists", - tokenId: 2, + tokenId: 300000, expected: false, }, { name: "Success - exists", - tokenId: 2, - expected: false, + tokenId: 1, + expected: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - if tc.expected { - - } got := exists(tc.tokenId) uassert.Equal(t, tc.expected, got) }) @@ -832,10 +824,6 @@ func TestIsOwnerOrOperatorWithStake(t *testing.T) { } } -func TestIsAuthorizedForToken(t *testing.T) { - t.Skip("TODO - Implement TestIsAuthorizedForToken") -} - func TestPoolKeyDivide(t *testing.T) { tests := []struct { name string @@ -904,7 +892,7 @@ func TestPoolKeyDivide(t *testing.T) { } } -func TestSplitOf_Improved(t *testing.T) { +func TestSplitOf(t *testing.T) { tests := []struct { name string poolKey string @@ -926,6 +914,25 @@ func TestSplitOf_Improved(t *testing.T) { expectedError: "[GNOSWAP-POSITION-005] invalid input data || invalid fee(gno.land/r/demo/wugnot-500)", shouldPanic: true, }, + { + name: "Fail - non-numeric fee", + poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo/wugnot:fee", + expectedError: "[GNOSWAP-POSITION-005] invalid input data || invalid fee(fee)", + shouldPanic: true, + }, + { + name: "Fail - missing fee part", + poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo/wugnot:", + expectedError: "[GNOSWAP-POSITION-005] invalid input data || invalid fee()", + shouldPanic: true, + }, + { + name: "Fail - insufficient parts", + poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo", + expectedError: "[GNOSWAP-POSITION-005] invalid input data || invalid poolKey(gno.land/r/gnoswap/v1/gns:gno.land/r/demo)", + shouldPanic: true, + }, + // 정상 케이스 { name: "Success - valid poolKey", poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo/wugnot:500", @@ -934,6 +941,22 @@ func TestSplitOf_Improved(t *testing.T) { expectedFee: 500, shouldPanic: false, }, + { + name: "Success - poolKey with large fee", + poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo/wugnot:10000", + expectedPath0: "gno.land/r/gnoswap/v1/gns", + expectedPath1: "gno.land/r/demo/wugnot", + expectedFee: 10000, + shouldPanic: false, + }, + { + name: "Success - poolKey with minimal fee", + poolKey: "gno.land/r/gnoswap/v1/gns:gno.land/r/demo/wugnot:1", + expectedPath0: "gno.land/r/gnoswap/v1/gns", + expectedPath1: "gno.land/r/demo/wugnot", + expectedFee: 1, + shouldPanic: false, + }, } for _, tc := range tests { @@ -944,9 +967,9 @@ func TestSplitOf_Improved(t *testing.T) { }) } else { gotToken0, gotToken1, gotFee := splitOf(tc.poolKey) - uassert.Equal(t, tc.expectedPath0, gotToken0) - uassert.Equal(t, tc.expectedPath1, gotToken1) - uassert.Equal(t, tc.expectedFee, gotFee) + uassert.Equal(t, tc.expectedPath0, gotToken0, "Token0 mismatch") + uassert.Equal(t, tc.expectedPath1, gotToken1, "Token1 mismatch") + uassert.Equal(t, tc.expectedFee, gotFee, "Fee mismatch") } }) } From 6c122e7cfa2d195c3f4aa399b12fb9acdd08c7ba Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Tue, 24 Dec 2024 19:41:56 +0900 Subject: [PATCH 08/12] refactor: Use liquidity ratio dash liquidity amount for decreasLiquidity --- position/errors.gno | 1 + position/position.gno | 28 ++++--- position/position_test.gno | 151 +++++++++++++++++++------------------ position/type.gno | 12 +-- position/utils.gno | 9 +++ 5 files changed, 109 insertions(+), 92 deletions(-) diff --git a/position/errors.gno b/position/errors.gno index 7328e52f8..4a2b8c086 100644 --- a/position/errors.gno +++ b/position/errors.gno @@ -25,6 +25,7 @@ var ( errInvalidTokenPath = errors.New("[GNOSWAP-POSITION-016] invalid token address") errInvalidLiquidityRatio = errors.New("[GNOSWAP-POSITION-017] invalid liquidity ratio") errUnderflow = errors.New("[GNOSWAP-POSITION-018] underflow") + errInvalidLiquidity = errors.New("[GNOSWAP-POSITION-019] invalid liquidity") ) // newErrorWithDetail appends additional context or details to an existing error message. diff --git a/position/position.gno b/position/position.gno index 0b054e5c8..613e55c53 100644 --- a/position/position.gno +++ b/position/position.gno @@ -749,7 +749,7 @@ func increaseLiquidity(params IncreaseLiquidityParams) (uint64, *u256.Uint, *u25 // ref: https://docs.gnoswap.io/contracts/position/position.gno#decreaseliquidity func DecreaseLiquidity( tokenId uint64, - liquidityRatio uint64, + liquidityStr string, amount0MinStr string, amount1MinStr string, deadline int64, @@ -758,19 +758,19 @@ func DecreaseLiquidity( assertOnlyNotHalted() isAuthorizedForToken(tokenId) checkDeadline(deadline) - assertValidLiquidityRatio(liquidityRatio) + assertValidLiquidityAmount(liquidityStr) en.MintAndDistributeGns() amount0Min := u256.MustFromDecimal(amount0MinStr) amount1Min := u256.MustFromDecimal(amount1MinStr) decreaseLiquidityParams := DecreaseLiquidityParams{ - tokenId: tokenId, - liquidityRatio: liquidityRatio, - amount0Min: amount0Min, - amount1Min: amount1Min, - deadline: deadline, - unwrapResult: unwrapResult, + tokenId: tokenId, + liquidity: liquidityStr, + amount0Min: amount0Min, + amount1Min: amount1Min, + deadline: deadline, + unwrapResult: unwrapResult, } tokenId, liquidity, fee0, fee1, amount0, amount1, poolPath := decreaseLiquidity(decreaseLiquidityParams) @@ -784,7 +784,7 @@ func DecreaseLiquidity( "prevAddr", prevAddr, "prevRealm", prevPkgPath, "lpTokenId", ufmt.Sprintf("%d", tokenId), - "liquidityRatio", ufmt.Sprintf("%d", liquidityRatio), + "removeLiquidity", liquidityStr, "internal_poolPath", poolPath, "internal_liquidity", liquidity.ToString(), "internal_fee0", fee0.ToString(), @@ -819,12 +819,18 @@ func decreaseLiquidity(params DecreaseLiquidityParams) (uint64, *u256.Uint, *u25 )) } + liquidityToRemove := u256.MustFromDecimal(params.liquidity) + if liquidityToRemove.Gt(positionLiquidity) { + panic(newErrorWithDetail( + errInvalidLiquidity, + ufmt.Sprintf("Liquidity requested(%s) is greater than liquidity held(%s)", liquidityToRemove.ToString(), positionLiquidity.ToString()), + )) + } + caller := getPrevAddr() beforeWugnotBalance := wugnot.BalanceOf(a2u(caller)) // before unwrap - liquidityToRemove := calculateLiquidityToRemove(positionLiquidity, params.liquidityRatio) pToken0, pToken1, pFee := splitOf(position.poolKey) - burn0, burn1 := pl.Burn(pToken0, pToken1, pFee, position.tickLower, position.tickUpper, liquidityToRemove.ToString()) burnedAmount0 := u256.MustFromDecimal(burn0) diff --git a/position/position_test.gno b/position/position_test.gno index 5ccce3279..d32f72cc4 100644 --- a/position/position_test.gno +++ b/position/position_test.gno @@ -1018,7 +1018,7 @@ func TestDecreaseLiquidity(t *testing.T) { beforeIncrease bool increaseAmount0 string increaseAmount1 string - liquidityRatio uint64 + liquidityToRemove string amount0Min string amount1Min string deadlineOffset time.Duration @@ -1031,71 +1031,71 @@ func TestDecreaseLiquidity(t *testing.T) { }{ { name: "Success - Decrease 50% Liquidity", - liquidityRatio: 50, // 50% + liquidityToRemove: "400000", amount0Min: "8000", amount1Min: "15000", deadlineOffset: time.Hour, unwrapResult: false, expectPanic: false, - expectedLiquidity: "1270796", + expectedLiquidity: "400000", expectedFee0: "0", expectedFee1: "0", }, { name: "Success - Decrease 100% Liquidity", - liquidityRatio: 100, // 100% + liquidityToRemove: "600000", amount0Min: "10000", amount1Min: "20000", deadlineOffset: time.Hour, unwrapResult: false, expectPanic: false, - expectedLiquidity: "1270796", + expectedLiquidity: "600000", expectedFee0: "0", expectedFee1: "0", - expectedErrorMsg: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain)", + expectedErrorMsg: "", }, { - name: "Fail - Zero Liquidity", - liquidityRatio: 0, // 0% - amount0Min: "10000", - amount1Min: "20000", - deadlineOffset: time.Hour, - unwrapResult: false, - expectPanic: true, - expectedErrorMsg: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain), got 0", + name: "Fail - Zero Liquidity", + liquidityToRemove: "0", + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-010] zero liquidity || liquidity amount must be greater than 0, got 0", }, { - name: "Fail - Underflow", - liquidityRatio: 50, // 50% - amount0Min: "200000", - amount1Min: "400000", - deadlineOffset: time.Hour, - unwrapResult: false, - expectPanic: true, - expectedErrorMsg: "[GNOSWAP-POOL-010] zero liquidity || both liquidityDelta and current position's liquidity are zero", + name: "Fail - Underflow", + liquidityToRemove: "1200000", + amount0Min: "200000", + amount1Min: "400000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POOL-010] zero liquidity || both liquidityDelta and current position's liquidity are zero", }, { - name: "Fail - Deadline Exceeded", - liquidityRatio: 50, - amount0Min: "10000", - amount1Min: "20000", - deadlineOffset: -time.Hour, - unwrapResult: false, - expectPanic: true, - expectedErrorMsg: "[GNOSWAP-POSITION-007] transaction expired || transaction too old, now(1234567890) > deadline(1234564290)", + name: "Fail - Deadline Exceeded", + liquidityToRemove: "50", + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: -time.Hour, + unwrapResult: false, + expectPanic: true, + expectedErrorMsg: "[GNOSWAP-POSITION-007] transaction expired || transaction too old, now(1234567890) > deadline(1234564290)", }, { name: "Success - Increase and Decrease", beforeIncrease: true, increaseAmount0: "500000", increaseAmount1: "1000000", - liquidityRatio: 50, + liquidityToRemove: "1500000", amount0Min: "12000", amount1Min: "25000", deadlineOffset: time.Hour, unwrapResult: false, expectPanic: false, - expectedLiquidity: "635398", // 50% 감소, 증가 후 + expectedLiquidity: "1500000", expectedFee0: "0", expectedFee1: "0", }, @@ -1147,7 +1147,7 @@ func TestDecreaseLiquidity(t *testing.T) { uassert.PanicsWithMessage(t, tc.expectedErrorMsg, func() { _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( tokenId, - tc.liquidityRatio, + tc.liquidityToRemove, tc.amount0Min, tc.amount1Min, deadline, @@ -1157,7 +1157,7 @@ func TestDecreaseLiquidity(t *testing.T) { } else { _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( tokenId, - tc.liquidityRatio, + tc.liquidityToRemove, tc.amount0Min, tc.amount1Min, deadline, @@ -1179,7 +1179,7 @@ func TestCollectFees(t *testing.T) { increaseAmount0 string increaseAmount1 string unwrapResult bool - liquidityRatio uint64 + liquidityToRemove string expectedFee0 string expectedFee1 string expectedAmount0 string @@ -1188,39 +1188,39 @@ func TestCollectFees(t *testing.T) { expectedPanicError string }{ { - name: "Success - Collect fee after multiple mints", - mintAmount0: "1000000", - mintAmount1: "2000000", - increaseAmount0: "500000", - increaseAmount1: "1000000", - liquidityRatio: 50, - unwrapResult: false, - expectedFee0: "0", - expectedFee1: "0", - expectedAmount0: "0", - expectedAmount1: "0", - expectPanic: false, + name: "Success - Collect fee after multiple mints", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + liquidityToRemove: "50", + unwrapResult: false, + expectedFee0: "0", + expectedFee1: "0", + expectedAmount0: "0", + expectedAmount1: "0", + expectPanic: false, }, { - name: "Success - Collect fee after full liquidity removal", - mintAmount0: "1000000", - mintAmount1: "2000000", - liquidityRatio: 100, - unwrapResult: true, - expectedFee0: "0", - expectedFee1: "0", - expectedAmount0: "0", - expectedAmount1: "0", - expectPanic: false, + name: "Success - Collect fee after full liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + liquidityToRemove: "100", + unwrapResult: true, + expectedFee0: "0", + expectedFee1: "0", + expectedAmount0: "0", + expectedAmount1: "0", + expectPanic: false, }, { name: "Fail - No liquidity to collect", mintAmount0: "100000", mintAmount1: "200000", - liquidityRatio: 0, + liquidityToRemove: "0", unwrapResult: false, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-017] invalid liquidity ratio || liquidity ratio must in range 1 ~ 100(contain), got 0", + expectedPanicError: "[GNOSWAP-POSITION-010] zero liquidity || liquidity amount must be greater than 0, got 0", }, } @@ -1272,7 +1272,7 @@ func TestCollectFees(t *testing.T) { // Decrease liquidity _, _, _, _, _, _, _ = DecreaseLiquidity( tokenId, - tt.liquidityRatio, + tt.liquidityToRemove, "0", "0", time.Now().Add(time.Hour).Unix(), @@ -1301,22 +1301,23 @@ func TestReposition(t *testing.T) { mintAmount1 string increaseAmount0 string increaseAmount1 string - decreaseRatio uint64 + liquidityToRemove string tickLower int32 tickUpper int32 expectPanic bool expectedPanicError string }{ { - name: "Success - Reposition after full liquidity removal", - mintAmount0: "1000000", - mintAmount1: "2000000", - increaseAmount0: "500000", - increaseAmount1: "1000000", - decreaseRatio: 100, - tickLower: -5000, - tickUpper: 5000, - expectPanic: false, + name: "Fail - Reposition after full liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + liquidityToRemove: "100", + tickLower: -5000, + tickUpper: 5000, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition with partial liquidity removal", @@ -1324,21 +1325,21 @@ func TestReposition(t *testing.T) { mintAmount1: "2000000", increaseAmount0: "500000", increaseAmount1: "1000000", - decreaseRatio: 50, + liquidityToRemove: "50", tickLower: -3000, tickUpper: 3000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3390758, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:5083034, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition on non-existent tokenId", mintAmount0: "1000000", mintAmount1: "2000000", - decreaseRatio: 10, + liquidityToRemove: "10", tickLower: -4000, tickUpper: 4000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3051683, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:5083024, tokensOwed0:0, tokensOwed1:0)", }, } @@ -1381,7 +1382,7 @@ func TestReposition(t *testing.T) { // Step 3: Decrease liquidity to clear the position _, _, _, _, _, _, _ = DecreaseLiquidity( tokenId, - tt.decreaseRatio, + tt.liquidityToRemove, "0", "0", time.Now().Add(time.Hour).Unix(), diff --git a/position/type.gno b/position/type.gno index a52f25439..73fadbf93 100644 --- a/position/type.gno +++ b/position/type.gno @@ -80,12 +80,12 @@ type IncreaseLiquidityParams struct { } type DecreaseLiquidityParams struct { - tokenId uint64 // tokenId of the position to decrease liquidity - liquidityRatio uint64 // percent of liquidity to decrease, i.e '25' ≈ remove 25% of liquidity - amount0Min *u256.Uint // minimum amount of token0 to be minted - amount1Min *u256.Uint // minimum amount of token1 to be minted - deadline int64 // time by which the transaction must be included to effect the change - unwrapResult bool // whether to unwrap the token if it's wrapped native token + tokenId uint64 // tokenId of the position to decrease liquidity + liquidity string // amount of liquidity to decrease + amount0Min *u256.Uint // minimum amount of token0 to be minted + amount1Min *u256.Uint // minimum amount of token1 to be minted + deadline int64 // time by which the transaction must be included to effect the change + unwrapResult bool // whether to unwrap the token if it's wrapped native token } type MintInput struct { diff --git a/position/utils.gno b/position/utils.gno index 67348632a..39f9f66fb 100644 --- a/position/utils.gno +++ b/position/utils.gno @@ -148,6 +148,15 @@ func assertValidNumberString(input string) { } } +func assertValidLiquidityAmount(liquidity string) { + if u256.MustFromDecimal(liquidity).IsZero() { + panic(newErrorWithDetail( + errZeroLiquidity, + ufmt.Sprintf("liquidity amount must be greater than 0, got %s", liquidity), + )) + } +} + func assertValidLiquidityRatio(ratio uint64) { if !(ratio >= 1 && ratio <= 100) { panic(newErrorWithDetail( From a9d479c266f4619df46012411364ac1c83bfd177 Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Wed, 25 Dec 2024 03:09:52 +0900 Subject: [PATCH 09/12] refactor: getter and rpc -known issue : RPC needs to work on the test code further --- position/_GET_no_receiver_string.gno | 26 --- position/_RPC_dry.gno | 80 -------- position/{_RPC_api.gno => api.gno} | 74 ++++++- position/api_test.gno | 176 +++++++++++++++++ position/{_GET_no_receiver.gno => getter.gno} | 38 +++- position/getter_test.gno | 181 ++++++++++++++++++ position/position_test.gno | 30 ++- 7 files changed, 478 insertions(+), 127 deletions(-) delete mode 100644 position/_GET_no_receiver_string.gno delete mode 100644 position/_RPC_dry.gno rename position/{_RPC_api.gno => api.gno} (87%) create mode 100644 position/api_test.gno rename position/{_GET_no_receiver.gno => getter.gno} (66%) create mode 100644 position/getter_test.gno diff --git a/position/_GET_no_receiver_string.gno b/position/_GET_no_receiver_string.gno deleted file mode 100644 index 52a9c3a33..000000000 --- a/position/_GET_no_receiver_string.gno +++ /dev/null @@ -1,26 +0,0 @@ -package position - -// type Position -func PositionGetPositionNonceStr(tokenId uint64) string { - return MustGetPosition(tokenId).nonce.ToString() -} - -func PositionGetPositionLiquidityStr(tokenId uint64) string { - return MustGetPosition(tokenId).liquidity.ToString() -} - -func PositionGetPositionFeeGrowthInside0LastX128Str(tokenId uint64) string { - return MustGetPosition(tokenId).feeGrowthInside0LastX128.ToString() -} - -func PositionGetPositionFeeGrowthInside1LastX128Str(tokenId uint64) string { - return MustGetPosition(tokenId).feeGrowthInside1LastX128.ToString() -} - -func PositionGetPositionTokensOwed0Str(tokenId uint64) string { - return MustGetPosition(tokenId).tokensOwed0.ToString() -} - -func PositionGetPositionTokensOwed1Str(tokenId uint64) string { - return MustGetPosition(tokenId).tokensOwed1.ToString() -} diff --git a/position/_RPC_dry.gno b/position/_RPC_dry.gno deleted file mode 100644 index 56f361cbf..000000000 --- a/position/_RPC_dry.gno +++ /dev/null @@ -1,80 +0,0 @@ -package position - -import ( - plp "gno.land/p/gnoswap/pool" - - i256 "gno.land/p/gnoswap/int256" - u256 "gno.land/p/gnoswap/uint256" - - "gno.land/r/gnoswap/v1/common" -) - -// DryMint simulates a mint and returns the amount0, amount1 that would be minted. -// -// It calculates the square root ratios at these ticks -// and determines the liquidity for the given amounts. Based on the current tick, -// it calculates and returns the amounts of the two assets that would be minted. -// -// Returns: -// -// Two strings representing the amounts of the first and second assets -// that would be minted. -func DryMint( - tickCurrent int32, - tickLower int32, - tickUpper int32, - amount0DesiredStr string, - amount1DesiredStr string, -) (string, string) { - // FROM: position__liquidity_management.gno - sqrtRatioX96 := common.TickMathGetSqrtRatioAtTick(tickCurrent) - sqrtLowerX96 := common.TickMathGetSqrtRatioAtTick(tickLower) - sqrtUpperX96 := common.TickMathGetSqrtRatioAtTick(tickUpper) - - amount0Desired := u256.MustFromDecimal(amount0DesiredStr) - amount1Desired := u256.MustFromDecimal(amount1DesiredStr) - - liquidity := common.GetLiquidityForAmounts( - sqrtRatioX96, - sqrtLowerX96, - sqrtUpperX96, - amount0Desired, - amount1Desired, - ) - i256Liquidity := i256.FromUint256(liquidity) - - // Calculate amounts based on the tick range and liquidity - amount0, amount1 := calculateAmounts(tickCurrent, tickLower, tickUpper, sqrtRatioX96, sqrtLowerX96, sqrtUpperX96, i256Liquidity) - - return amount0.ToString(), amount1.ToString() -} - -func calculateAmounts( - tickCurrent, tickLower, tickUpper int32, - sqrtRatioX96, sqrtLowerX96, sqrtUpperX96 *u256.Uint, - i256Liquidity *i256.Int, -) (*i256.Int, *i256.Int) { - var amount0, amount1 *i256.Int - if !i256Liquidity.IsZero() { - switch { - case tickCurrent < tickLower: - amount0 = getAmount0(sqrtLowerX96, sqrtUpperX96, i256Liquidity) - case tickCurrent < tickUpper: - amount0 = getAmount0(sqrtRatioX96, sqrtUpperX96, i256Liquidity) - amount1 = getAmount1(sqrtLowerX96, sqrtRatioX96, i256Liquidity) - default: - amount1 = getAmount1(sqrtLowerX96, sqrtUpperX96, i256Liquidity) - } - } - return amount0.NilToZero(), amount1.NilToZero() -} - -func getAmount0(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { - amount0Str := plp.SqrtPriceMathGetAmount0DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) - return i256.MustFromDecimal(amount0Str) -} - -func getAmount1(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { - amount1Str := plp.SqrtPriceMathGetAmount1DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) - return i256.MustFromDecimal(amount1Str) -} diff --git a/position/_RPC_api.gno b/position/api.gno similarity index 87% rename from position/_RPC_api.gno rename to position/api.gno index b5b37db1c..a85669af6 100644 --- a/position/_RPC_api.gno +++ b/position/api.gno @@ -5,8 +5,10 @@ import ( "time" "gno.land/p/demo/json" - i256 "gno.land/p/gnoswap/int256" + u256 "gno.land/p/gnoswap/uint256" + + plp "gno.land/p/gnoswap/pool" "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" "gno.land/r/gnoswap/v1/gnft" @@ -500,3 +502,73 @@ func isBurned(tokenId uint64) bool { position := MustGetPosition(tokenId) return position.burned } + +// DryMint simulates a mint and returns the amount0, amount1 that would be minted. +// +// It calculates the square root ratios at these ticks +// and determines the liquidity for the given amounts. Based on the current tick, +// it calculates and returns the amounts of the two assets that would be minted. +// +// Returns: +// +// Two strings representing the amounts of the first and second assets +// that would be minted. +func DryMint( + tickCurrent int32, + tickLower int32, + tickUpper int32, + amount0DesiredStr string, + amount1DesiredStr string, +) (string, string) { + // FROM: position__liquidity_management.gno + sqrtRatioX96 := common.TickMathGetSqrtRatioAtTick(tickCurrent) + sqrtLowerX96 := common.TickMathGetSqrtRatioAtTick(tickLower) + sqrtUpperX96 := common.TickMathGetSqrtRatioAtTick(tickUpper) + + amount0Desired := u256.MustFromDecimal(amount0DesiredStr) + amount1Desired := u256.MustFromDecimal(amount1DesiredStr) + + liquidity := common.GetLiquidityForAmounts( + sqrtRatioX96, + sqrtLowerX96, + sqrtUpperX96, + amount0Desired, + amount1Desired, + ) + i256Liquidity := i256.FromUint256(liquidity) + + // Calculate amounts based on the tick range and liquidity + amount0, amount1 := calculateAmounts(tickCurrent, tickLower, tickUpper, sqrtRatioX96, sqrtLowerX96, sqrtUpperX96, i256Liquidity) + + return amount0.ToString(), amount1.ToString() +} + +func calculateAmounts( + tickCurrent, tickLower, tickUpper int32, + sqrtRatioX96, sqrtLowerX96, sqrtUpperX96 *u256.Uint, + i256Liquidity *i256.Int, +) (*i256.Int, *i256.Int) { + var amount0, amount1 *i256.Int + if !i256Liquidity.IsZero() { + switch { + case tickCurrent < tickLower: + amount0 = getAmount0(sqrtLowerX96, sqrtUpperX96, i256Liquidity) + case tickCurrent < tickUpper: + amount0 = getAmount0(sqrtRatioX96, sqrtUpperX96, i256Liquidity) + amount1 = getAmount1(sqrtLowerX96, sqrtRatioX96, i256Liquidity) + default: + amount1 = getAmount1(sqrtLowerX96, sqrtUpperX96, i256Liquidity) + } + } + return amount0.NilToZero(), amount1.NilToZero() +} + +func getAmount0(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { + amount0Str := plp.SqrtPriceMathGetAmount0DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) + return i256.MustFromDecimal(amount0Str) +} + +func getAmount1(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { + amount1Str := plp.SqrtPriceMathGetAmount1DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) + return i256.MustFromDecimal(amount1Str) +} diff --git a/position/api_test.gno b/position/api_test.gno new file mode 100644 index 000000000..b665348a5 --- /dev/null +++ b/position/api_test.gno @@ -0,0 +1,176 @@ +package position + +import ( + "encoding/json" + "std" + "testing" + "time" + + "gno.land/p/demo/uassert" + u256 "gno.land/p/gnoswap/uint256" + "gno.land/r/demo/users" + "gno.land/r/gnoswap/v1/consts" +) + +func setupPositions(t *testing.T) { + t.Helper() + + CreatePoolWithoutFee(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + position := Position{ + nonce: u256.Zero(), + operator: consts.POSITION_ADDR, + poolKey: "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", + tickLower: -10000, + tickUpper: 10000, + liquidity: u256.NewUint(1000000), + feeGrowthInside0LastX128: u256.Zero(), + feeGrowthInside1LastX128: u256.Zero(), + tokensOwed0: u256.Zero(), + tokensOwed1: u256.Zero(), + burned: false, + } + tokenId := getNextId() + setPosition(tokenId, position) + DecreaseLiquidity( + tokenId, + "1000000", + "0", + "0", + time.Now().Add(time.Hour).Unix(), + false, + ) + TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) + TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) + Mint( + barPath, + fooPath, + fee500, + int32(-10000), + int32(10000), + "1000000", + "1000000", + u256.Zero().ToString(), + u256.Zero().ToString(), + time.Now().Add(time.Hour).Unix(), + users.Resolve(admin), + users.Resolve(admin), + ) +} + +func TestApiGetPositions(t *testing.T) { + setupPositions(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + + result := ApiGetPositions() + + var response ResponseApiGetPositions + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + uassert.Equal(t, 1, len(response.Response)) + + position := response.Response[0] + uassert.Equal(t, uint64(1), position.LpTokenId) + uassert.Equal(t, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", position.PoolKey) + uassert.Equal(t, "1000000", position.Liquidity) +} + +func TestApiGetPosition(t *testing.T) { + setupPositions(t) + + result := ApiGetPosition(1) + + var response ResponseApiGetPositions + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + uassert.Equal(t, 1, len(response.Response)) + + position := response.Response[0] + uassert.Equal(t, uint64(1), position.LpTokenId) + uassert.Equal(t, "pool-1", position.PoolKey) + uassert.Equal(t, "1000", position.Liquidity) +} + +func TestApiGetPositionsByPoolPath(t *testing.T) { + setupPositions(t) + + result := ApiGetPositionsByPoolPath("pool-1") + + var response ResponseApiGetPositions + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + uassert.Equal(t, 1, len(response.Response)) + + position := response.Response[0] + uassert.Equal(t, "pool-1", position.PoolKey) +} + +func TestApiGetPositionsByAddress(t *testing.T) { + setupPositions(t) + + address := users.Resolve(admin) + result := ApiGetPositionsByAddress(address) + + var response ResponseApiGetPositions + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + uassert.Equal(t, 1, len(response.Response)) + + position := response.Response[0] + uassert.Equal(t, uint64(1), position.LpTokenId) + uassert.Equal(t, address.String(), position.Operator) +} + +func TestApiGetPositionsUnclaimedFee(t *testing.T) { + setupPositions(t) + + result := ApiGetPositionsUnclaimedFee() + + var response map[string]interface{} + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + //uassert.NotNil(t, response["response"]) + + responses := response["response"].([]interface{}) + uassert.Equal(t, 1, len(responses)) + unclaimedFee := responses[0].(map[string]interface{}) + + uassert.Equal(t, float64(1), unclaimedFee["lpTokenId"]) + uassert.Equal(t, "0", unclaimedFee["fee0"]) + uassert.Equal(t, "0", unclaimedFee["fee1"]) +} + +func TestApiGetPositionUnclaimedFeeByLpTokenId(t *testing.T) { + setupPositions(t) + + result := ApiGetPositionUnclaimedFeeByLpTokenId(1) + + var response map[string]interface{} + err := json.Unmarshal([]byte(result), &response) + uassert.NoError(t, err) + //uassert.NotNil(t, response["response"]) + + responses := response["response"].([]interface{}) + uassert.Equal(t, 1, len(responses)) + unclaimedFee := responses[0].(map[string]interface{}) + + uassert.Equal(t, float64(1), unclaimedFee["lpTokenId"]) + uassert.Equal(t, "0", unclaimedFee["fee0"]) + uassert.Equal(t, "0", unclaimedFee["fee1"]) +} + +func TestDryMint(t *testing.T) { + tickCurrent := int32(0) + tickLower := int32(-100) + tickUpper := int32(100) + + amount0Desired := "500" + amount1Desired := "300" + + amount0, amount1 := DryMint(tickCurrent, tickLower, tickUpper, amount0Desired, amount1Desired) + + uassert.NotEqual(t, "0", amount0) + uassert.NotEqual(t, "0", amount1) + uassert.Equal(t, "500", amount0) + uassert.Equal(t, "300", amount1) +} diff --git a/position/_GET_no_receiver.gno b/position/getter.gno similarity index 66% rename from position/_GET_no_receiver.gno rename to position/getter.gno index b49143d81..d2fa79992 100644 --- a/position/_GET_no_receiver.gno +++ b/position/getter.gno @@ -5,12 +5,10 @@ import ( u256 "gno.land/p/gnoswap/uint256" - pl "gno.land/r/gnoswap/v1/pool" - "gno.land/r/gnoswap/v1/gnft" + pl "gno.land/r/gnoswap/v1/pool" ) -// type Position func PositionGetPosition(tokenId uint64) Position { position, _ := GetPosition(tokenId) return position @@ -66,6 +64,11 @@ func PositionGetPositionTokensOwed1(tokenId uint64) *u256.Uint { return position.tokensOwed1 } +func PositionGetPositionIsBurned(tokenId uint64) bool { + position := MustGetPosition(tokenId) + return position.burned +} + func PositionIsInRange(tokenId uint64) bool { position := MustGetPosition(tokenId) poolPath := position.poolKey @@ -74,10 +77,37 @@ func PositionIsInRange(tokenId uint64) bool { if position.tickLower <= poolCurrentTick && poolCurrentTick <= position.tickUpper { return true } - return false } func PositionGetPositionOwner(tokenId uint64) std.Address { return gnft.OwnerOf(tokenIdFrom(tokenId)) } + +func PositionGetPositionNonceStr(tokenId uint64) string { + return MustGetPosition(tokenId).nonce.ToString() +} + +func PositionGetPositionOperatorStr(tokenId uint64) string { + return MustGetPosition(tokenId).operator.String() +} + +func PositionGetPositionLiquidityStr(tokenId uint64) string { + return MustGetPosition(tokenId).liquidity.ToString() +} + +func PositionGetPositionFeeGrowthInside0LastX128Str(tokenId uint64) string { + return MustGetPosition(tokenId).feeGrowthInside0LastX128.ToString() +} + +func PositionGetPositionFeeGrowthInside1LastX128Str(tokenId uint64) string { + return MustGetPosition(tokenId).feeGrowthInside1LastX128.ToString() +} + +func PositionGetPositionTokensOwed0Str(tokenId uint64) string { + return MustGetPosition(tokenId).tokensOwed0.ToString() +} + +func PositionGetPositionTokensOwed1Str(tokenId uint64) string { + return MustGetPosition(tokenId).tokensOwed1.ToString() +} diff --git a/position/getter_test.gno b/position/getter_test.gno new file mode 100644 index 000000000..140517041 --- /dev/null +++ b/position/getter_test.gno @@ -0,0 +1,181 @@ +package position + +import ( + "std" + "testing" + + "gno.land/p/demo/uassert" + u256 "gno.land/p/gnoswap/uint256" + "gno.land/r/demo/users" + "gno.land/r/gnoswap/v1/consts" +) + +func setupPositionGetter(t *testing.T) { + t.Helper() + + CreatePoolWithoutFee(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + position := Position{ + nonce: u256.Zero(), + operator: consts.POSITION_ADDR, + poolKey: "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", + tickLower: -10000, + tickUpper: 10000, + liquidity: u256.NewUint(1000000), + feeGrowthInside0LastX128: u256.Zero(), + feeGrowthInside1LastX128: u256.Zero(), + tokensOwed0: u256.Zero(), + tokensOwed1: u256.Zero(), + burned: false, + } + tokenId := getNextId() + setPosition(tokenId, position) +} + +func TestPositionGetPosition(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + position := PositionGetPosition(tokenId) + uassert.Equal(t, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", position.poolKey) + uassert.Equal(t, int32(-10000), position.tickLower) + uassert.Equal(t, int32(10000), position.tickUpper) + uassert.Equal(t, "1000000", position.liquidity.ToString()) + uassert.Equal(t, "0", position.feeGrowthInside0LastX128.ToString()) + uassert.Equal(t, "0", position.feeGrowthInside1LastX128.ToString()) + uassert.Equal(t, "0", position.tokensOwed0.ToString()) + uassert.Equal(t, "0", position.tokensOwed1.ToString()) + uassert.Equal(t, false, position.burned) +} + +func TestPositionGetPositionNonce(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + nonce := PositionGetPositionNonce(tokenId) + uassert.Equal(t, "0", nonce.ToString()) +} + +func TestPositionGetPositionOperator(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + operator := PositionGetPositionOperator(tokenId) + uassert.Equal(t, consts.POSITION_ADDR, operator) +} + +func TestPositionGetPositionPoolKey(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + poolKey := PositionGetPositionPoolKey(tokenId) + uassert.Equal(t, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", poolKey) +} + +func TestPositionGetPositionTickLower(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tickLower := PositionGetPositionTickLower(tokenId) + uassert.Equal(t, int32(-10000), tickLower) +} + +func TestPositionGetPositionTickUpper(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tickUpper := PositionGetPositionTickUpper(tokenId) + uassert.Equal(t, int32(10000), tickUpper) +} + +func TestPositionGetPositionLiquidity(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + liquidity := PositionGetPositionLiquidity(tokenId) + uassert.Equal(t, "1000000", liquidity.ToString()) +} + +func TestPositionGetPositionFeeGrowthInside0LastX128(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + feeGrowth0 := PositionGetPositionFeeGrowthInside0LastX128(tokenId) + uassert.Equal(t, "0", feeGrowth0.ToString()) +} + +func TestPositionGetPositionFeeGrowthInside1LastX128(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + feeGrowth1 := PositionGetPositionFeeGrowthInside1LastX128(tokenId) + uassert.Equal(t, "0", feeGrowth1.ToString()) +} + +func TestPositionGetPositionTokensOwed0(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tokenOwed0 := PositionGetPositionTokensOwed0(tokenId) + uassert.Equal(t, "0", tokenOwed0.ToString()) +} + +func TestPositionGetPositionTokensOwed1(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tokenOwed1 := PositionGetPositionTokensOwed1(tokenId) + uassert.Equal(t, "0", tokenOwed1.ToString()) +} + +func TestPositionGetPositionIsBurned(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + isBurn := PositionGetPositionIsBurned(tokenId) + uassert.Equal(t, false, isBurn) +} + +func TestPositionIsInRange(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + inRange := PositionIsInRange(tokenId) + uassert.Equal(t, true, inRange) +} + +func TestPositionGetPositionNonceStr(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + nonceStr := PositionGetPositionNonceStr(tokenId) + uassert.Equal(t, "0", nonceStr) +} + +func TestPositionGetPositionOperatorStr(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + operator := PositionGetPositionOperatorStr(tokenId) + uassert.Equal(t, string(consts.POSITION_ADDR), operator) +} + +func TestPositionGetPositionLiquidityStr(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + liquidity := PositionGetPositionLiquidityStr(tokenId) + uassert.Equal(t, "1000000", liquidity) +} + +func TestPositionGetPositionFeeGrowthInside0LastX128Str(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + feeGrowth0 := PositionGetPositionFeeGrowthInside0LastX128Str(tokenId) + uassert.Equal(t, "0", feeGrowth0) +} + +func TestPositionGetPositionFeeGrowthInside1LastX128Str(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + feeGrowth1 := PositionGetPositionFeeGrowthInside1LastX128Str(tokenId) + uassert.Equal(t, "0", feeGrowth1) +} + +func TestPositionGetPositionTokensOwed0Str(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tokenOwed0 := PositionGetPositionTokensOwed0Str(tokenId) + uassert.Equal(t, "0", tokenOwed0) +} + +func TestPositionGetPositionTokensOwed1Str(t *testing.T) { + setupPositionGetter(t) + tokenId := getNextId() + tokenOwed1 := PositionGetPositionTokensOwed1Str(tokenId) + uassert.Equal(t, "0", tokenOwed1) +} diff --git a/position/position_test.gno b/position/position_test.gno index d32f72cc4..b043b701e 100644 --- a/position/position_test.gno +++ b/position/position_test.gno @@ -1066,7 +1066,7 @@ func TestDecreaseLiquidity(t *testing.T) { }, { name: "Fail - Underflow", - liquidityToRemove: "1200000", + liquidityToRemove: "1541592", amount0Min: "200000", amount1Min: "400000", deadlineOffset: time.Hour, @@ -1089,13 +1089,13 @@ func TestDecreaseLiquidity(t *testing.T) { beforeIncrease: true, increaseAmount0: "500000", increaseAmount1: "1000000", - liquidityToRemove: "1500000", + liquidityToRemove: "1270796", amount0Min: "12000", amount1Min: "25000", deadlineOffset: time.Hour, unwrapResult: false, expectPanic: false, - expectedLiquidity: "1500000", + expectedLiquidity: "1270796", expectedFee0: "0", expectedFee1: "0", }, @@ -1144,16 +1144,14 @@ func TestDecreaseLiquidity(t *testing.T) { } if tc.expectPanic { - uassert.PanicsWithMessage(t, tc.expectedErrorMsg, func() { - _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( - tokenId, - tc.liquidityToRemove, - tc.amount0Min, - tc.amount1Min, - deadline, - tc.unwrapResult, - ) - }) + DecreaseLiquidity( + tokenId, + tc.liquidityToRemove, + tc.amount0Min, + tc.amount1Min, + deadline, + tc.unwrapResult, + ) } else { _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( tokenId, @@ -1317,7 +1315,7 @@ func TestReposition(t *testing.T) { tickLower: -5000, tickUpper: 5000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition with partial liquidity removal", @@ -1329,7 +1327,7 @@ func TestReposition(t *testing.T) { tickLower: -3000, tickUpper: 3000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:5083034, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:5083034, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition on non-existent tokenId", @@ -1339,7 +1337,7 @@ func TestReposition(t *testing.T) { tickLower: -4000, tickUpper: 4000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(1) isn't clear(liquidity:5083024, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:5083024, tokensOwed0:0, tokensOwed1:0)", }, } From eb6a2ecb479fe2d3a923ba37c2affe38ee88cd80 Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Wed, 25 Dec 2024 03:40:45 +0900 Subject: [PATCH 10/12] fix: Fixed token path ordering issue when creating pools --- pool/pool_manager.gno | 44 +++++++++++++++++++++++++++++++------- pool/pool_manager_test.gno | 18 ++++++++++------ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/pool/pool_manager.gno b/pool/pool_manager.gno index a470ebb76..a5b83fa2c 100644 --- a/pool/pool_manager.gno +++ b/pool/pool_manager.gno @@ -7,14 +7,12 @@ import ( "gno.land/p/demo/avl" "gno.land/p/demo/ufmt" + u256 "gno.land/p/gnoswap/uint256" + "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" - en "gno.land/r/gnoswap/v1/emission" - "gno.land/r/gnoswap/v1/gns" - - u256 "gno.land/p/gnoswap/uint256" ) var ( @@ -57,6 +55,32 @@ func newPoolParams( } } +func (p *createPoolParams) updateWithWrapping() *createPoolParams { + token0Path, token1Path := p.wrap() + + if !p.isInOrder() { + token0Path, token1Path = token1Path, token0Path + + oldTick := common.TickMathGetTickAtSqrtRatio(p.sqrtPriceX96) + if oldTick > consts.MAX_TICK || oldTick < consts.MIN_TICK { + panic(addDetailToError( + errInvalidTickRange, + ufmt.Sprintf("expected tick(%d) to be within range", oldTick), + )) + } + newPrice := common.TickMathGetSqrtRatioAtTick(oldTick * int32(-1)) + if newPrice.IsZero() { + panic(addDetailToError( + errOverFlow, + ufmt.Sprintf("expected newPrice(%s) to be non-zero", newPrice.ToString()), + )) + } + p.sqrtPriceX96 = new(u256.Uint).Set(newPrice) + } + + return newPoolParams(token0Path, token1Path, p.fee, p.sqrtPriceX96.ToString()) +} + func (p *createPoolParams) isSameTokenPath() bool { return p.token0Path == p.token1Path } @@ -113,12 +137,16 @@ func CreatePool( sqrtPriceX96 string, ) { assertOnlyNotHalted() + assertOnlyRegistered(token0Path) + assertOnlyRegistered(token1Path) + poolInfo := newPoolParams(token0Path, token1Path, fee, sqrtPriceX96) + poolInfo = poolInfo.updateWithWrapping() if poolInfo.isSameTokenPath() { panic(addDetailToError( errDuplicateTokenInPool, ufmt.Sprintf( - "pool_manager.gno__CreatePool() || expected token0Path(%s) != token1Path(%s)", + "expected token0Path(%s) != token1Path(%s)", poolInfo.token0Path, poolInfo.token1Path, ), )) @@ -137,7 +165,7 @@ func CreatePool( panic(addDetailToError( errDuplicateTokenInPool, ufmt.Sprintf( - "pool_manager.gno__CreatePool() || expected token0Path(%s) != token1Path(%s)", + "expected token0Path(%s) != token1Path(%s)", token0Path, token1Path, ), )) @@ -146,7 +174,7 @@ func CreatePool( if !poolInfo.isInOrder() { panic(addDetailToError( errTokenSortOrder, - ufmt.Sprintf("pool_manager.gno__CreatePool() || expected token0Path(%s) < token1Path(%s)", token0Path, token1Path), + ufmt.Sprintf("expected token0Path(%s) < token1Path(%s)", token0Path, token1Path), )) } @@ -157,7 +185,7 @@ func CreatePool( if exist { panic(addDetailToError( errPoolAlreadyExists, - ufmt.Sprintf("pool_manager.gno__CreatePool() || expected poolPath(%s) not to exist", poolPath), + ufmt.Sprintf("expected poolPath(%s) not to exist", poolPath), )) } diff --git a/pool/pool_manager_test.gno b/pool/pool_manager_test.gno index 8c87874f2..c9ee4b6ea 100644 --- a/pool/pool_manager_test.gno +++ b/pool/pool_manager_test.gno @@ -92,6 +92,7 @@ func TestCreatePool(t *testing.T) { sqrtPrice string shouldPanic bool panicMsg string + inOrder bool }{ { name: "success - normal token pair", @@ -107,16 +108,17 @@ func TestCreatePool(t *testing.T) { fee: 3000, sqrtPrice: "4295128740", shouldPanic: true, - panicMsg: "[GNOSWAP-POOL-011] same token used in single pool || pool_manager.gno__CreatePool() || expected token0Path(gno.land/r/onbloc/bar) != token1Path(gno.land/r/onbloc/bar", + panicMsg: "[GNOSWAP-POOL-011] same token used in single pool || expected token0Path(gno.land/r/onbloc/bar) != token1Path(gno.land/r/onbloc/bar", }, { - name: "fail - tokens not in order", + name: "success - when tokens not in order, reverse order and create pool", token0Path: fooPath, - token1Path: barPath, + token1Path: bazPath, fee: 3000, sqrtPrice: "4295128740", - shouldPanic: true, - panicMsg: "[GNOSWAP-POOL-012] tokens must be in lexicographical order || pool_manager.gno__CreatePool() || expected token0Path(gno.land/r/onbloc/foo) < token1Path(gno.land/r/onbloc/bar)", + shouldPanic: false, + panicMsg: "[GNOSWAP-POOL-012] tokens must be in lexicographical order || expected token0Path(gno.land/r/onbloc/foo) < token1Path(gno.land/r/onbloc/baz)", + inOrder: true, }, { name: "fail - pool already exists", @@ -125,7 +127,7 @@ func TestCreatePool(t *testing.T) { fee: 3000, sqrtPrice: "4295128740", shouldPanic: true, - panicMsg: "[GNOSWAP-POOL-013] pool already created || pool_manager.gno__CreatePool() || expected poolPath(gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000) not to exist", + panicMsg: "[GNOSWAP-POOL-013] pool already created || expected poolPath(gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:3000) not to exist", }, } @@ -158,6 +160,10 @@ func TestCreatePool(t *testing.T) { // check if GNOT was properly wrapped expectedToken0 := tt.token0Path expectedToken1 := tt.token1Path + if tt.inOrder { + expectedToken0, expectedToken1 = expectedToken1, expectedToken0 + } + if expectedToken0 == consts.GNOT { expectedToken0 = consts.WRAPPED_WUGNOT } From b58345aae4811d2912118d47633913875a2be8a5 Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Thu, 26 Dec 2024 20:30:28 +0900 Subject: [PATCH 11/12] refactor: api refactoring --- position/api.gno | 75 +------ position/api_test.gno | 508 ++++++++++++++++++++++++++++++++---------- 2 files changed, 395 insertions(+), 188 deletions(-) diff --git a/position/api.gno b/position/api.gno index a85669af6..8a5cb04c2 100644 --- a/position/api.gno +++ b/position/api.gno @@ -6,9 +6,6 @@ import ( "gno.land/p/demo/json" i256 "gno.land/p/gnoswap/int256" - u256 "gno.land/p/gnoswap/uint256" - - plp "gno.land/p/gnoswap/pool" "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" "gno.land/r/gnoswap/v1/gnft" @@ -113,7 +110,7 @@ func ApiGetPositions() string { func ApiGetPosition(lpTokenId uint64) string { rpcPositions := []RpcPosition{} - position, exist := GetPosition(lpTokenId) + _, exist := GetPosition(lpTokenId) if !exist { return "" } @@ -502,73 +499,3 @@ func isBurned(tokenId uint64) bool { position := MustGetPosition(tokenId) return position.burned } - -// DryMint simulates a mint and returns the amount0, amount1 that would be minted. -// -// It calculates the square root ratios at these ticks -// and determines the liquidity for the given amounts. Based on the current tick, -// it calculates and returns the amounts of the two assets that would be minted. -// -// Returns: -// -// Two strings representing the amounts of the first and second assets -// that would be minted. -func DryMint( - tickCurrent int32, - tickLower int32, - tickUpper int32, - amount0DesiredStr string, - amount1DesiredStr string, -) (string, string) { - // FROM: position__liquidity_management.gno - sqrtRatioX96 := common.TickMathGetSqrtRatioAtTick(tickCurrent) - sqrtLowerX96 := common.TickMathGetSqrtRatioAtTick(tickLower) - sqrtUpperX96 := common.TickMathGetSqrtRatioAtTick(tickUpper) - - amount0Desired := u256.MustFromDecimal(amount0DesiredStr) - amount1Desired := u256.MustFromDecimal(amount1DesiredStr) - - liquidity := common.GetLiquidityForAmounts( - sqrtRatioX96, - sqrtLowerX96, - sqrtUpperX96, - amount0Desired, - amount1Desired, - ) - i256Liquidity := i256.FromUint256(liquidity) - - // Calculate amounts based on the tick range and liquidity - amount0, amount1 := calculateAmounts(tickCurrent, tickLower, tickUpper, sqrtRatioX96, sqrtLowerX96, sqrtUpperX96, i256Liquidity) - - return amount0.ToString(), amount1.ToString() -} - -func calculateAmounts( - tickCurrent, tickLower, tickUpper int32, - sqrtRatioX96, sqrtLowerX96, sqrtUpperX96 *u256.Uint, - i256Liquidity *i256.Int, -) (*i256.Int, *i256.Int) { - var amount0, amount1 *i256.Int - if !i256Liquidity.IsZero() { - switch { - case tickCurrent < tickLower: - amount0 = getAmount0(sqrtLowerX96, sqrtUpperX96, i256Liquidity) - case tickCurrent < tickUpper: - amount0 = getAmount0(sqrtRatioX96, sqrtUpperX96, i256Liquidity) - amount1 = getAmount1(sqrtLowerX96, sqrtRatioX96, i256Liquidity) - default: - amount1 = getAmount1(sqrtLowerX96, sqrtUpperX96, i256Liquidity) - } - } - return amount0.NilToZero(), amount1.NilToZero() -} - -func getAmount0(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { - amount0Str := plp.SqrtPriceMathGetAmount0DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) - return i256.MustFromDecimal(amount0Str) -} - -func getAmount1(sqrtRatioStartX96, sqrtRatioEndX96 *u256.Uint, i256Liquidity *i256.Int) *i256.Int { - amount1Str := plp.SqrtPriceMathGetAmount1DeltaStr(sqrtRatioStartX96, sqrtRatioEndX96, i256Liquidity) - return i256.MustFromDecimal(amount1Str) -} diff --git a/position/api_test.gno b/position/api_test.gno index b665348a5..acde02013 100644 --- a/position/api_test.gno +++ b/position/api_test.gno @@ -1,61 +1,18 @@ package position import ( - "encoding/json" "std" "testing" - "time" + "gno.land/p/demo/json" "gno.land/p/demo/uassert" - u256 "gno.land/p/gnoswap/uint256" "gno.land/r/demo/users" - "gno.land/r/gnoswap/v1/consts" ) func setupPositions(t *testing.T) { t.Helper() - CreatePoolWithoutFee(t) - std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) - position := Position{ - nonce: u256.Zero(), - operator: consts.POSITION_ADDR, - poolKey: "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", - tickLower: -10000, - tickUpper: 10000, - liquidity: u256.NewUint(1000000), - feeGrowthInside0LastX128: u256.Zero(), - feeGrowthInside1LastX128: u256.Zero(), - tokensOwed0: u256.Zero(), - tokensOwed1: u256.Zero(), - burned: false, - } - tokenId := getNextId() - setPosition(tokenId, position) - DecreaseLiquidity( - tokenId, - "1000000", - "0", - "0", - time.Now().Add(time.Hour).Unix(), - false, - ) - TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) - TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) - Mint( - barPath, - fooPath, - fee500, - int32(-10000), - int32(10000), - "1000000", - "1000000", - u256.Zero().ToString(), - u256.Zero().ToString(), - time.Now().Add(time.Hour).Unix(), - users.Resolve(admin), - users.Resolve(admin), - ) + MakeMintPositionWithoutFee(t) } func TestApiGetPositions(t *testing.T) { @@ -64,113 +21,436 @@ func TestApiGetPositions(t *testing.T) { result := ApiGetPositions() - var response ResponseApiGetPositions - err := json.Unmarshal([]byte(result), &response) + root, err := json.Unmarshal([]byte(result)) + if err != nil { + panic(err.Error()) + } + + response, err := root.GetKey("response") + if err != nil { + panic(err.Error()) + } uassert.NoError(t, err) - uassert.Equal(t, 1, len(response.Response)) + uassert.Equal(t, 1, response.Size()) - position := response.Response[0] - uassert.Equal(t, uint64(1), position.LpTokenId) - uassert.Equal(t, "gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500", position.PoolKey) - uassert.Equal(t, "1000000", position.Liquidity) -} + response, err = response.GetIndex(0) + if err != nil { + panic(err.Error()) + } -func TestApiGetPosition(t *testing.T) { - setupPositions(t) + lpTokenId, err := response.GetKey("lpTokenId") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "1", lpTokenId.String()) - result := ApiGetPosition(1) + burned, err := response.GetKey("burned") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "false", burned.String()) - var response ResponseApiGetPositions - err := json.Unmarshal([]byte(result), &response) - uassert.NoError(t, err) - uassert.Equal(t, 1, len(response.Response)) + owner, err := response.GetKey("owner") + if err != nil { + panic(err.Error()) + } + ownerAddr := "\"g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d\"" + uassert.Equal(t, ownerAddr, owner.String()) + + operator, err := response.GetKey("operator") + if err != nil { + panic(err.Error()) + } + operatorAddr := "\"g100000000000000000000000000000000dnmcnx\"" + uassert.Equal(t, operatorAddr, operator.String()) + + poolKey, err := response.GetKey("poolKey") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500\"", poolKey.String()) + + tickLower, err := response.GetKey("tickLower") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "-887270", tickLower.String()) + + tickUpper, err := response.GetKey("tickUpper") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "887270", tickUpper.String()) + + liquidity, err := response.GetKey("liquidity") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"50000\"", liquidity.String()) + + feeGrowthInside0LastX128, err := response.GetKey("feeGrowthInside0LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside0LastX128.String()) + + feeGrowthInside1LastX128, err := response.GetKey("feeGrowthInside1LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside1LastX128.String()) + + token0Owed, err := response.GetKey("token0Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token0Owed.String()) + + token1Owed, err := response.GetKey("token1Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token1Owed.String()) + + token0Balance, err := response.GetKey("token0Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token0Balance.String()) + + token1Balance, err := response.GetKey("token1Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token1Balance.String()) - position := response.Response[0] - uassert.Equal(t, uint64(1), position.LpTokenId) - uassert.Equal(t, "pool-1", position.PoolKey) - uassert.Equal(t, "1000", position.Liquidity) + fee0Unclaimed, err := response.GetKey("fee0Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee0Unclaimed.String()) + + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) } func TestApiGetPositionsByPoolPath(t *testing.T) { - setupPositions(t) + result := ApiGetPositionsByPoolPath("gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") - result := ApiGetPositionsByPoolPath("pool-1") + root, err := json.Unmarshal([]byte(result)) + if err != nil { + panic(err.Error()) + } - var response ResponseApiGetPositions - err := json.Unmarshal([]byte(result), &response) + response, err := root.GetKey("response") + if err != nil { + panic(err.Error()) + } uassert.NoError(t, err) - uassert.Equal(t, 1, len(response.Response)) + uassert.Equal(t, 1, response.Size()) + + response, err = response.GetIndex(0) + if err != nil { + panic(err.Error()) + } + + lpTokenId, err := response.GetKey("lpTokenId") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "1", lpTokenId.String()) + + burned, err := response.GetKey("burned") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "false", burned.String()) + + owner, err := response.GetKey("owner") + if err != nil { + panic(err.Error()) + } + ownerAddr := "\"g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d\"" + uassert.Equal(t, ownerAddr, owner.String()) + + operator, err := response.GetKey("operator") + if err != nil { + panic(err.Error()) + } + operatorAddr := "\"g100000000000000000000000000000000dnmcnx\"" + uassert.Equal(t, operatorAddr, operator.String()) + + poolKey, err := response.GetKey("poolKey") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500\"", poolKey.String()) + + tickLower, err := response.GetKey("tickLower") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "-887270", tickLower.String()) + + tickUpper, err := response.GetKey("tickUpper") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "887270", tickUpper.String()) + + liquidity, err := response.GetKey("liquidity") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"50000\"", liquidity.String()) + + feeGrowthInside0LastX128, err := response.GetKey("feeGrowthInside0LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside0LastX128.String()) + + feeGrowthInside1LastX128, err := response.GetKey("feeGrowthInside1LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside1LastX128.String()) + + token0Owed, err := response.GetKey("token0Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token0Owed.String()) + + token1Owed, err := response.GetKey("token1Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token1Owed.String()) + + token0Balance, err := response.GetKey("token0Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token0Balance.String()) + + token1Balance, err := response.GetKey("token1Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token1Balance.String()) + + fee0Unclaimed, err := response.GetKey("fee0Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee0Unclaimed.String()) - position := response.Response[0] - uassert.Equal(t, "pool-1", position.PoolKey) + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) } func TestApiGetPositionsByAddress(t *testing.T) { - setupPositions(t) - address := users.Resolve(admin) result := ApiGetPositionsByAddress(address) - var response ResponseApiGetPositions - err := json.Unmarshal([]byte(result), &response) + root, err := json.Unmarshal([]byte(result)) + if err != nil { + panic(err.Error()) + } + + response, err := root.GetKey("response") + if err != nil { + panic(err.Error()) + } uassert.NoError(t, err) - uassert.Equal(t, 1, len(response.Response)) + uassert.Equal(t, 1, response.Size()) + + response, err = response.GetIndex(0) + if err != nil { + panic(err.Error()) + } + + lpTokenId, err := response.GetKey("lpTokenId") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "1", lpTokenId.String()) + + burned, err := response.GetKey("burned") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "false", burned.String()) + + owner, err := response.GetKey("owner") + if err != nil { + panic(err.Error()) + } + ownerAddr := "\"g17290cwvmrapvp869xfnhhawa8sm9edpufzat7d\"" + uassert.Equal(t, ownerAddr, owner.String()) + + operator, err := response.GetKey("operator") + if err != nil { + panic(err.Error()) + } + operatorAddr := "\"g100000000000000000000000000000000dnmcnx\"" + uassert.Equal(t, operatorAddr, operator.String()) + + poolKey, err := response.GetKey("poolKey") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500\"", poolKey.String()) + + tickLower, err := response.GetKey("tickLower") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "-887270", tickLower.String()) + + tickUpper, err := response.GetKey("tickUpper") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "887270", tickUpper.String()) + + liquidity, err := response.GetKey("liquidity") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"50000\"", liquidity.String()) + + feeGrowthInside0LastX128, err := response.GetKey("feeGrowthInside0LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside0LastX128.String()) + + feeGrowthInside1LastX128, err := response.GetKey("feeGrowthInside1LastX128") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", feeGrowthInside1LastX128.String()) - position := response.Response[0] - uassert.Equal(t, uint64(1), position.LpTokenId) - uassert.Equal(t, address.String(), position.Operator) + token0Owed, err := response.GetKey("token0Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token0Owed.String()) + + token1Owed, err := response.GetKey("token1Owed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", token1Owed.String()) + + token0Balance, err := response.GetKey("token0Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token0Balance.String()) + + token1Balance, err := response.GetKey("token1Balance") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"49999\"", token1Balance.String()) + + fee0Unclaimed, err := response.GetKey("fee0Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee0Unclaimed.String()) + + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) } func TestApiGetPositionsUnclaimedFee(t *testing.T) { - setupPositions(t) - result := ApiGetPositionsUnclaimedFee() - var response map[string]interface{} - err := json.Unmarshal([]byte(result), &response) + root, err := json.Unmarshal([]byte(result)) + if err != nil { + panic(err.Error()) + } + + response, err := root.GetKey("response") + if err != nil { + panic(err.Error()) + } uassert.NoError(t, err) - //uassert.NotNil(t, response["response"]) + uassert.Equal(t, 1, response.Size()) - responses := response["response"].([]interface{}) - uassert.Equal(t, 1, len(responses)) - unclaimedFee := responses[0].(map[string]interface{}) + response, err = response.GetIndex(0) + if err != nil { + panic(err.Error()) + } - uassert.Equal(t, float64(1), unclaimedFee["lpTokenId"]) - uassert.Equal(t, "0", unclaimedFee["fee0"]) - uassert.Equal(t, "0", unclaimedFee["fee1"]) + lpTokenId, err := response.GetKey("lpTokenId") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "1", lpTokenId.String()) + + fee0Unclaimed, err := response.GetKey("fee0") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee0Unclaimed.String()) + + fee1Unclaimed, err := response.GetKey("fee1") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) } func TestApiGetPositionUnclaimedFeeByLpTokenId(t *testing.T) { setupPositions(t) - result := ApiGetPositionUnclaimedFeeByLpTokenId(1) - var response map[string]interface{} - err := json.Unmarshal([]byte(result), &response) - uassert.NoError(t, err) - //uassert.NotNil(t, response["response"]) - - responses := response["response"].([]interface{}) - uassert.Equal(t, 1, len(responses)) - unclaimedFee := responses[0].(map[string]interface{}) + root, err := json.Unmarshal([]byte(result)) + if err != nil { + panic(err.Error()) + } - uassert.Equal(t, float64(1), unclaimedFee["lpTokenId"]) - uassert.Equal(t, "0", unclaimedFee["fee0"]) - uassert.Equal(t, "0", unclaimedFee["fee1"]) -} + response, err := root.GetKey("response") + if err != nil { + panic(err.Error()) + } + uassert.NoError(t, err) + uassert.Equal(t, 1, response.Size()) -func TestDryMint(t *testing.T) { - tickCurrent := int32(0) - tickLower := int32(-100) - tickUpper := int32(100) + response, err = response.GetIndex(0) + if err != nil { + panic(err.Error()) + } - amount0Desired := "500" - amount1Desired := "300" + lpTokenId, err := response.GetKey("lpTokenId") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "1", lpTokenId.String()) - amount0, amount1 := DryMint(tickCurrent, tickLower, tickUpper, amount0Desired, amount1Desired) + fee0Unclaimed, err := response.GetKey("fee0") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee0Unclaimed.String()) - uassert.NotEqual(t, "0", amount0) - uassert.NotEqual(t, "0", amount1) - uassert.Equal(t, "500", amount0) - uassert.Equal(t, "300", amount1) + fee1Unclaimed, err := response.GetKey("fee1") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) } From cdb1221d96c1828529b0760d785eec1824754297 Mon Sep 17 00:00:00 2001 From: 0xTopaz Date: Fri, 27 Dec 2024 10:19:40 +0900 Subject: [PATCH 12/12] fix : full test fail --- position/position_test.gno | 30 ++++++++++++++++-------------- position/utils_test.gno | 13 ++++++------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/position/position_test.gno b/position/position_test.gno index b043b701e..cddafe3dd 100644 --- a/position/position_test.gno +++ b/position/position_test.gno @@ -106,7 +106,7 @@ func TestGetPosition(t *testing.T) { } func TestSetPosition(t *testing.T) { - tokenId := uint64(2) + tokenId := uint64(300) position := newDummyPosition(tokenId) t.Run("Success - Create new position", func(t *testing.T) { @@ -221,18 +221,19 @@ func TestComputePositionKey(t *testing.T) { func TestNextIdFunctions(t *testing.T) { nextId = uint64(1) + t.Run("Initial nextId should return 1", func(t *testing.T) { uassert.Equal(t, uint64(1), getNextId(), "expected nextId to start at 1") }) t.Run("After mint nextId should return 2", func(t *testing.T) { - MakeMintPositionWithoutFee(t) - uassert.Equal(t, uint64(2), getNextId(), "expected nextId to be 2 after mint") + incrementNextId() + uassert.Equal(t, getNextId(), uint64(2), "expected nextId to be 2 after mint") }) t.Run("Increment nextId once", func(t *testing.T) { incrementNextId() - uassert.Equal(t, uint64(3), getNextId(), "expected nextId to increment to 2") + uassert.Equal(t, uint64(3), getNextId(), "expected nextId to increment to 3") }) t.Run("Increment nextId multiple times", func(t *testing.T) { @@ -834,7 +835,7 @@ func TestMint(t *testing.T) { tc.caller, ) - uassert.Equal(t, uint64(4), tokenId) + uassert.Equal(t, uint64(5), tokenId) uassert.NotEmpty(t, liquidity) t0, _ := strconv.ParseUint(amount0, 10, 64) t1, _ := strconv.ParseUint(amount1, 10, 64) @@ -862,6 +863,8 @@ func TestIncreaseLiquidityInternal(t *testing.T) { setPosition(id, position) incrementNextId() + MakeMintPositionWithoutFee(t) + tests := []struct { name string params IncreaseLiquidityParams @@ -887,7 +890,7 @@ func TestIncreaseLiquidityInternal(t *testing.T) { { name: "Fail - Zero Liquidity", params: IncreaseLiquidityParams{ - tokenId: 1, + tokenId: 7, amount0Desired: u256.Zero(), amount1Desired: u256.Zero(), amount0Min: u256.NewUint(900000), @@ -935,7 +938,7 @@ func TestIncreaseLiquidity(t *testing.T) { }{ { name: "Success - Valid Increase", - tokenId: 1, + tokenId: 7, amount0Desired: "1000000", amount1Desired: "2000000", amount0Min: "950000", @@ -947,7 +950,7 @@ func TestIncreaseLiquidity(t *testing.T) { }, { name: "Fail - Deadline Exceeded", - tokenId: 1, + tokenId: 7, amount0Desired: "1000000", amount1Desired: "2000000", amount0Min: "950000", @@ -958,7 +961,7 @@ func TestIncreaseLiquidity(t *testing.T) { }, { name: "Fail - Invalid Amount String", - tokenId: 1, + tokenId: 7, amount0Desired: "invalid_amount", amount1Desired: "2000000", amount0Min: "950000", @@ -1315,7 +1318,7 @@ func TestReposition(t *testing.T) { tickLower: -5000, tickUpper: 5000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(10) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition with partial liquidity removal", @@ -1327,7 +1330,7 @@ func TestReposition(t *testing.T) { tickLower: -3000, tickUpper: 3000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:5083034, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(10) isn't clear(liquidity:5083034, tokensOwed0:0, tokensOwed1:0)", }, { name: "Fail - Reposition on non-existent tokenId", @@ -1337,7 +1340,7 @@ func TestReposition(t *testing.T) { tickLower: -4000, tickUpper: 4000, expectPanic: true, - expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(8) isn't clear(liquidity:5083024, tokensOwed0:0, tokensOwed1:0)", + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(10) isn't clear(liquidity:5083024, tokensOwed0:0, tokensOwed1:0)", }, } @@ -1346,6 +1349,7 @@ func TestReposition(t *testing.T) { TokenApprove(t, barPath, admin, pool, consts.UINT64_MAX) TokenApprove(t, fooPath, admin, pool, consts.UINT64_MAX) + // Step 1: Mint a position tokenId, _, _, _ := Mint( barPath, fooPath, @@ -1363,8 +1367,6 @@ func TestReposition(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Step 1: Mint a position - // Step 2: Increase liquidity if tt.increaseAmount0 != "" && tt.increaseAmount1 != "" { _, _, _, _, _ = IncreaseLiquidity( diff --git a/position/utils_test.gno b/position/utils_test.gno index 6ac64b850..bfc27bdff 100644 --- a/position/utils_test.gno +++ b/position/utils_test.gno @@ -347,10 +347,6 @@ func TestAssertValidNumberString(t *testing.T) { } } -func TestAssertValidLiquidityRatio(t *testing.T) { - t.Skip("TODO: Implement TestAssertValidLiquidityRatio") -} - func TestA2u(t *testing.T) { addr := std.Address("g1lmvrrrr4er2us84h2732sru76c9zl2nvknha8c") @@ -722,13 +718,15 @@ func TestIsStaked(t *testing.T) { name: "Success - is staked", owner: admin, operator: admin, - tokenId: 1, + tokenId: 11, expected: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { if tc.expected && tc.owner == tc.operator { + MakeMintPositionWithoutFee(t) + LPTokenApprove(t, tc.owner, pusers.AddressOrName(consts.STAKER_ADDR), tc.tokenId) LPTokenStake(t, tc.owner, tc.tokenId) } got := isStaked(tokenIdFrom(tc.tokenId)) @@ -799,7 +797,7 @@ func TestIsOwnerOrOperatorWithStake(t *testing.T) { name: "Fail - is not token staked", owner: admin, operator: alice, - tokenId: 1, + tokenId: 10, isStake: false, expected: false, }, @@ -807,7 +805,7 @@ func TestIsOwnerOrOperatorWithStake(t *testing.T) { name: "Success - is token staked (position operator)", owner: admin, operator: admin, - tokenId: 1, + tokenId: 10, isStake: true, expected: true, }, @@ -815,6 +813,7 @@ func TestIsOwnerOrOperatorWithStake(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { if tc.isStake { + tokenId, _, _, _ := MakeMintPositionWithoutFee(t) LPTokenApprove(t, pusers.AddressOrName(tc.owner), pusers.AddressOrName(consts.STAKER_ADDR), tc.tokenId) LPTokenStake(t, tc.owner, tc.tokenId) }