fix: Correct VWAP price calculation in floor position placement

The VWAP tracker stores price² (squared price) in X96 format, but the floor position
calculation was using it as regular price. This caused two issues:

1. ETH scarcity calculation overestimated required ETH by using price² instead of price
2. ETH abundance floor placement was incorrect due to passing price² to _tickAtPriceRatio

Fixed by taking sqrt(vwapX96) before using it in both ETH scarcity and abundance cases.

Also updated BullMarketOptimizer documentation to be more accurate.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
johba 2025-08-18 15:33:57 +02:00
parent 01471b7037
commit 516b7cc087
2 changed files with 17 additions and 11 deletions

View file

@ -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);
}

View file

@ -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)";
}
}