// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "forge-std/console.sol"; import {TwabController} from "pt-v5-twab-controller/TwabController.sol"; import {PoolAddress, PoolKey} from "@aperture/uni-v3-lib/PoolAddress.sol"; import "@uniswap-v3-core/interfaces/IUniswapV3Factory.sol"; import "@uniswap-v3-core/interfaces/IUniswapV3Pool.sol"; import "../src/interfaces/IWETH9.sol"; import "../src/Harb.sol"; import {BaseLineLP} from "../src/BaseLineLP.sol"; import {Stake, ExceededAvailableStake} from "../src/Stake.sol"; address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address constant V3_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984; address constant TAX_POOL = address(2); // default fee of 1% uint24 constant FEE = uint24(10_000); contract BaseLineLPTest is Test { uint256 mainnetFork; IWETH9 weth; Harb harb; IUniswapV3Factory factory; Stake stake; BaseLineLP liquidityManager; function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } // z is now the integer square root of y, or the closest integer to the square root of y. } function initializePoolFor1Cent(bool isEthToken0, address pool) public { uint256 price; if (isEthToken0) { // ETH as token0, so we are setting the price of 1 ETH in terms of token1 (USD cent) price = 3700 * 10**20; // 1 ETH = 3700 USD, scaled by 10^18 for precision } else { // Token (valued at 1 USD cent) as token0, ETH as token1 // We invert the logic to represent the price of 1 token in terms of ETH price = uint256(10**16) / 3700; // Adjust for 18 decimal places } uint160 sqrtPriceX96 = uint160(sqrt(price) * 2**96 / 10**18); // Adjust sqrt value to 96-bit precision // Initialize pool with the calculated sqrtPriceX96 IUniswapV3Pool(pool).initialize(sqrtPriceX96); } function setUp() public { mainnetFork = vm.createFork(vm.envString("ETH_NODE_URI_MAINNET"), 19615864); vm.selectFork(mainnetFork); weth = IWETH9(WETH); TwabController tc = new TwabController(60 * 60 * 24, uint32(block.timestamp)); harb = new Harb("HARB", "HARB", V3_FACTORY, WETH, tc); factory = IUniswapV3Factory(V3_FACTORY); address pool = factory.createPool(address(weth), address(harb), FEE); initializePoolFor1Cent(address(weth) < address(harb), pool); stake = new Stake(address(harb)); harb.setStakingPool(address(stake)); liquidityManager = new BaseLineLP(V3_FACTORY, WETH, address(harb)); harb.setLiquidityManager(address(liquidityManager)); } function testLP(address account) public { vm.assume(account != address(0)); vm.assume(account != address(1)); // TWAB sponsorship address vm.assume(account != address(2)); // tax pool address vm.deal(account, 10 ether); vm.prank(account); (bool sent, ) = address(liquidityManager).call{value: 10 ether}(""); require(sent, "Failed to send Ether"); vm.expectRevert(); liquidityManager.shift(); liquidityManager.slide(); } }