This commit is contained in:
johba 2025-07-25 19:09:11 +02:00
parent f710750e87
commit 1dad2fb12a
5 changed files with 56 additions and 56 deletions

View file

@ -24,8 +24,8 @@ import {Stake, ExceededAvailableStake} from "../src/Stake.sol";
import {LiquidityManager} from "../src/LiquidityManager.sol";
import {ThreePositionStrategy} from "../src/abstracts/ThreePositionStrategy.sol";
import "../src/helpers/UniswapHelpers.sol";
import {UniswapTestBase} from "./helpers/UniswapTestBase.sol";
import {LiquidityManagerSetupHelper} from "./helpers/TestBase.sol";
import {UniSwapHelper} from "./helpers/UniswapTestBase.sol";
import {TestEnvironment} from "./helpers/TestBase.sol";
import "../src/Optimizer.sol";
import "../test/mocks/MockOptimizer.sol";
@ -63,7 +63,7 @@ contract Dummy {
// This contract can be empty as it is only used to affect the nonce
}
contract LiquidityManagerTest is UniswapTestBase {
contract LiquidityManagerTest is UniSwapHelper {
// Constant address for recenter operations
address constant RECENTER_CALLER = address(0x7777);
// Setup configuration
@ -81,8 +81,8 @@ contract LiquidityManagerTest is UniswapTestBase {
Optimizer optimizer;
address feeDestination = makeAddr("fees");
// Setup helper instance
LiquidityManagerSetupHelper setupHelper;
// Test environment instance
TestEnvironment testEnv;
struct Response {
uint256 ethFloor;
@ -99,24 +99,24 @@ contract LiquidityManagerTest is UniswapTestBase {
int24 discoveryTickUpper;
}
/// @notice Utility to deploy dummy contracts for address manipulation
/// @notice Manipulate nonce by deploying dummy contracts
/// @param count Number of dummy contracts to deploy
/// @dev Used to manipulate contract deployment addresses for token ordering
function deployDummies(uint256 count) internal {
/// @dev Used to control contract deployment addresses for token ordering
function manipulateNonce(uint256 count) internal {
for (uint256 i = 0; i < count; i++) {
new Dummy(); // Just increment the nonce
}
}
/// @notice Main setup function with custom token order
/// @notice Deploy protocol with specific token ordering
/// @param token0shouldBeWeth Whether token0 should be WETH (affects pool pair ordering)
function setUpCustomToken0(bool token0shouldBeWeth) public {
// Create setup helper if not already created
if (address(setupHelper) == address(0)) {
setupHelper = new LiquidityManagerSetupHelper(feeDestination);
function deployProtocolWithTokenOrder(bool token0shouldBeWeth) public {
// Create test environment if not already created
if (address(testEnv) == address(0)) {
testEnv = new TestEnvironment(feeDestination);
}
// Use helper to set up environment
// Use test environment to set up protocol
(
IUniswapV3Factory _factory,
IUniswapV3Pool _pool,
@ -126,7 +126,7 @@ contract LiquidityManagerTest is UniswapTestBase {
LiquidityManager _lm,
Optimizer _optimizer,
bool _token0isWeth
) = setupHelper.setupEnvironment(token0shouldBeWeth, RECENTER_CALLER);
) = testEnv.setupEnvironment(token0shouldBeWeth, RECENTER_CALLER);
// Assign to state variables
factory = _factory;
@ -139,12 +139,12 @@ contract LiquidityManagerTest is UniswapTestBase {
token0isWeth = _token0isWeth;
}
/// @notice Intelligent recenter function that handles extreme price conditions
/// @notice Recenter with intelligent error handling for extreme price conditions
/// @param last Whether this is the last attempt (affects error handling)
function recenter(bool last) internal {
function recenterWithErrorHandling(bool last) internal {
_updateOracleTime();
_handleExtremePrice();
_attemptRecenter(last);
normalizeExtremePrice();
executeRecenter(last);
}
/// @notice Updates oracle time to ensure accurate price data
@ -153,15 +153,15 @@ contract LiquidityManagerTest is UniswapTestBase {
vm.warp(timeBefore + ORACLE_UPDATE_INTERVAL);
}
/// @notice Handles extreme price conditions with normalizing swaps
function _handleExtremePrice() internal {
// Use the unified extreme price handling from UniswapTestBase
/// @notice Normalize extreme price conditions with corrective swaps
function normalizeExtremePrice() internal {
// Use the unified extreme price handling from UniSwapHelper
handleExtremePrice();
}
/// @notice Attempts the recenter operation with proper error handling
/// @notice Execute recenter operation with authorization
/// @param last Whether this is the last attempt (affects error handling)
function _attemptRecenter(bool last) internal {
function executeRecenter(bool last) internal {
vm.prank(RECENTER_CALLER);
try lm.recenter() returns (bool isUp) {
_validateRecenterResult(isUp);
@ -174,7 +174,7 @@ contract LiquidityManagerTest is UniswapTestBase {
/// @notice Validates recenter operation results
/// @param isUp Whether the recenter moved positions up or down
function _validateRecenterResult(bool isUp) internal view {
Response memory liquidityResponse = checkLiquidity(isUp ? "shift" : "slide");
Response memory liquidityResponse = inspectPositions(isUp ? "shift" : "slide");
// Debug logging
console.log("=== POSITION ANALYSIS ===");
@ -297,7 +297,7 @@ contract LiquidityManagerTest is UniswapTestBase {
/// @notice Checks and validates current liquidity positions across all stages
/// @return liquidityResponse Structure containing ETH and HARB amounts for each position
/// @dev Aggregates position data from FLOOR, ANCHOR, and DISCOVERY stages
function checkLiquidity(string memory /* eventName */ ) internal view returns (Response memory) {
function inspectPositions(string memory /* eventName */ ) internal view returns (Response memory) {
Response memory liquidityResponse;
int24 currentTick;
@ -339,7 +339,7 @@ contract LiquidityManagerTest is UniswapTestBase {
uint256 limit = buyLimitToLiquidityBoundary();
uint256 cappedAmount = (limit > 0 && amountEth > limit) ? limit : amountEth;
buyRaw(cappedAmount);
checkLiquidity("buy");
inspectPositions("buy");
}
/// @notice Executes a sell operation (HARB -> ETH) with liquidity boundary checking
@ -349,7 +349,7 @@ contract LiquidityManagerTest is UniswapTestBase {
uint256 limit = sellLimitToLiquidityBoundary();
uint256 cappedAmount = (limit > 0 && amountHarb > limit) ? limit : amountHarb;
sellRaw(cappedAmount);
checkLiquidity("sell");
inspectPositions("sell");
}
/// @notice Allows contract to receive ETH directly
@ -371,12 +371,12 @@ contract LiquidityManagerTest is UniswapTestBase {
function setUp() public {
if (!_skipAutoSetup) {
_commonSetup(DEFAULT_TOKEN0_IS_WETH, DEFAULT_ACCOUNT_BALANCE);
deployAndFundProtocol(DEFAULT_TOKEN0_IS_WETH, DEFAULT_ACCOUNT_BALANCE);
}
}
/// @notice Call this in tests that need custom setup to skip automatic setUp
function _skipSetup() internal {
/// @notice Disable automatic setUp for tests that need custom initialization
function disableAutoSetup() internal {
_skipAutoSetup = true;
}
@ -388,15 +388,15 @@ contract LiquidityManagerTest is UniswapTestBase {
/// @notice Setup with custom parameters but standard flow
function _setupCustom(bool token0IsWeth, uint256 accountBalance) internal {
_skipSetup();
_commonSetup(token0IsWeth, accountBalance);
disableAutoSetup();
deployAndFundProtocol(token0IsWeth, accountBalance);
}
/// @notice Common setup for most tests
/// @notice Deploy and fund protocol for testing
/// @param token0IsWeth Whether token0 should be WETH
/// @param accountBalance How much ETH to give to account
function _commonSetup(bool token0IsWeth, uint256 accountBalance) internal {
setUpCustomToken0(token0IsWeth);
function deployAndFundProtocol(bool token0IsWeth, uint256 accountBalance) internal {
deployProtocolWithTokenOrder(token0IsWeth);
// Fund account and convert to WETH
vm.deal(account, accountBalance);
@ -404,7 +404,7 @@ contract LiquidityManagerTest is UniswapTestBase {
weth.deposit{value: accountBalance}();
// Setup initial liquidity
recenter(false);
recenterWithErrorHandling(false);
}
// ========================================
@ -416,10 +416,10 @@ contract LiquidityManagerTest is UniswapTestBase {
/// without system failure. Tests system stability at tick boundaries.
function testTickBoundaryReaching() public {
// Skip automatic setup to reduce blocking liquidity
_skipSetup();
disableAutoSetup();
// Custom minimal setup
setUpCustomToken0(DEFAULT_TOKEN0_IS_WETH);
deployProtocolWithTokenOrder(DEFAULT_TOKEN0_IS_WETH);
vm.deal(account, 15000 ether);
vm.prank(account);
weth.deposit{value: 15000 ether}();
@ -715,7 +715,7 @@ contract LiquidityManagerTest is UniswapTestBase {
// Test the intelligent recenter with diagnostics
console.log("\n=== PHASE 2: Test intelligent recenter ===");
recenter(false);
recenterWithErrorHandling(false);
// Check final state
(, int24 finalTick,,,,,) = pool.slot0();
@ -815,7 +815,7 @@ contract LiquidityManagerTest is UniswapTestBase {
// Periodic recentering based on frequency
if (recenterFrequencyCounter >= frequency) {
recenter(false);
recenterWithErrorHandling(false);
recenterFrequencyCounter = 0;
} else {
recenterFrequencyCounter++;
@ -827,7 +827,7 @@ contract LiquidityManagerTest is UniswapTestBase {
if (finalHarbBal > 0) {
sell(finalHarbBal);
}
recenter(true);
recenterWithErrorHandling(true);
}
@ -859,10 +859,10 @@ contract LiquidityManagerTest is UniswapTestBase {
// Phase 2: Trigger recenter to rebalance liquidity positions
console.log("\n=== PHASE 2: Recenter Operation ===");
recenter(false);
recenterWithErrorHandling(false);
// Record liquidity distribution after recenter
Response memory liquidity = checkLiquidity("after-recenter");
Response memory liquidity = inspectPositions("after-recenter");
console.log("Post-recenter - Floor ETH:", liquidity.ethFloor / 1e18);
console.log("Post-recenter - Anchor ETH:", liquidity.ethAnchor / 1e18);
console.log("Post-recenter - Discovery ETH:", liquidity.ethDiscovery / 1e18);

View file

@ -7,7 +7,7 @@ import "../src/Kraiken.sol";
import {TooMuchSnatch, Stake} from "../src/Stake.sol";
import "./helpers/TestBase.sol";
contract StakeTest is TestUtilities {
contract StakeTest is TestConstants {
Kraiken kraiken;
Stake stakingPool;
address liquidityPool;

View file

@ -132,7 +132,7 @@ contract MockThreePositionStrategy is ThreePositionStrategy {
}
}
contract ThreePositionStrategyTest is TestUtilities {
contract ThreePositionStrategyTest is TestConstants {
MockThreePositionStrategy strategy;
address constant HARB_TOKEN = address(0x1234);

View file

@ -21,11 +21,11 @@ uint256 constant INITIAL_LM_ETH_BALANCE = 50 ether;
uint256 constant ORACLE_UPDATE_INTERVAL = 5 hours;
/**
* @title TestBase
* @notice Base contract providing shared utilities, default parameters, and setup functions for tests and scripts
* @dev Consolidates common test functionality to reduce code duplication
* @title TestConstants
* @notice Base contract providing shared constants and default parameters for tests
* @dev Consolidates common test constants to reduce code duplication
*/
abstract contract TestUtilities is Test {
abstract contract TestConstants is Test {
/**
* @notice Returns default parameters for ThreePositionStrategy testing
* @return Default PositionParams structure with standard values
@ -60,11 +60,11 @@ abstract contract TestUtilities is Test {
}
/**
* @title LiquidityManagerSetupHelper
* @notice Helper contract that provides common setup functionality for LiquidityManager tests and scripts
* @title TestEnvironment
* @notice Helper contract that provides test environment setup for LiquidityManager tests and scripts
* @dev Extracted from LiquidityManager.t.sol to enable reuse without inheritance
*/
contract LiquidityManagerSetupHelper is TestUtilities {
contract TestEnvironment is TestConstants {
using UniswapHelpers for IUniswapV3Pool;
// Core contracts

View file

@ -11,10 +11,10 @@ import {Kraiken} from "../../src/Kraiken.sol";
import {ThreePositionStrategy} from "../../src/abstracts/ThreePositionStrategy.sol";
/**
* @title UniswapTestBase
* @dev Base contract for Uniswap V3 testing, providing reusable swap logic.
* @title UniSwapHelper
* @dev Helper contract for Uniswap V3 testing, providing reusable swap logic.
*/
abstract contract UniswapTestBase is Test {
abstract contract UniSwapHelper is Test {
address account = makeAddr("alice");
IUniswapV3Pool public pool;
IWETH9 public weth;