// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.19; /** * @title MockPool * @notice Mock Uniswap V3 pool for testing normalized indicator computation in Optimizer. * @dev Implements slot0() and observe() with configurable return values. * * observe() models the TWAP cumulative-tick convention: * tickCumulative at time T = integral of tick dt from pool inception to T. * We set tickCumulative[now] = 0 and back-fill: * tickCumulative[longWindow ago] = -longTwapTick * LONG_WINDOW * tickCumulative[shortWindow ago] = -shortTwapTick * SHORT_WINDOW * This means: * longTwapTick = (cum[now] - cum[longAgo]) / LONG_WINDOW = longTwapTick ✓ * shortTwapTick = (cum[now] - cum[shortAgo]) / SHORT_WINDOW = shortTwapTick ✓ */ contract MockPool { int24 public currentTick; int24 public longTwapTick; int24 public shortTwapTick; bool public revertOnObserve; uint32 internal constant LONG_WINDOW = 1_800; uint32 internal constant SHORT_WINDOW = 300; function setCurrentTick(int24 _tick) external { currentTick = _tick; } function setTwapTicks(int24 _longTwap, int24 _shortTwap) external { longTwapTick = _longTwap; shortTwapTick = _shortTwap; } function setRevertOnObserve(bool _revert) external { revertOnObserve = _revert; } function slot0() external view returns ( uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked ) { return (0, currentTick, 0, 100, 100, 0, true); } /// @notice Returns tick cumulatives for the three time points [LONG_WINDOW, SHORT_WINDOW, 0]. /// @dev Only handles the exact 3-element call from Optimizer.getLiquidityParams(). function observe(uint32[] calldata secondsAgos) external view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) { require(!revertOnObserve, "MockPool: observe reverts"); require(secondsAgos.length == 3, "MockPool: expected 3 time points"); tickCumulatives = new int56[](3); secondsPerLiquidityCumulativeX128s = new uint160[](3); // cum[now] = 0 tickCumulatives[2] = 0; // cum[longAgo] = -longTwapTick * LONG_WINDOW tickCumulatives[0] = int56(-int256(longTwapTick)) * int56(int32(LONG_WINDOW)); // cum[shortAgo] = -shortTwapTick * SHORT_WINDOW tickCumulatives[1] = int56(-int256(shortTwapTick)) * int56(int32(SHORT_WINDOW)); } }