diff --git a/onchain/src/abstracts/ThreePositionStrategy.sol b/onchain/src/abstracts/ThreePositionStrategy.sol index f94925f..75efcf0 100644 --- a/onchain/src/abstracts/ThreePositionStrategy.sol +++ b/onchain/src/abstracts/ThreePositionStrategy.sol @@ -202,7 +202,10 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker { int24 vwapTick; if (vwapX96 > 0) { - uint256 requiredEthForBuyback = outstandingSupply.mulDiv(vwapX96, (1 << 96)); + // vwapX96 is price² in X96 format, need to convert to regular price + // price = sqrt(price²) = sqrt(vwapX96) * 2^48 / 2^96 = sqrt(vwapX96) / 2^48 + uint256 sqrtVwapX96 = Math.sqrt(vwapX96) << 48; // sqrt(price²) in X96 format + uint256 requiredEthForBuyback = outstandingSupply.mulDiv(sqrtVwapX96, (1 << 96)); if (floorEthBalance < requiredEthForBuyback) { // ETH scarcity: not enough ETH to buy back at VWAP price @@ -211,7 +214,10 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker { emit EthScarcity(currentTick, ethBalance, outstandingSupply, vwapX96, vwapTick); } else { // ETH abundance: sufficient ETH reserves - vwapTick = _tickAtPriceRatio(int128(int256(vwapX96 >> 32))); + // vwapX96 is price² in X96 format, need to convert to regular price in X64 format + // price = sqrt(price²), then convert from X96 to X64 by >> 32 + uint256 sqrtVwapX96Abundance = Math.sqrt(vwapX96) << 48; // sqrt(price²) in X96 format + vwapTick = _tickAtPriceRatio(int128(int256(sqrtVwapX96Abundance >> 32))); vwapTick = token0isWeth ? -vwapTick : vwapTick; emit EthAbundance(currentTick, ethBalance, outstandingSupply, vwapX96, vwapTick); } diff --git a/onchain/test/mocks/BullMarketOptimizer.sol b/onchain/test/mocks/BullMarketOptimizer.sol index 39f4f46..eae16f0 100644 --- a/onchain/test/mocks/BullMarketOptimizer.sol +++ b/onchain/test/mocks/BullMarketOptimizer.sol @@ -15,23 +15,23 @@ contract BullMarketOptimizer { return 0; // Placeholder implementation } - /// @notice Returns whale attack liquidity parameters - /// @return capitalInefficiency 0% - very aggressive - /// @return anchorShare 95% - massive anchor concentration - /// @return anchorWidth 1000 - moderate width - /// @return discoveryDepth Testing value: 1e18 + /// @notice Returns bull market liquidity parameters + /// @return capitalInefficiency 0% - aggressive bull market stance + /// @return anchorShare 95% - reduces floor allocation to 90.1% + /// @return anchorWidth 50 - medium width for concentrated liquidity + /// @return discoveryDepth 1e18 - maximum discovery depth function getLiquidityParams() external pure returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) { - capitalInefficiency = 0; // 0% - very aggressive - anchorShare = 95 * 10 ** 16; // 95% - massive anchor position + capitalInefficiency = 0; // 0% - aggressive bull market stance + anchorShare = 95 * 10 ** 16; // 95% - reduces floor to 90.1% of ETH anchorWidth = 50; // 50% - medium width for concentrated liquidity - discoveryDepth = 1e18; // Testing this value + discoveryDepth = 1e18; // Maximum discovery depth } function getDescription() external pure returns (string memory) { - return "Bull Market (Testing discoveryDepth)"; + return "Bull Market (Aggressive)"; } }