feat: Optimize discovery position depth calculation
- Implement dynamic discovery depth based on anchor position share - Add configurable discovery_max_multiple (1.5-4x) for flexible adjustment - Update BullMarketOptimizer with new depth calculation logic - Fix scenario visualizer floor position visibility - Add comprehensive tests for discovery depth behavior The discovery position now dynamically adjusts its depth based on the anchor position's share of total liquidity, allowing for more effective price discovery while maintaining protection against manipulation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7ac6b33850
commit
2205ae719b
8 changed files with 383 additions and 95 deletions
|
|
@ -76,13 +76,13 @@ contract MockThreePositionStrategy is ThreePositionStrategy {
|
|||
}
|
||||
|
||||
function setAnchorPosition(int24 currentTick, uint256 anchorEthBalance, PositionParams memory params)
|
||||
external returns (uint256) {
|
||||
external returns (uint256, uint128) {
|
||||
return _setAnchorPosition(currentTick, anchorEthBalance, params);
|
||||
}
|
||||
|
||||
function setDiscoveryPosition(int24 currentTick, uint256 pulledHarb, PositionParams memory params)
|
||||
function setDiscoveryPosition(int24 currentTick, uint128 anchorLiquidity, PositionParams memory params)
|
||||
external returns (uint256) {
|
||||
return _setDiscoveryPosition(currentTick, pulledHarb, params);
|
||||
return _setDiscoveryPosition(currentTick, anchorLiquidity, params);
|
||||
}
|
||||
|
||||
function setFloorPosition(
|
||||
|
|
@ -163,7 +163,7 @@ contract ThreePositionStrategyTest is TestConstants {
|
|||
ThreePositionStrategy.PositionParams memory params = getDefaultParams();
|
||||
uint256 anchorEthBalance = 20 ether; // 20% of total
|
||||
|
||||
uint256 pulledHarb = strategy.setAnchorPosition(CURRENT_TICK, anchorEthBalance, params);
|
||||
(uint256 pulledHarb, ) = strategy.setAnchorPosition(CURRENT_TICK, anchorEthBalance, params);
|
||||
|
||||
// Verify position was created
|
||||
assertEq(strategy.getMintedPositionsCount(), 1, "Should have minted one position");
|
||||
|
|
@ -212,16 +212,26 @@ contract ThreePositionStrategyTest is TestConstants {
|
|||
|
||||
function testDiscoveryPositionDependsOnAnchor() public {
|
||||
ThreePositionStrategy.PositionParams memory params = getDefaultParams();
|
||||
uint256 pulledHarb = 1000 ether; // Simulated from anchor
|
||||
uint128 anchorLiquidity = 1000e18; // Simulated anchor liquidity
|
||||
|
||||
uint256 discoveryAmount = strategy.setDiscoveryPosition(CURRENT_TICK, pulledHarb, params);
|
||||
uint256 discoveryAmount = strategy.setDiscoveryPosition(CURRENT_TICK, anchorLiquidity, params);
|
||||
|
||||
// Discovery amount should be proportional to pulledHarb
|
||||
// Discovery amount should be proportional to anchor liquidity
|
||||
assertGt(discoveryAmount, 0, "Discovery amount should be positive");
|
||||
assertGt(discoveryAmount, pulledHarb / 100, "Discovery should be meaningful portion of pulled HARB");
|
||||
|
||||
MockThreePositionStrategy.MintedPosition memory pos = strategy.getMintedPosition(0);
|
||||
assertEq(uint256(pos.stage), uint256(ThreePositionStrategy.Stage.DISCOVERY), "Should be discovery position");
|
||||
|
||||
// Discovery liquidity should ensure multiple times more liquidity per tick
|
||||
uint256 expectedMultiplier = 200 + (800 * params.discoveryDepth / 10 ** 18);
|
||||
// Calculate anchor width (same calculation as in _setDiscoveryPosition)
|
||||
int24 anchorSpacing = 200 + (34 * int24(params.anchorWidth) * 200 / 100);
|
||||
int24 anchorWidth = 2 * anchorSpacing;
|
||||
// Adjust for width difference
|
||||
uint128 expectedLiquidity = uint128(
|
||||
uint256(anchorLiquidity) * expectedMultiplier * 11000 / (100 * uint256(int256(anchorWidth)))
|
||||
);
|
||||
assertEq(pos.liquidity, expectedLiquidity, "Discovery liquidity should match expected multiple adjusted for width");
|
||||
}
|
||||
|
||||
function testDiscoveryPositionPlacement() public {
|
||||
|
|
@ -231,8 +241,8 @@ contract ThreePositionStrategyTest is TestConstants {
|
|||
// Test with WETH as token0
|
||||
strategy = new MockThreePositionStrategy(HARB_TOKEN, WETH_TOKEN, token0IsWeth, ETH_BALANCE, OUTSTANDING_SUPPLY);
|
||||
|
||||
uint256 pulledHarb = 1000 ether;
|
||||
strategy.setDiscoveryPosition(CURRENT_TICK, pulledHarb, params);
|
||||
uint128 anchorLiquidity = 1000e18;
|
||||
strategy.setDiscoveryPosition(CURRENT_TICK, anchorLiquidity, params);
|
||||
|
||||
MockThreePositionStrategy.MintedPosition memory pos = strategy.getMintedPosition(0);
|
||||
|
||||
|
|
@ -245,12 +255,12 @@ contract ThreePositionStrategyTest is TestConstants {
|
|||
ThreePositionStrategy.PositionParams memory params = getDefaultParams();
|
||||
params.discoveryDepth = 10 ** 18; // Maximum depth (100%)
|
||||
|
||||
uint256 pulledHarb = 1000 ether;
|
||||
uint256 discoveryAmount1 = strategy.setDiscoveryPosition(CURRENT_TICK, pulledHarb, params);
|
||||
uint128 anchorLiquidity = 1000e18;
|
||||
uint256 discoveryAmount1 = strategy.setDiscoveryPosition(CURRENT_TICK, anchorLiquidity, params);
|
||||
|
||||
strategy.clearMintedPositions();
|
||||
params.discoveryDepth = 0; // Minimum depth
|
||||
uint256 discoveryAmount2 = strategy.setDiscoveryPosition(CURRENT_TICK, pulledHarb, params);
|
||||
uint256 discoveryAmount2 = strategy.setDiscoveryPosition(CURRENT_TICK, anchorLiquidity, params);
|
||||
|
||||
assertGt(discoveryAmount1, discoveryAmount2, "Higher discovery depth should result in more tokens");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue