diff --git a/onchain/src/LiquidityManager.sol b/onchain/src/LiquidityManager.sol index 6efda70..b6d24eb 100644 --- a/onchain/src/LiquidityManager.sol +++ b/onchain/src/LiquidityManager.sol @@ -211,7 +211,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { } /// @notice Removes all positions and collects fees - /// @param recordVWAP Whether to record VWAP (only when net ETH inflow since last recenter) + /// @param recordVWAP Whether to record VWAP (only when net ETH outflow / price fell since last recenter, or at bootstrap) function _scrapePositions(bool recordVWAP) internal { uint256 fee0 = 0; uint256 fee1 = 0; @@ -239,8 +239,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { } // Transfer fees and record volume for VWAP - // Only record VWAP when net ETH inflow (KRK sold out) — prevents sell-back - // activity from diluting the price memory of original KRK distribution. + // VWAP is recorded only on sell events (price fell) or at bootstrap — see recenter(). // Skip transfer when feeDestination is self — fees accrue as deployable liquidity. if (feeDestination != address(this)) { if (fee0 > 0) { diff --git a/onchain/test/VWAPFloorProtection.t.sol b/onchain/test/VWAPFloorProtection.t.sol index b1f9331..20d099f 100644 --- a/onchain/test/VWAPFloorProtection.t.sol +++ b/onchain/test/VWAPFloorProtection.t.sol @@ -17,12 +17,8 @@ pragma solidity ^0.8.19; import { LiquidityManager } from "../src/LiquidityManager.sol"; import { ThreePositionStrategy } from "../src/abstracts/ThreePositionStrategy.sol"; -import { Kraiken } from "../src/Kraiken.sol"; -import "../src/interfaces/IWETH9.sol"; import { TestEnvironment } from "./helpers/TestBase.sol"; import { UniSwapHelper } from "./helpers/UniswapTestBase.sol"; -import "@uniswap-v3-core/interfaces/IUniswapV3Pool.sol"; -import "forge-std/Test.sol"; contract VWAPFloorProtectionTest is UniSwapHelper { address constant RECENTER_CALLER = address(0x7777); @@ -128,6 +124,11 @@ contract VWAPFloorProtectionTest is UniSwapHelper { try lm.recenter() { } catch { } } + // This test is written for token0isWeth=false (set in setUp via setupEnvironment(false,...)). + // For !token0isWeth: buying KRK pushes tick UP (WETH/KRK price rises), so floor must be + // BELOW (lower tick than) the inflated current tick. + assertFalse(token0isWeth, "test assumes token0isWeth=false; update gap logic if changed"); + // Read floor and current tick (, int24 currentTick,,,,,) = pool.slot0(); (, int24 floorTickLower, int24 floorTickUpper) = @@ -135,7 +136,6 @@ contract VWAPFloorProtectionTest is UniSwapHelper { int24 floorCenter = floorTickLower + (floorTickUpper - floorTickLower) / 2; - // For !token0isWeth buying pushes tick UP (KRK more expensive). // The floor must be BELOW the current inflated tick by a substantial margin — // at minimum the anchor spacing plus some additional buffer from VWAP anchoring. // We assert that the gap is at least 400 ticks (two tick spacings).