From c1d7ca4265d3e2c5dbd47ad5c44fdd1cdebab824 Mon Sep 17 00:00:00 2001 From: Andrew Dmytrenko Date: Thu, 12 Sep 2024 10:04:08 +0300 Subject: [PATCH] make ticks more predictable --- contracts/BNBPartyFee.sol | 45 ++++++++++++++++++--------------- contracts/BNBPartyLiquidity.sol | 2 +- contracts/BNBPartySwaps.sol | 4 +-- test/BNBPartyFactory.ts | 4 +-- test/WithdrawFee.ts | 4 +-- test/helper.ts | 4 +-- 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/contracts/BNBPartyFee.sol b/contracts/BNBPartyFee.sol index 1087b45..9a8ffb8 100644 --- a/contracts/BNBPartyFee.sol +++ b/contracts/BNBPartyFee.sol @@ -21,16 +21,7 @@ abstract contract BNBPartyFee is BNBPartyModifiers { uint256 feeGrowthInside1LastX128 ) { - Ticks memory ticks; - if (address(WBNB) == pool.token0()) { - ticks.tickLower = party.lpTicks.tickLower; - ticks.tickUpper = party.lpTicks.tickUpper; - } else { - ticks = _invertTicks( - party.lpTicks.tickLower, - party.lpTicks.tickUpper - ); - } + Ticks memory ticks = _getTicks(pool.token0(), party.lpTicks); ( feeGrowthInside0LastX128, feeGrowthInside1LastX128 @@ -58,16 +49,7 @@ abstract contract BNBPartyFee is BNBPartyModifiers { uint256 feeGrowthInside1LastX128 ) { - Ticks memory ticks; - if (address(WBNB) == pool.token0()) { - ticks.tickLower = party.partyTicks.tickLower; - ticks.tickUpper = party.partyTicks.tickUpper; - } else { - ticks = _invertTicks( - party.partyTicks.tickLower, - party.partyTicks.tickUpper - ); - } + Ticks memory ticks = _getTicks(pool.token0(), party.partyTicks); ( feeGrowthInside0LastX128, feeGrowthInside1LastX128 @@ -113,6 +95,10 @@ abstract contract BNBPartyFee is BNBPartyModifiers { } } + /// @notice Invert the ticks + /// @param tickLower Lower tick + /// @param tickUpper Upper tick + /// @return ticks struct with inverted ticks function _invertTicks( int24 tickLower, int24 tickUpper @@ -120,4 +106,23 @@ abstract contract BNBPartyFee is BNBPartyModifiers { ticks.tickLower = -tickUpper; ticks.tickUpper = -tickLower; } + + /// @notice Internal function to retrieve the Ticks based on the token address + /// @param token0 Address of the token0 + /// @param ticks The Ticks struct with lower and upper ticks + /// @return adjustedTicks The Ticks struct adjusted based on token address + function _getTicks( + address token0, + Ticks memory ticks + ) + internal + view + returns (Ticks memory adjustedTicks) + { + if (address(WBNB) == token0) { + adjustedTicks = _invertTicks(ticks.tickLower, ticks.tickUpper); + } else { + adjustedTicks = ticks; + } + } } diff --git a/contracts/BNBPartyLiquidity.sol b/contracts/BNBPartyLiquidity.sol index 80a6404..501fd50 100644 --- a/contracts/BNBPartyLiquidity.sol +++ b/contracts/BNBPartyLiquidity.sol @@ -47,7 +47,7 @@ abstract contract BNBPartyLiquidity is BNBPartyLiquidityHelper { IERC20(token0).safeIncreaseAllowance(address(positionManager), amount0); IERC20(token1).safeIncreaseAllowance(address(positionManager), amount1); // Create new Liquidity Pool - _createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, token0 == address(WBNB) ? party.lpTicks : _invertTicks(party.lpTicks.tickLower, party.lpTicks.tickUpper)); + _createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, token1 == address(WBNB) ? party.lpTicks : _invertTicks(party.lpTicks.tickLower, party.lpTicks.tickUpper)); // Send bonuses _unwrapAndSendBNB(recipient, unwrapAmount); diff --git a/contracts/BNBPartySwaps.sol b/contracts/BNBPartySwaps.sol index d2f8797..7d25df9 100644 --- a/contracts/BNBPartySwaps.sol +++ b/contracts/BNBPartySwaps.sol @@ -62,9 +62,9 @@ abstract contract BNBPartySwaps is BNBPartyView { address _token ) internal view returns (address token0, address token1, uint160 sqrtPriceX96, Ticks memory ticks) { if (_token < address(WBNB)) { - return (_token, address(WBNB), party.sqrtPriceX96, _invertTicks(party.partyTicks.tickLower, party.partyTicks.tickUpper)); + return (_token, address(WBNB), party.sqrtPriceX96, Ticks(party.partyTicks.tickLower, party.partyTicks.tickUpper)); } else { - return (address(WBNB), _token, _reverseSqrtPrice(party.sqrtPriceX96), Ticks(party.partyTicks.tickLower, party.partyTicks.tickUpper)); + return (address(WBNB), _token, _reverseSqrtPrice(party.sqrtPriceX96), _invertTicks(party.partyTicks.tickLower, party.partyTicks.tickUpper)); } } diff --git a/test/BNBPartyFactory.ts b/test/BNBPartyFactory.ts index 44ab028..3297af6 100644 --- a/test/BNBPartyFactory.ts +++ b/test/BNBPartyFactory.ts @@ -47,8 +47,8 @@ describe("BNBPartyFactory", function () { expect((await bnbPartyFactory.party()).lpFee).to.equal(FeeAmount.HIGH) expect((await bnbPartyFactory.party()).partyLpFee).to.equal(FeeAmount.HIGH) expect((await bnbPartyFactory.party()).createTokenFee).to.equal(tokenCreationFee) - expect((await bnbPartyFactory.party()).partyTicks.tickUpper).to.equal("195600") - expect((await bnbPartyFactory.party()).partyTicks.tickLower).to.equal("-214200") + expect((await bnbPartyFactory.party()).partyTicks.tickUpper).to.equal("214200") + expect((await bnbPartyFactory.party()).partyTicks.tickLower).to.equal("-195600") }) it("should create party LP", async function () { diff --git a/test/WithdrawFee.ts b/test/WithdrawFee.ts index a25a030..f82c51a 100644 --- a/test/WithdrawFee.ts +++ b/test/WithdrawFee.ts @@ -68,11 +68,11 @@ describe("Withdraw fees", function () { it("should return fee from second lp", async () => { await bnbPartyFactory.joinParty(MEME, 0, { value: BNBToTarget }) // create second lp await bnbPartyFactory.joinParty(MEME, 0, { value: ethers.parseEther("1") }) // make swap for fee - const secondLP = await v3Factory.getPool(MEME, await wbnb.getAddress(), FeeAmount.HIGH) + const secondLP = await v3Factory.getPool(await wbnb.getAddress(), MEME, FeeAmount.HIGH) const lpPool = (await ethers.getContractAt("UniswapV3Pool", secondLP)) as any as IUniswapV3Pool const token0 = await lpPool.token0() await bnbPartyFactory.withdrawLPFee([secondLP]) - const collectedFee = await bnbPartyFactory.getFeeGrowthInsideLastX128(secondLP, positionManager) + const collectedFee = await bnbPartyFactory.getFeeGrowthInsideLastX128(secondLP, await positionManager.getAddress()) const fee = collectedFee.feeGrowthInside0LastX128 == 0n ? collectedFee.feeGrowthInside1LastX128 : collectedFee.feeGrowthInside0LastX128 if (token0 == (await wbnb.getAddress())) { const feeGrowthGlobalX128 = await lpPool.feeGrowthGlobal0X128() diff --git a/test/helper.ts b/test/helper.ts index 563f6ac..d7a3c2e 100644 --- a/test/helper.ts +++ b/test/helper.ts @@ -63,8 +63,8 @@ export async function deployContracts(partyTarget = ethers.parseEther("90"), wbn bonusTargetReach: returnFeeAmount, bonusPartyCreator: bonusFee, targetReachFee: targetReachFee, - partyTicks: { tickLower: "-214200", tickUpper: "195600" }, - lpTicks: { tickLower: "-214200", tickUpper: "201400" } + partyTicks: { tickLower: "-195600", tickUpper: "214200" }, + lpTicks: { tickLower: "-201400", tickUpper: "214200" } }, wbnbAddress, await sqrtPriceCalculator.getAddress()