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/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 } 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/_helper_test.gno b/position/_helper_test.gno index 41c4c458f..30ccacef0 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} @@ -504,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() @@ -552,6 +573,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 +785,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 +801,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 +809,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 +817,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/_RPC_api.gno b/position/api.gno similarity index 99% rename from position/_RPC_api.gno rename to position/api.gno index 5afcdd684..8a5cb04c2 100644 --- a/position/_RPC_api.gno +++ b/position/api.gno @@ -5,7 +5,6 @@ import ( "time" "gno.land/p/demo/json" - i256 "gno.land/p/gnoswap/int256" "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" @@ -111,7 +110,7 @@ func ApiGetPositions() string { func ApiGetPosition(lpTokenId uint64) string { rpcPositions := []RpcPosition{} - position, exist := GetPosition(lpTokenId) + _, exist := GetPosition(lpTokenId) if !exist { return "" } @@ -392,7 +391,7 @@ func rpcMakePosition(lpTokenId uint64) RpcPosition { currentX96, lowerX96, upperX96, - i256.FromUint256(position.liquidity), + position.liquidity, ) unclaimedFee0 := i256.Zero() diff --git a/position/api_test.gno b/position/api_test.gno new file mode 100644 index 000000000..acde02013 --- /dev/null +++ b/position/api_test.gno @@ -0,0 +1,456 @@ +package position + +import ( + "std" + "testing" + + "gno.land/p/demo/json" + "gno.land/p/demo/uassert" + "gno.land/r/demo/users" +) + +func setupPositions(t *testing.T) { + t.Helper() + + MakeMintPositionWithoutFee(t) +} + +func TestApiGetPositions(t *testing.T) { + setupPositions(t) + std.TestSetRealm(std.NewUserRealm(users.Resolve(admin))) + + result := ApiGetPositions() + + 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, 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()) + + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) +} + +func TestApiGetPositionsByPoolPath(t *testing.T) { + result := ApiGetPositionsByPoolPath("gno.land/r/onbloc/bar:gno.land/r/onbloc/foo:500") + + 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, 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()) + + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) +} + +func TestApiGetPositionsByAddress(t *testing.T) { + address := users.Resolve(admin) + result := ApiGetPositionsByAddress(address) + + 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, 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()) + + fee1Unclaimed, err := response.GetKey("fee1Unclaimed") + if err != nil { + panic(err.Error()) + } + uassert.Equal(t, "\"0\"", fee1Unclaimed.String()) +} + +func TestApiGetPositionsUnclaimedFee(t *testing.T) { + result := ApiGetPositionsUnclaimedFee() + + 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, 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()) + + 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) + + 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, 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()) + + 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()) +} 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/_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/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.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.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.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 a913d77d5..613e55c53 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" @@ -215,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) @@ -230,11 +230,9 @@ func Mint( panic(newErrorWithDetail(errWrapUnwrap, err.Error())) } } - poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(processedInput.poolPath) prevAddr, prevPkgPath := getPrevAsString() - std.Emit( "Mint", "prevAddr", prevAddr, @@ -334,10 +332,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 +524,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 +532,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 +667,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 +710,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,11 +747,9 @@ 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, + liquidityStr string, amount0MinStr string, amount1MinStr string, deadline int64, @@ -764,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) @@ -790,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(), @@ -825,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) @@ -839,8 +839,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 +931,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 +938,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 +961,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 +1005,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 +1015,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 +1062,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 +1073,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 +1092,9 @@ func Reposition( position.tokensOwed0 = u256.Zero() position.tokensOwed1 = u256.Zero() position.burned = false - mustUpdatePosition(tokenId, position) poolSqrtPriceX96 := pl.PoolGetSlot0SqrtPriceX96(position.poolKey) - prevAddr, prevPkgPath := getPrevAsString() std.Emit( diff --git a/position/position_test.gno b/position/position_test.gno index 3a6e2666e..cddafe3dd 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(300) + 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) { @@ -109,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) { @@ -587,29 +700,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(5), 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() + + MakeMintPositionWithoutFee(t) + + 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: 7, + 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: 7, + 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: 7, + 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: 7, + 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 + liquidityToRemove string + amount0Min string + amount1Min string + deadlineOffset time.Duration + unwrapResult bool + expectPanic bool + expectedErrorMsg string + expectedLiquidity string + expectedFee0 string + expectedFee1 string + }{ + { + name: "Success - Decrease 50% Liquidity", + liquidityToRemove: "400000", + amount0Min: "8000", + amount1Min: "15000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "400000", + expectedFee0: "0", + expectedFee1: "0", + }, + { + name: "Success - Decrease 100% Liquidity", + liquidityToRemove: "600000", + amount0Min: "10000", + amount1Min: "20000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "600000", + expectedFee0: "0", + expectedFee1: "0", + expectedErrorMsg: "", + }, + { + 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", + liquidityToRemove: "1541592", + 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", + 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", + liquidityToRemove: "1270796", + amount0Min: "12000", + amount1Min: "25000", + deadlineOffset: time.Hour, + unwrapResult: false, + expectPanic: false, + expectedLiquidity: "1270796", + 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 { + DecreaseLiquidity( + tokenId, + tc.liquidityToRemove, + tc.amount0Min, + tc.amount1Min, + deadline, + tc.unwrapResult, + ) + } else { + _, liquidity, fee0, fee1, _, _, _ := DecreaseLiquidity( + tokenId, + tc.liquidityToRemove, + 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 + liquidityToRemove string + 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", + 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", + liquidityToRemove: "100", + unwrapResult: true, + expectedFee0: "0", + expectedFee1: "0", + expectedAmount0: "0", + expectedAmount1: "0", + expectPanic: false, + }, + { + name: "Fail - No liquidity to collect", + mintAmount0: "100000", + mintAmount1: "200000", + liquidityToRemove: "0", + unwrapResult: false, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-010] zero liquidity || liquidity amount must be greater than 0, 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.liquidityToRemove, + "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 + liquidityToRemove string + tickLower int32 + tickUpper int32 + expectPanic bool + expectedPanicError string + }{ + { + 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(10) isn't clear(liquidity:3812288, tokensOwed0:0, tokensOwed1:0)", + }, + { + name: "Fail - Reposition with partial liquidity removal", + mintAmount0: "1000000", + mintAmount1: "2000000", + increaseAmount0: "500000", + increaseAmount1: "1000000", + liquidityToRemove: "50", + tickLower: -3000, + tickUpper: 3000, + expectPanic: true, + 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", + mintAmount0: "1000000", + mintAmount1: "2000000", + liquidityToRemove: "10", + tickLower: -4000, + tickUpper: 4000, + expectPanic: true, + expectedPanicError: "[GNOSWAP-POSITION-009] position is not clear || position(10) isn't clear(liquidity:5083024, 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) + + // Step 1: Mint a position + 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 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.liquidityToRemove, + "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/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 a3732dab5..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(tid(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) -} diff --git a/position/tests/__TEST_fee_collect_with_two_user_test.gnoA b/position/tests/__TEST_fee_collect_with_two_user_test.gnoA index 51906879e..baa6d7157 100644 --- a/position/tests/__TEST_fee_collect_with_two_user_test.gnoA +++ b/position/tests/__TEST_fee_collect_with_two_user_test.gnoA @@ -6,7 +6,6 @@ import ( "time" "gno.land/p/demo/testutils" - "gno.land/p/demo/uassert" "gno.land/r/gnoswap/v1/common" "gno.land/r/gnoswap/v1/consts" @@ -16,8 +15,6 @@ import ( "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 ( @@ -46,6 +43,7 @@ func TestCollectFeeWithTwoUser(t *testing.T) { 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" @@ -62,20 +60,21 @@ func TestCollectFeeWithTwoUser(t *testing.T) { 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( + tokenId_res1, liquidity_res1, amount0_res1, amount1_res1 := Mint( barPath, // token0 string, bazPath, // token1 string, 3000, // fee uint32, - minTick, // tickLower int32, - maxTick, // tickUpper int32, + -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 - admin, + user1Adderss, ) + println("tokenId_res1:", tokenId_res1) std.TestSetRealm(user2Realm) bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX) @@ -83,74 +82,78 @@ func TestCollectFeeWithTwoUser(t *testing.T) { 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( + tokenId_res2, liquidity_res2, amount0_res2, amount1_res2 := Mint( barPath, // token0 string, bazPath, // token1 string, 3000, // fee uint32, - minTick, // tickLower int32, - maxTick, // tickUpper int32, + -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 - admin, + 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 - ) - - // ====== 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 - ) + // 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, _, _ := 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)) + // 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/tests/__TEST_position_api_test.gnoA index 0201c1443..bcce61003 100644 --- a/position/tests/__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, admin, 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, admin, 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, admin, admin) + Mint(bazPath, quxPath, fee500, int32(9000), int32(11000), "1000000", "1000000", "1", "1", max_timeout, adminAddr, adminAddr) } 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, ) } @@ -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/tests/__TEST_position_full_test.gnoA b/position/tests/__TEST_position_full_test.gnoA index abf32fa4b..f49b2d064 100644 --- a/position/tests/__TEST_position_full_test.gnoA +++ b/position/tests/__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/tests/__TEST_position_full_with_emission_test.gnoA index 2c8e74399..babffe3fa 100644 --- a/position/tests/__TEST_position_full_with_emission_test.gnoA +++ b/position/tests/__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/tests/__TEST_position_increase_burned_position_test.gnoA index 1fcfe4cc7..29d986473 100644 --- a/position/tests/__TEST_position_increase_burned_position_test.gnoA +++ b/position/tests/__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/tests/__TEST_position_increase_decrease_test.gnoA index 5abf8059a..bc1ff69bf 100644 --- a/position/tests/__TEST_position_increase_decrease_test.gnoA +++ b/position/tests/__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/tests/__TEST_position_mint_gnot_grc20_in-range_out-range_test.gnoA index e0d17d967..271185f64 100644 --- 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 @@ -26,6 +26,8 @@ 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) { @@ -39,10 +41,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)) } @@ -55,20 +57,28 @@ func TestOneSideOnlyGrc20WithoutSend(t *testing.T) { 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, + // 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, + ) + }, ) } @@ -83,20 +93,28 @@ func TestOneSideOnlyGrc20WithSend0Coin(t *testing.T) { 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, + // 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, + ) + }, ) } @@ -111,7 +129,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( @@ -128,67 +146,66 @@ func TestOneSideOnlyUgnot(t *testing.T) { fresh01, // operator fresh01, ) - - // send 100_000_000 - // mint 900_00_000 - // => remain 10_000_000 - uassert.Equal(t, ugnotBalanceOf(fresh01), uint64(10_000_000)) + // 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(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(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) - }, - ) -} +// 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/tests/__TEST_position_mint_swap_burn_left_test.gnoA b/position/tests/__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/tests/__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/tests/__TEST_position_native_increase_decrease_test.gnoA index 9b676a9fa..d21b3135f 100644 --- a/position/tests/__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) { @@ -42,20 +41,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 +68,8 @@ func testMintPosition(t *testing.T) { "0", "0", max_timeout, - admin, - admin, + adminAddr, + adminAddr, ) uassert.Equal(t, tokenId, uint64(1)) @@ -82,13 +81,13 @@ 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) - // 4. refund 50000005 - 50000000 = 5 + // 3. 50000000 wugnot spent to mint (amount) + // 4. refund 5 ugnot ( admin ugnot balance ) }) } @@ -101,21 +100,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 +127,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 +147,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 +164,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 +186,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 +203,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/tests/__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/tests/__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/tests/__TEST_position_reposition_gnot_pair_test.gnoA index a0dc361e2..1dc217834 100644 --- a/position/tests/__TEST_position_reposition_gnot_pair_test.gnoA +++ b/position/tests/__TEST_position_reposition_gnot_pair_test.gnoA @@ -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/tests/__TEST_position_reposition_grc20_pair_test.gnoA index 44eb7723b..c26d7a599 100644 --- a/position/tests/__TEST_position_reposition_grc20_pair_test.gnoA +++ b/position/tests/__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)) @@ -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(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, 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(tid(_lpTokenId)) - uassert.Equal(t, ownerOfPosition, admin) + 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") @@ -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") }) @@ -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,16 +272,16 @@ 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") diff --git a/position/tests/__TEST_position_reposition_grc20_pair_with_swap_test.gnoA b/position/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__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/tests/__TEST_position_unclaimed_fee_test.gnoA index bdee97195..a3f1634ac 100644 --- a/position/tests/__TEST_position_unclaimed_fee_test.gnoA +++ b/position/tests/__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/type.gno b/position/type.gno index 7a5383745..73fadbf93 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, @@ -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 e072461e7..39f9f66fb 100644 --- a/position/utils.gno +++ b/position/utils.gno @@ -148,21 +148,20 @@ func assertValidNumberString(input string) { } } -func assertValidLiquidityRatio(ratio uint64) { - if !(ratio >= 1 && ratio <= 100) { +func assertValidLiquidityAmount(liquidity string) { + if u256.MustFromDecimal(liquidity).IsZero() { panic(newErrorWithDetail( - errInvalidLiquidityRatio, - ufmt.Sprintf("liquidity ratio must in range 1 ~ 100(contain), got %d", ratio), + errZeroLiquidity, + ufmt.Sprintf("liquidity amount must be greater than 0, got %s", liquidity), )) } } -// [DEPRECATED] assertOnlyValidAddress panics if the address is invalid. -func assertWrapNativeToken(ugnotSent uint64, prevRealm std.Address) { - if err := wrap(ugnotSent, prevRealm); err != nil { +func assertValidLiquidityRatio(ratio uint64) { + if !(ratio >= 1 && ratio <= 100) { panic(newErrorWithDetail( - errWrapUnwrap, - ufmt.Sprintf("wrap error: %s", err.Error()), + errInvalidLiquidityRatio, + ufmt.Sprintf("liquidity ratio must in range 1 ~ 100(contain), got %d", ratio), )) } } diff --git a/position/utils_test.gno b/position/utils_test.gno index 04d33a469..bfc27bdff 100644 --- a/position/utils_test.gno +++ b/position/utils_test.gno @@ -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", @@ -347,15 +347,6 @@ func TestAssertValidNumberString(t *testing.T) { } } -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 +615,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) }) @@ -730,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)) @@ -807,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, }, @@ -815,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, }, @@ -823,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) } @@ -832,10 +823,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 +891,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 +913,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 +940,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 +966,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") } }) } 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 fe95cec3e..e1c0d2dc0 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" ) @@ -670,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)) @@ -678,7 +677,7 @@ func getTokenPairBalanceFromPosition(tokenId uint64) (string, string) { currentX96, lowerX96, upperX96, - i256.FromUint256(pn.PositionGetPositionLiquidity(tokenId)), + pn.PositionGetPositionLiquidity(tokenId), ) if token0Balance == "" {