Skip to content

Commit

Permalink
Merge pull request #71 from gnoswap-labs/GSW-404-feat-estimate-liquid…
Browse files Browse the repository at this point in the history
…ity-amounts

GSW-404 feat: estimate liquidity amounts
  • Loading branch information
r3v4s authored Oct 12, 2023
2 parents 03b77ee + cf1b77e commit d3947c0
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 26 deletions.
34 changes: 17 additions & 17 deletions _test/gs_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,16 @@ func init() {
// println(govAddr, "// gov")
}

// 1. [POOL] Init
// 1. [TC - POOL] Init
func TestPoolInitManual(t *testing.T) {
std.TestSetOrigCaller(pc01)

pl.InitManual()

shouldPanicWithMsg(t, func() { pl.InitManual() }, "[POOl] pool_manager.gno__InitManual() || contract must not be initialized")
shouldPanicWithMsg(t, func() { pl.InitManual() }, "[TC - POOl] pool_manager.gno__InitManual() || contract must not be initialized")
}

// 2. [POOL] CreatePool
// 2. [TC - POOL] CreatePool
func TestPoolCreatePool(t *testing.T) {
std.TestSetOrigCaller(pc01)

Expand All @@ -99,7 +99,7 @@ func TestPoolCreatePool(t *testing.T) {
shouldEQ(t, tmpPool.GetTickSpacing(), bigint(10))
}

// 3. [POSITION] Mint LP
// 3. [TC - POSITION] Mint LP
func TestPositionMint(t *testing.T) {
tmpPool := pl.GetPool(pToken0, pToken1, pFee)

Expand Down Expand Up @@ -171,7 +171,7 @@ func TestPositionMint(t *testing.T) {
}
}

// 4. [STAKER] CreateExternalIncentive
// 4. [TC - STAKER] CreateExternalIncentive
// Internal incentive will automatcially created via init()
func TestStakerCreateExternalIncentive(t *testing.T) {
std.TestSetOrigCaller(ci01)
Expand All @@ -190,11 +190,11 @@ func TestStakerCreateExternalIncentive(t *testing.T) {
func() {
stk.CreateExternalIncentive("bar_foo_500", "OBL", 10_000_000_000, GetTimestamp(), GetTimestamp()+(TIMESTAMP_30DAYS*2))
},
"[STAKER] staker.gno__CreateExternalIncentive() || incentive(YmFyX2Zvb181MDBfT0JM) already exists",
"[TC - STAKER] staker.gno__CreateExternalIncentive() || incentive(YmFyX2Zvb181MDBfT0JM) already exists",
)
}

// 5. [STAKER] StakeToken
// 5. [TC - STAKER] StakeToken
func TestStakerStakeToken(t *testing.T) {
// lp01 stakes tokenId '1'
std.TestSetPrevAddr(lp01) // r3v4_xxx: only test code, we need to call gnft.Approve directly from user
Expand All @@ -215,7 +215,7 @@ func TestStakerStakeToken(t *testing.T) {
shouldEQ(t, gnft.OwnerOf(bigint(2)), stakerAddr)
}

// 6. [POOL] SetFeeProtocol
// 6. [TC - POOL] SetFeeProtocol
func TestPoolSetFeeProtocol(t *testing.T) {
std.TestSetOrigCaller(pc01)

Expand All @@ -226,7 +226,7 @@ func TestPoolSetFeeProtocol(t *testing.T) {
shouldEQ(t, tmpPool.GetFeeProtocol(), bigint(134))
}

// 7. [POOL] Swap ( token0 -> token1 )
// 7. [TC - POOL] Swap ( token0 -> token1 )
func TestPoolSwap01(t *testing.T) {
tmpPool := pl.GetPool(pToken0, pToken1, pFee)
testPrice01 := bigint(MIN_SQRT_RATIO + 1)
Expand Down Expand Up @@ -283,7 +283,7 @@ func TestPoolSwap01(t *testing.T) {
shouldEQ(t, token1Balance(pc01), cAmount1)
}

// 8. [POSITION] Collect
// 8. [TC - POSITION] Collect
// * collect fee from (swap token0 > token1)
func TestPositionCollect01(t *testing.T) {
{
Expand Down Expand Up @@ -337,7 +337,7 @@ func TestPositionCollect01(t *testing.T) {
}
}

// 9. [POOL] Swap ( token1 -> token0 )
// 9. [TC - POOL] Swap ( token1 -> token0 )
func TestPoolSwap10(t *testing.T) {
tmpPool := pl.GetPool(pToken0, pToken1, pFee)
testPrice10 := bigint(MAX_SQRT_RATIO - 1)
Expand Down Expand Up @@ -393,7 +393,7 @@ func TestPoolSwap10(t *testing.T) {
shouldEQ(t, token1Balance(pc01), cAmount1)
}

// 10. [POSITION] Collect
// 10. [TC - POSITION] Collect
// * collect fee from (swap token1 > token0)
func TestPositionCollect10(t *testing.T) {
{
Expand Down Expand Up @@ -447,7 +447,7 @@ func TestPositionCollect10(t *testing.T) {
}
}

// 11. [STAKER] UnstakeToken
// 11. [TC - STAKER] UnstakeToken
func TestStakerUnstakeToken(t *testing.T) {
{
// lp01 unstakes tokenId '1'
Expand Down Expand Up @@ -478,7 +478,7 @@ func TestStakerUnstakeToken(t *testing.T) {
}
}

// 12. [STAKER] EndExternalIncentive
// 12. [TC - STAKER] EndExternalIncentive
func TestStakerEndExternalIncentive(t *testing.T) {
std.TestSetOrigCaller(ci01)
std.TestSkipHeights(1036800)
Expand All @@ -494,7 +494,7 @@ func TestStakerEndExternalIncentive(t *testing.T) {
shouldPanicWithMsg(
t,
func() { stk.EndExternalIncentive("bar_foo_500", "OBL") },
"[STAKER] staker.gno__EndIncentive() || cannot end non existent incentive(YmFyX2Zvb181MDBfT0JM)",
"[TC - STAKER] staker.gno__EndIncentive() || cannot end non existent incentive(YmFyX2Zvb181MDBfT0JM)",
)
}

Expand All @@ -513,7 +513,7 @@ func a2u(addr std.Address) users.AddressOrName {

func tid(tokenId interface{}) grc721.TokenID {
if tokenId == nil {
panic("[POSITION] test_helper.gno__tid() || tokenId is nil")
panic("[TC - POSITION] test_helper.gno__tid() || tokenId is nil")
}

switch tokenId.(type) {
Expand All @@ -528,7 +528,7 @@ func tid(tokenId interface{}) grc721.TokenID {
case grc721.TokenID:
return tokenId.(grc721.TokenID)
default:
panic("[STAKER] utils.gno__tid() || unsupported tokenId type")
panic("[TC - STAKER] utils.gno__tid() || unsupported tokenId type")
}
}

Expand Down
2 changes: 0 additions & 2 deletions _test/phase_v1.mk
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,13 @@ approve-lp01:
$(info ************ [APPROVE] foo & bar from lp01 to pool ************)
@echo "" | gnokey maketx call -pkgpath gno.land/r/foo -func Approve -args $(ADDR_POOL) -args 50000000000 -insecure-password-stdin=true -remote $(GNOLAND_RPC_URL) -broadcast=true -chainid dev -gas-fee 1ugnot -gas-wanted 9000000 -memo "" lp01 > /dev/null
@echo "" | gnokey maketx call -pkgpath gno.land/r/bar -func Approve -args $(ADDR_POOL) -args 50000000000 -insecure-password-stdin=true -remote $(GNOLAND_RPC_URL) -broadcast=true -chainid dev -gas-fee 1ugnot -gas-wanted 9000000 -memo "" lp01 > /dev/null

@echo


approve-tr01:
$(info ************ [APPROVE] foo & bar from tr01 to pool ************)
@echo "" | gnokey maketx call -pkgpath gno.land/r/bar -func Approve -args $(ADDR_POOL) -args 50000000000 -insecure-password-stdin=true -remote $(GNOLAND_RPC_URL) -broadcast=true -chainid dev -gas-fee 1ugnot -gas-wanted 9000000 -memo "" tr01 > /dev/null
@echo "" | gnokey maketx call -pkgpath gno.land/r/foo -func Approve -args $(ADDR_POOL) -args 50000000000 -insecure-password-stdin=true -remote $(GNOLAND_RPC_URL) -broadcast=true -chainid dev -gas-fee 1ugnot -gas-wanted 9000000 -memo "" tr01 > /dev/null

@echo


Expand Down
11 changes: 5 additions & 6 deletions pool/pool_multi_lp_fee_api_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,17 @@ func TestSwap(t *testing.T) {

Swap(pToken0, pToken1, pFee, tr01, true, bigint(150000), test_price_01)
jsonStr = gjson.Parse(ApiGetPool("bar_foo_500"))
jsonStr = gjson.Parse(ApiGetPool("bar_foo_500"))
shouldEQ(t, jsonStr.Get("response.data.token0_balance").Int(), 3107550)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 8448096)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 7635058)
shouldEQ(t, jsonStr.Get("response.data.liquidity").Int(), 100000000)
shouldEQ(t, len(jsonStr.Get("response.data.positions").Array()), 1)

Swap(pToken0, pToken1, pFee, tr01, false, bigint(601851), test_price_10)
// Swap(pToken0, pToken1, pFee, tr01, true, bigint(1500000), test_price_01) // two iteration // s0: 1_500_000 // s1: -3_626_984 // currentTick: 7668
std.TestSkipHeights(1)
jsonStr = gjson.Parse(ApiGetPool("bar_foo_500"))
shouldEQ(t, jsonStr.Get("response.data.token0_balance").Int(), 4718682)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 9049947)
shouldEQ(t, jsonStr.Get("response.data.token0_balance").Int(), 1496418)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 8236909)
shouldEQ(t, jsonStr.Get("response.data.liquidity").Int(), 100000000)
shouldEQ(t, len(jsonStr.Get("response.data.positions").Array()), 1)

Expand All @@ -132,8 +131,8 @@ func TestSwap(t *testing.T) {
Collect(pToken0, pToken1, pFee, lp01, test_tickLower, test_tickUpper, 100000000, 100000000)
std.TestSkipHeights(1)
jsonStr = gjson.Parse(ApiGetPool("bar_foo_500"))
shouldEQ(t, jsonStr.Get("response.data.token0_balance").Int(), 4718608)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 9049647)
shouldEQ(t, jsonStr.Get("response.data.token0_balance").Int(), 1496344)
shouldEQ(t, jsonStr.Get("response.data.token1_balance").Int(), 8236609)
shouldEQ(t, jsonStr.Get("response.data.liquidity").Int(), 100000000)
shouldEQ(t, len(jsonStr.Get("response.data.positions").Array()), 1)
}
Expand Down
2 changes: 1 addition & 1 deletion pool/tick_bitmap.gno
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (pool *Pool) tickBitmapFlipTick(
tick int32,
tickSpacing int32,
) {
require(tick%tickSpacing == 0, ufmt.Sprintf("[POOL] tick_bitmap.gno__tickBitmapFlipTick() || tick MOD tickSpacing(%s) != 0", tick%tickSpacing))
require(tick%tickSpacing == 0, ufmt.Sprintf("[POOL] tick_bitmap.gno__tickBitmapFlipTick() || tick MOD tickSpacing(%d) != 0", tick%tickSpacing))
wordPos, bitPos := tickBitmapPosition(tick)
mask := bigint(1) << uint64(bitPos)
requireUnsigned(mask, ufmt.Sprintf("[POOL] tick_bitmap.gno__tickBitmapFlipTick() || mask(%s) > 0", mask))
Expand Down
2 changes: 2 additions & 0 deletions position/consts.gno
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ const (
// ETC
Q96 bigint = 79228162514264337593543950336 // 2 ** 96
Q128 bigint = 340282366920938463463374607431768211456 // 2 ** 128

MAX_UINT160 bigint = 1461501637330902918203684832716283019655932542975
)
54 changes: 54 additions & 0 deletions position/math_logic.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package position

import (
p "gno.land/r/pool"
)

func DryMint(
tickCurrent int32,
tickLower int32,
tickUpper int32,
amount0Desired bigint,
amount1Desired bigint,
) (amount0, amount1 bigint) {
sqrtRatioX96 := p.TickMathGetSqrtRatioAtTick(tickCurrent)
sqrtLowerX96 := p.TickMathGetSqrtRatioAtTick(tickLower)
sqrtUpperX96 := p.TickMathGetSqrtRatioAtTick(tickUpper)

liquidity := liquidityAmountsGetLiquidityForAmounts(
sqrtRatioX96,
sqrtLowerX96,
sqrtUpperX96,
amount0Desired,
amount1Desired,
)

if liquidity != 0 {
if tickCurrent < tickLower {
amount0 = sqrtPriceMathGetAmount0Delta(
sqrtLowerX96,
sqrtUpperX96,
liquidity,
)
} else if tickCurrent < tickUpper {
amount0 = sqrtPriceMathGetAmount0Delta(
sqrtRatioX96,
sqrtUpperX96,
liquidity,
)

amount1 = sqrtPriceMathGetAmount1Delta(
sqrtLowerX96,
sqrtRatioX96,
liquidity,
)
} else {
amount1 = sqrtPriceMathGetAmount1Delta(
sqrtLowerX96,
sqrtUpperX96,
liquidity,
)
}
}
return
}
44 changes: 44 additions & 0 deletions position/math_logic_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package position

import (
"testing"
)

func TestDryMintInRange(t *testing.T) {
m0, m1 := DryMint(
10000, // tickCurrent int32
7000, // tickLower int32
15000, // tickUpper int32
10000, // amount0Desired bigint
16000, // amount1Desired bigint
)

shouldEQ(t, m0, bigint(9347))
shouldEQ(t, m1, bigint(15999))
}

func TestDryMintLowerRange(t *testing.T) {
m0, m1 := DryMint(
7000, // tickCurrent int32
5000, // tickLower int32
6000, // tickUpper int32
10000, // amount0Desired bigint
16000, // amount1Desired bigint
)

shouldEQ(t, m0, bigint(0))
shouldEQ(t, m1, bigint(15999))
}

func TestDryMintUpperRange(t *testing.T) {
m0, m1 := DryMint(
7000, // tickCurrent int32
9000, // tickLower int32
11000, // tickUpper int32
10000, // amount0Desired bigint
16000, // amount1Desired bigint
)

shouldEQ(t, m0, bigint(9999))
shouldEQ(t, m1, bigint(0))
}
Loading

0 comments on commit d3947c0

Please sign in to comment.