harb/onchain/test/mocks/MockLiquidityManagerPositions.sol
johba 8064623a54 fix: feat: Push3 input redesign — normalized indicators instead of raw protocol values (#635) (#649)
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>
2026-03-13 07:53:46 +01:00

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);
}
}