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:
commit
6ff8282a7e
19 changed files with 241 additions and 330 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue