Fixes #635 ## Changes The implementation is complete and committed. All 211 tests pass. ## Summary of changes ### `onchain/src/Optimizer.sol` - **Replaced raw slot inputs** with normalized indicators in `getLiquidityParams()`: - Slot 2 `pricePosition`: where current price sits within VWAP ± 11 000 ticks (0 = lower bound, 0.5e18 = at VWAP, 1e18 = upper bound) - Slot 3 `volatility`: `|shortTwap − longTwap| / 1000 ticks`, capped at 1e18 - Slot 4 `momentum`: 0 = falling, 0.5e18 = flat, 1e18 = rising (5-min vs 30-min TWAP delta) - Slot 5 `timeSinceRecenter`: `elapsed / 86400s`, capped at 1e18 - Slot 6 `utilizationRate`: 1e18 if current tick is within anchor position range, else 0 - **Extended `setDataSources()`** to accept `liquidityManager` + `token0isWeth` (needed for correct tick direction in momentum/utilizationRate) - **Added `_vwapToTick()`** helper: converts `vwapX96 = price × 2⁹⁶` to tick via `sqrt(vwapX96) << 48`, with TickMath bounds clamping - All slots gracefully default to 0 when data sources are unconfigured or TWAP history is insufficient (try/catch on `pool.observe()`) ### `onchain/src/OptimizerV3Push3.sol` - Updated NatSpec to document the new `[0, 1e18]` slot semantics ### New tests (`onchain/test/`) - `OptimizerNormalizedInputsTest`: 18 tests covering all new slots, token ordering, TWAP fallback, and a bounded fuzz test - `mocks/MockPool.sol`: configurable `slot0()` + `observe()` with TWAP tick math - `mocks/MockLiquidityManagerPositions.sol`: configurable anchor position bounds Co-authored-by: openhands <openhands@all-hands.dev> Reviewed-on: https://codeberg.org/johba/harb/pulls/649 Reviewed-by: review_bot <review_bot@noreply.codeberg.org>
27 lines
1,020 B
Solidity
27 lines
1,020 B
Solidity
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
pragma solidity ^0.8.19;
|
|
|
|
/**
|
|
* @title MockLiquidityManagerPositions
|
|
* @notice Mock LiquidityManager for testing utilizationRate (slot 6) normalization in Optimizer.
|
|
* @dev Exposes positions(uint8) matching ThreePositionStrategy's public mapping getter.
|
|
* Stage enum: FLOOR=0, ANCHOR=1, DISCOVERY=2.
|
|
*/
|
|
contract MockLiquidityManagerPositions {
|
|
struct TokenPosition {
|
|
uint128 liquidity;
|
|
int24 tickLower;
|
|
int24 tickUpper;
|
|
}
|
|
|
|
mapping(uint8 => TokenPosition) private _positions;
|
|
|
|
function setPosition(uint8 stage, uint128 liquidity, int24 tickLower, int24 tickUpper) external {
|
|
_positions[stage] = TokenPosition({ liquidity: liquidity, tickLower: tickLower, tickUpper: tickUpper });
|
|
}
|
|
|
|
function positions(uint8 stage) external view returns (uint128 liquidity, int24 tickLower, int24 tickUpper) {
|
|
TokenPosition storage p = _positions[stage];
|
|
return (p.liquidity, p.tickLower, p.tickUpper);
|
|
}
|
|
}
|