Merge pull request 'fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)' (#1076) from fix/issue-1063 into master

This commit is contained in:
johba 2026-03-20 22:37:34 +01:00
commit 4f6b6cf586
6 changed files with 28 additions and 14 deletions

View file

@ -49,3 +49,4 @@
- [2026-03-15] evo_run007_champion.push3 note has same CI/DD inversion (#790)
- [2026-03-15] txnBot AGENTS.md ENVIRONMENT enum is stale (#784)
- [2026-03-20] Adoption milestone state ambiguity in MEMORY.md (#1068)
- [2026-03-20] OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)

View file

@ -93,6 +93,10 @@ contract DeployBase is Script {
} else {
optimizerAddress = optimizer;
console.log("Using existing optimizer at:", optimizerAddress);
// Guard: ensure the pre-existing optimizer is not a stub (e.g. OptimizerV3Push3).
// OptimizerV3Push3.getLiquidityParams() always reverts; a live optimizer must not.
(bool ok,) = optimizerAddress.staticcall(abi.encodeWithSignature("getLiquidityParams()"));
require(ok, "DeployBase: optimizer getLiquidityParams() reverted - stub or misconfigured address");
}
// Deploy LiquidityManager

View file

@ -134,8 +134,8 @@ contract BacktestRunner is Script {
// ------------------------------------------------------------------
// KrAIken system deployment (follows DeployLocal.sol pattern)
//
// 1. Deploy OptimizerV3Push3 (no proxy getLiquidityParams() uses zeroed
// inputs, returning bear-mode defaults on every recenter).
// 1. Deploy OptimizerV3Push3 (no proxy getLiquidityParams() always reverts;
// LM's try/catch falls back to bear-mode defaults on every recenter).
// 2. Deploy LiquidityManager pointing at the shadow pool.
// 3. Wire BacktestKraiken.setLiquidityManager(lm).
// 4. Set feeDestination = sender.

View file

@ -12,8 +12,8 @@ import { MockToken } from "./MockToken.sol";
struct KrAIkenSystem {
BacktestKraiken kraiken;
/// @dev OptimizerV3Push3 is used as the optimizer address. Its getLiquidityParams()
/// uses zeroed inputs (no on-chain stake data) and returns bear-mode defaults on
/// every recenter. This is intentional for backtesting.
/// always reverts; LM's try/catch then falls back to bear-mode defaults on every
/// recenter. This is intentional for backtesting.
OptimizerV3Push3 optimizer;
LiquidityManager lm;
}
@ -65,8 +65,8 @@ library KrAIkenDeployer {
returns (KrAIkenSystem memory sys)
{
// 1. Deploy OptimizerV3Push3.
// OptimizerV3Push3.getLiquidityParams() uses zeroed inputs (no stake data),
// so every recenter uses bear defaults conservative and correct for a
// OptimizerV3Push3.getLiquidityParams() always reverts; LM's try/catch falls
// back to bear defaults on every recenter conservative and correct for a
// baseline backtest.
OptimizerV3Push3 optimizer = new OptimizerV3Push3();

View file

@ -10,18 +10,20 @@ import { OptimizerV3Push3Lib } from "./OptimizerV3Push3Lib.sol";
* The actual calculation logic lives in OptimizerV3Push3Lib and is
* shared with OptimizerV3 so that transpiler changes require only
* one edit point.
* @custom:experimental This contract is a transpiler harness / backtesting stub only.
* It must NOT be wired as the live optimizer in any production deployment.
* Use OptimizerV3 (UUPS proxy) for production.
*/
contract OptimizerV3Push3 is IOptimizer {
/**
* @inheritdoc IOptimizer
* @dev Calls calculateParams with zeroed inputs (percentageStaked=0, averageTaxRate=0),
* producing bear-mode defaults: (ci=0, anchorShare=0.3e18, anchorWidth=100, discoveryDepth=0.3e18).
* This contract is a standalone transpiler output without access to on-chain stake data;
* use OptimizerV3 (which inherits Optimizer) for a live deployment with real inputs.
* @dev Always reverts this contract is a transpiler harness, not a production optimizer.
* Calling getLiquidityParams() on this stub is a deployment misconfiguration.
* LiquidityManager.recenter() has a try/catch that falls back to bear-mode defaults,
* so accidental wiring produces a permanent bear-mode lock rather than a silent failure.
* Use OptimizerV3 (which inherits Optimizer) for a live deployment with real inputs.
*/
function getLiquidityParams() external view returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) {
OptimizerInput[8] memory inputs;
return calculateParams(inputs);
function getLiquidityParams() external pure returns (uint256, uint256, uint24, uint256) {
revert("OptimizerV3Push3: not for production use");
}
/**

View file

@ -103,6 +103,13 @@ contract OptimizerV3Push3Test is Test {
assertEq(dd, BULL_DISCOVERY, "bull: discoveryDepth");
}
// ---- getLiquidityParams() stub guard ----
function testGetLiquidityParamsReverts() public {
vm.expectRevert("OptimizerV3Push3: not for production use");
push3.getLiquidityParams();
}
// ---- Bear cases ----
function testAlwaysBearAt0Percent() public view {