harb/onchain/script/backtesting/KrAIkenDeployer.sol

101 lines
4.3 KiB
Solidity
Raw Normal View History

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.19;
import { MockToken } from "./MockToken.sol";
import { BacktestKraiken } from "./BacktestKraiken.sol";
import { OptimizerV3Push3 } from "../../src/OptimizerV3Push3.sol";
import { LiquidityManager } from "../../src/LiquidityManager.sol";
/**
* @notice Deployment result for the KrAIken system on the shadow pool.
*/
struct KrAIkenSystem {
BacktestKraiken kraiken;
/// @dev OptimizerV3Push3 is used as the optimizer address. It does not implement
/// getLiquidityParams(), so LiquidityManager's try/catch falls back to safe
/// bear-mode defaults on every recenter. This is intentional for backtesting.
OptimizerV3Push3 optimizer;
LiquidityManager lm;
}
/**
* @title KrAIkenDeployer
* @notice Library that deploys the KrAIken protocol contracts on top of a shadow pool
* for backtesting purposes.
*
* Deployment order follows DeployLocal.sol:
* 1. Deploy OptimizerV3Push3 (no proxy it only exposes isBullMarket(), so LM falls
* back to bear-mode defaults via try/catch on every recenter call).
* 2. Deploy LiquidityManager pointing at the shadow factory + mock WETH + BacktestKraiken.
* 3. Wire BacktestKraiken LM (setLiquidityManager).
* 4. Set fee destination on LM.
* 5. Fund LM with mock WETH (initial capital).
*
* @dev All functions are `internal` so they are inlined into BacktestRunner.s.sol,
* keeping msg.sender consistent with the broadcaster throughout deployment.
*/
library KrAIkenDeployer {
uint256 internal constant DEFAULT_INITIAL_CAPITAL = 10 ether;
/**
* @notice Deploy the KrAIken system with default initial capital (10 ETH equivalent).
*/
function deploy(
address shadowFactory,
address mockWeth,
address krkToken,
address feeDestination
)
internal
returns (KrAIkenSystem memory sys)
{
return deploy(shadowFactory, mockWeth, krkToken, feeDestination, DEFAULT_INITIAL_CAPITAL);
}
/**
* @notice Deploy the KrAIken system with configurable initial capital.
*
* @param shadowFactory Factory that created the shadow pool.
* @param mockWeth Mock WETH token address (18-decimal ERC-20, freely mintable).
* @param krkToken BacktestKraiken token address (setLiquidityManager not yet called).
* @param feeDestination Address that will receive LP fees; also used as the caller
* for subsequent setRecenterAccess() calls.
* @param initialCapital Mock WETH minted to LM so recenter() has capital to deploy.
*/
function deploy(
address shadowFactory,
address mockWeth,
address krkToken,
address feeDestination,
uint256 initialCapital
)
internal
returns (KrAIkenSystem memory sys)
{
// 1. Deploy OptimizerV3Push3.
// LiquidityManager wraps getLiquidityParams() in a try/catch and falls back to
// safe bear-mode defaults when the call reverts. Since OptimizerV3Push3 only
// exposes isBullMarket(), every recenter uses bear defaults — conservative and
// correct for a baseline backtest.
OptimizerV3Push3 optimizer = new OptimizerV3Push3();
// 2. Deploy LiquidityManager. It computes the pool address from factory + WETH +
// KRK + FEE (10 000). The shadow pool must have been created with the same
// factory and the same fee tier (ShadowPoolDeployer.SHADOW_FEE == 10 000).
LiquidityManager lm = new LiquidityManager(shadowFactory, mockWeth, krkToken, address(optimizer));
// 3. Wire BacktestKraiken → LM so the restricted mint/burn functions work.
BacktestKraiken(krkToken).setLiquidityManager(address(lm));
// 4. Set fee destination (required before setRecenterAccess can be called).
lm.setFeeDestination(feeDestination);
// 5. Fund LM with mock WETH. recenter() uses _getEthBalance() which reads
// weth.balanceOf(address(this)). Pre-funding avoids calling weth.deposit()
// (which MockToken does not implement).
MockToken(mockWeth).mint(address(lm), initialCapital);
sys = KrAIkenSystem({ kraiken: BacktestKraiken(krkToken), optimizer: optimizer, lm: lm });
}
}