From d01c561028c0c05b5cd484d363da625550349149 Mon Sep 17 00:00:00 2001 From: openhands Date: Fri, 13 Mar 2026 07:20:42 +0000 Subject: [PATCH] fix: No formal IOptimizer interface for getLiquidityParams ABI (#556) Add IOptimizer interface with getLiquidityParams() signature to IOptimizer.sol so upgrade-compatibility is explicit and static analysis can catch ABI mismatches. Update LiquidityManager to hold optimizer as IOptimizer instead of concrete Optimizer. Co-Authored-By: Claude Sonnet 4.6 --- onchain/src/IOptimizer.sol | 21 +++++++++++++++++++++ onchain/src/LiquidityManager.sol | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/onchain/src/IOptimizer.sol b/onchain/src/IOptimizer.sol index a438ecf..653d44d 100644 --- a/onchain/src/IOptimizer.sol +++ b/onchain/src/IOptimizer.sol @@ -9,3 +9,24 @@ struct OptimizerInput { int256 mantissa; int256 shift; } + +/** + * @title IOptimizer + * @notice Minimal interface for the Optimizer contract consumed by LiquidityManager. + * Declaring the ABI here makes upgrade-compatibility explicit: any new + * Optimizer implementation must satisfy this selector or the LiquidityManager + * will fall back to bear-mode defaults via its try-catch. + */ +interface IOptimizer { + /** + * @notice Returns the four liquidity parameters used by LiquidityManager.recenter(). + * @return capitalInefficiency Capital buffer level (0..1e18). CI=0 is safest. + * @return anchorShare Fraction of non-floor ETH in anchor (0..1e18). + * @return anchorWidth Anchor position width in tick units (uint24). + * @return discoveryDepth Discovery liquidity density (0..1e18). + */ + function getLiquidityParams() + external + view + returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth); +} diff --git a/onchain/src/LiquidityManager.sol b/onchain/src/LiquidityManager.sol index 6ece4ef..5707490 100644 --- a/onchain/src/LiquidityManager.sol +++ b/onchain/src/LiquidityManager.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import { Kraiken } from "./Kraiken.sol"; -import { Optimizer } from "./Optimizer.sol"; +import { IOptimizer } from "./IOptimizer.sol"; import { PriceOracle } from "./abstracts/PriceOracle.sol"; import { ThreePositionStrategy } from "./abstracts/ThreePositionStrategy.sol"; import { IWETH9 } from "./interfaces/IWETH9.sol"; @@ -38,7 +38,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { address private immutable factory; IWETH9 private immutable weth; Kraiken private immutable kraiken; - Optimizer private immutable optimizer; + IOptimizer private immutable optimizer; IUniswapV3Pool private immutable pool; bool private immutable token0isWeth; PoolKey private poolKey; @@ -84,7 +84,7 @@ contract LiquidityManager is ThreePositionStrategy, PriceOracle { pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); kraiken = Kraiken(_kraiken); token0isWeth = _WETH9 < _kraiken; - optimizer = Optimizer(_optimizer); + optimizer = IOptimizer(_optimizer); // Increase observation cardinality so pool.observe() has sufficient history // for _isPriceStable() TWAP checks. pool.increaseObservationCardinalityNext(ORACLE_CARDINALITY);