Merge pull request 'fix: Remove recenterAccess — make recenter() public with TWAP enforcement (#706)' (#713) from fix/issue-706 into master

This commit is contained in:
johba 2026-03-14 10:48:59 +01:00
commit 6ff8282a7e
19 changed files with 241 additions and 330 deletions

View file

@ -53,16 +53,15 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Access control and fee management
address private immutable deployer;
address public recenterAccess;
address public feeDestination;
bool public feeDestinationLocked;
/// @notice Last recenter tick used to determine net trade direction between recenters
int24 public lastRecenterTick;
/// @notice Last recenter timestamp rate limits open recenters.
/// @notice Last recenter timestamp rate limits recenters.
uint256 public lastRecenterTime;
/// @notice Minimum seconds between open recenters (when recenterAccess is unset)
/// @notice Minimum seconds between recenters
uint256 internal constant MIN_RECENTER_INTERVAL = 60;
/// @notice Target observation cardinality requested from the pool during construction
uint16 internal constant ORACLE_CARDINALITY = 100;
@ -73,12 +72,6 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
/// @notice Custom errors
error ZeroAddressInSetter();
/// @notice Access control modifier
modifier onlyFeeDestination() {
require(msg.sender == address(feeDestination), "only callable by feeDestination");
_;
}
/// @notice Constructor initializes all contract references and pool configuration
/// @param _factory The address of the Uniswap V3 factory
/// @param _WETH9 The address of the WETH contract
@ -146,28 +139,17 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
}
}
/// @notice Sets recenter access for testing/emergency purposes
/// @param addr Address to grant recenter access
function setRecenterAccess(address addr) external onlyFeeDestination {
recenterAccess = addr;
}
/// @notice Revokes recenter access
function revokeRecenterAccess() external onlyFeeDestination {
recenterAccess = address(0);
}
/// @notice Adjusts liquidity positions in response to price movements.
/// Callable by anyone. Always enforces cooldown and TWAP price stability.
/// This function either completes a full recenter (removing all positions,
/// recording VWAP where applicable, and redeploying liquidity) or reverts
/// it never returns silently without acting.
///
/// @dev Revert conditions (no silent false return for failure):
/// - "access denied" recenterAccess is set and caller is not that address
/// - "recenter cooldown" recenterAccess is unset and MIN_RECENTER_INTERVAL has not elapsed
/// - "price deviated from oracle" recenterAccess is unset and price is outside TWAP bounds
/// - "amplitude not reached." anchor position exists but price has not moved far enough
/// from the anchor centre to warrant repositioning
/// - "recenter cooldown" MIN_RECENTER_INTERVAL has not elapsed since last recenter
/// - "price deviated from oracle" price is outside TWAP bounds (manipulation guard)
/// - "amplitude not reached." anchor position exists but price has not moved far enough
/// from the anchor centre to warrant repositioning
///
/// @return isUp True if the KRK price in ETH rose since the last recenter
/// (buy event / net ETH inflow), regardless of token0/token1 ordering.
@ -177,13 +159,9 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle {
function recenter() external returns (bool isUp) {
(, int24 currentTick,,,,,) = pool.slot0();
// Validate access and price stability
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;
// Check if price movement is sufficient for recentering