From 076b25f4dd3ea10370e2c14a4c14b95b1ad6b444 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 16 Mar 2026 16:29:48 +0000 Subject: [PATCH 1/2] fix: CodeDocs.vue shows stale recenter() with recenterAccess guard (#837) Remove the obsolete recenterAccess pattern from the liquidityManagerSol snippet: drop the recenterAccess state variable, setRecenterAccess(), revokeRecenterAccess(), and onlyFeeDestination modifier. Update recenter() to reflect the current cooldown-only access model, fix the VWAP direction logic, and update the _scrapePositions() call signature to match LiquidityManager.sol. Co-Authored-By: Claude Sonnet 4.6 --- landing/src/views/docs/CodeDocs.vue | 30 ++++++----------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/landing/src/views/docs/CodeDocs.vue b/landing/src/views/docs/CodeDocs.vue index fa19c8a..8c88949 100644 --- a/landing/src/views/docs/CodeDocs.vue +++ b/landing/src/views/docs/CodeDocs.vue @@ -263,7 +263,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { PoolKey private poolKey; address private immutable deployer; - address public recenterAccess; address public feeDestination; int24 public lastRecenterTick; @@ -275,11 +274,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { error ZeroAddressInSetter(); error AddressAlreadySet(); - modifier onlyFeeDestination() { - require(msg.sender == address(feeDestination), "only callable by feeDestination"); - _; - } - constructor(address _factory, address _WETH9, address _kraiken, address _optimizer) { deployer = msg.sender; factory = _factory; @@ -313,22 +307,12 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { feeDestination = feeDestination_; } - function setRecenterAccess(address addr) external onlyFeeDestination { - recenterAccess = addr; - } - - function revokeRecenterAccess() external onlyFeeDestination { - recenterAccess = address(0); - } - function recenter() external returns (bool isUp) { (, int24 currentTick,,,,,) = pool.slot0(); - if (recenterAccess != address(0)) { - require(msg.sender == recenterAccess, "access denied"); - } else { - require(block.timestamp >= lastRecenterTime + MIN_RECENTER_INTERVAL, "recenter cooldown"); - require(_isPriceStable(currentTick), "price deviated from oracle"); - } + + // Always enforce cooldown and TWAP price stability — no bypass path + require(block.timestamp >= lastRecenterTime + MIN_RECENTER_INTERVAL, "recenter cooldown"); + require(_isPriceStable(currentTick), "price deviated from oracle"); lastRecenterTime = block.timestamp; isUp = false; @@ -344,14 +328,12 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { bool shouldRecordVWAP; if (cumulativeVolume == 0) { shouldRecordVWAP = true; - } else if (lastRecenterTick != 0) { - shouldRecordVWAP = token0isWeth ? (currentTick < lastRecenterTick) : (currentTick > lastRecenterTick); } else { - shouldRecordVWAP = true; + shouldRecordVWAP = token0isWeth ? (currentTick > lastRecenterTick) : (currentTick < lastRecenterTick); } lastRecenterTick = currentTick; - _scrapePositions(shouldRecordVWAP); + _scrapePositions(shouldRecordVWAP, currentTick); if (isUp) { kraiken.setPreviousTotalSupply(kraiken.totalSupply()); From 65ffb51a6416587be9afc5228fffdb732e8228bb Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 16 Mar 2026 16:58:24 +0000 Subject: [PATCH 2/2] fix: update _scrapePositions signature and body in CodeDocs.vue snippet (#837) Update the embedded _scrapePositions definition to accept (bool recordVWAP, int24 currentTick), compute currentPrice directly from the passed tick instead of sampling the ANCHOR position's centre tick, remove the ANCHOR-specific price-sampling branch from the loop, and replace the old split fee+VWAP transfer logic with the current contract's structure: feeDestination != address(this) guard before transfers, single ethFee branch for VWAP recording. Co-Authored-By: Claude Sonnet 4.6 --- landing/src/views/docs/CodeDocs.vue | 41 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/landing/src/views/docs/CodeDocs.vue b/landing/src/views/docs/CodeDocs.vue index 8c88949..b6334bb 100644 --- a/landing/src/views/docs/CodeDocs.vue +++ b/landing/src/views/docs/CodeDocs.vue @@ -360,10 +360,10 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { emit Recentered(currentTick, isUp); } - function _scrapePositions(bool recordVWAP) internal { + function _scrapePositions(bool recordVWAP, int24 currentTick) internal { uint256 fee0 = 0; uint256 fee1 = 0; - uint256 currentPrice; + uint256 currentPrice = _priceAtTick(token0isWeth ? -1 * currentTick : currentTick); for (uint256 i = uint256(Stage.FLOOR); i <= uint256(Stage.DISCOVERY); i++) { TokenPosition storage position = positions[Stage(i)]; @@ -373,28 +373,29 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { pool.collect(address(this), position.tickLower, position.tickUpper, type(uint128).max, type(uint128).max); fee0 += collected0 - amount0; fee1 += collected1 - amount1; - if (i == uint256(Stage.ANCHOR)) { - int24 tick = position.tickLower + ((position.tickUpper - position.tickLower) / 2); - currentPrice = _priceAtTick(token0isWeth ? -1 * tick : tick); + } + } + + if (feeDestination != address(this)) { + if (fee0 > 0) { + if (token0isWeth) { + IERC20(address(weth)).safeTransfer(feeDestination, fee0); + } else { + IERC20(address(kraiken)).safeTransfer(feeDestination, fee0); + } + } + if (fee1 > 0) { + if (token0isWeth) { + IERC20(address(kraiken)).safeTransfer(feeDestination, fee1); + } else { + IERC20(address(weth)).safeTransfer(feeDestination, fee1); } } } - if (fee0 > 0) { - if (token0isWeth) { - IERC20(address(weth)).safeTransfer(feeDestination, fee0); - if (recordVWAP) _recordVolumeAndPrice(currentPrice, fee0); - } else { - IERC20(address(kraiken)).safeTransfer(feeDestination, fee0); - } - } - if (fee1 > 0) { - if (token0isWeth) { - IERC20(address(kraiken)).safeTransfer(feeDestination, fee1); - } else { - IERC20(address(weth)).safeTransfer(feeDestination, fee1); - if (recordVWAP) _recordVolumeAndPrice(currentPrice, fee1); - } + if (recordVWAP) { + uint256 ethFee = token0isWeth ? fee0 : fee1; + if (ethFee > 0) _recordVolumeAndPrice(currentPrice, ethFee); } }