priceRatio stored and used in vwap always ETH/HARB. fixed compatibility.
This commit is contained in:
parent
1dfa81ea57
commit
0329a5da4f
2 changed files with 21 additions and 16 deletions
|
|
@ -24,7 +24,7 @@ import {Harberg} from "./Harberg.sol";
|
|||
* - Discovery Position: Expands liquidity by minting new Harberg tokens as the price rises, capturing potential growth in the ecosystem.
|
||||
* The contract dynamically adjusts these positions in response to market movements to maintain strategic liquidity levels and support the Harberg token's price.
|
||||
* It also collects and transfers fees generated from trading activities to a designated fee destination.
|
||||
* @dev Utilizes Uniswap V3's concentrated liquidity feature, enabling highly efficient use of capital.
|
||||
* @dev Utilizes Uniswap V3's concentrated liquidity feature, enabling highly efficient use of capital.
|
||||
*/
|
||||
contract LiquidityManager {
|
||||
using Math for uint256;
|
||||
|
|
@ -45,7 +45,7 @@ contract LiquidityManager {
|
|||
// only working with UNI V3 1% fee tier pools
|
||||
uint24 internal constant FEE = uint24(10_000);
|
||||
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
|
||||
// ANCHOR_LIQ_SHARE is the mininum share of total ETH in control
|
||||
// ANCHOR_LIQ_SHARE is the mininum share of total ETH in control
|
||||
// that will be left to put into anchor positon.
|
||||
uint256 internal constant MIN_ANCHOR_LIQ_SHARE = 5; // 5 = 5%
|
||||
uint256 internal constant MAX_ANCHOR_LIQ_SHARE = 25;
|
||||
|
|
@ -166,7 +166,8 @@ contract LiquidityManager {
|
|||
function tickAtPrice(bool t0isWeth, uint256 tokenAmount, uint256 ethAmount) internal pure returns (int24 tick_) {
|
||||
require(ethAmount > 0, "ETH amount cannot be zero");
|
||||
if (tokenAmount == 0) {
|
||||
tick_ = t0isWeth ? TickMath.MIN_TICK : TickMath.MAX_TICK;
|
||||
// HARB/ETH
|
||||
tick_ = TickMath.MAX_TICK;
|
||||
} else {
|
||||
// Use a fixed-point library or more precise arithmetic for the division here.
|
||||
// For example, using ABDKMath64x64 for a more precise division and square root calculation.
|
||||
|
|
@ -174,17 +175,19 @@ contract LiquidityManager {
|
|||
int128(int256(tokenAmount)),
|
||||
int128(int256(ethAmount))
|
||||
);
|
||||
tick_ = tickAtPriceRatio(t0isWeth, priceRatioX64);
|
||||
// HARB/ETH
|
||||
tick_ = tickAtPriceRatio(priceRatioX64);
|
||||
}
|
||||
// convert to tick in a pool
|
||||
tick_ = t0isWeth ? tick_ : -tick_;
|
||||
}
|
||||
|
||||
function tickAtPriceRatio(bool t0isWeth, int128 priceRatioX64) internal pure returns (int24 tick_) {
|
||||
function tickAtPriceRatio(int128 priceRatioX64) internal pure returns (int24 tick_) {
|
||||
// Convert the price ratio into a sqrt price in the format expected by Uniswap's TickMath.
|
||||
uint160 sqrtPriceX96 = uint160(
|
||||
int160(ABDKMath64x64.sqrt(priceRatioX64) << 32)
|
||||
);
|
||||
tick_ = TickMath.getTickAtSqrtRatio(sqrtPriceX96);
|
||||
tick_ = t0isWeth ? tick_ : -tick_;
|
||||
}
|
||||
|
||||
/// @notice Calculates the price ratio from a given Uniswap V3 tick as HARB/ETH.
|
||||
|
|
@ -241,16 +244,17 @@ contract LiquidityManager {
|
|||
// not enough ETH, find a lower price
|
||||
requiredEthForBuyback = floorEthBalance;
|
||||
vwapTick = tickAtPrice(token0isWeth, outstandingSupply * capitalInfefficiency / 100 , requiredEthForBuyback);
|
||||
emit EthScarcity(currentTick, ethBalance, outstandingSupply, vwapX96, capitalInfefficiency, anchorLiquidityShare, vwapTick);
|
||||
emit EthScarcity(currentTick, ethBalance, outstandingSupply, vwapX96, capitalInfefficiency, anchorLiquidityShare, vwapTick);
|
||||
} else if (vwapX96 == 0) {
|
||||
requiredEthForBuyback = floorEthBalance;
|
||||
vwapTick = currentTick;
|
||||
} else {
|
||||
// recalculate vwap with capital inefficiency
|
||||
vwapX96 = cumulativeVolumeWeightedPriceX96 * capitalInfefficiency / 100 / cumulativeVolume; // in harb/eth
|
||||
vwapTick = tickAtPriceRatio(token0isWeth, int128(int256 (vwapX96 >> 32)));
|
||||
|
||||
vwapTick = token0isWeth ? vwapTick : -vwapTick;
|
||||
// ETH/HARB tick
|
||||
vwapTick = tickAtPriceRatio(int128(int256(vwapX96 >> 32)));
|
||||
// convert to pool tick
|
||||
vwapTick = token0isWeth ? -vwapTick : vwapTick;
|
||||
emit EthAbundance(currentTick, ethBalance, outstandingSupply, vwapX96, capitalInfefficiency, anchorLiquidityShare, vwapTick);
|
||||
}
|
||||
// never make floor smaller than anchor
|
||||
|
|
@ -265,7 +269,7 @@ contract LiquidityManager {
|
|||
vwapTick = (vwapTick > currentTick - ANCHOR_SPACING) ? currentTick - ANCHOR_SPACING : vwapTick;
|
||||
}
|
||||
|
||||
// normalize tick position for pool
|
||||
// normalize tick position for pool
|
||||
vwapTick = vwapTick / TICK_SPACING * TICK_SPACING;
|
||||
// calculate liquidity
|
||||
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(vwapTick);
|
||||
|
|
@ -336,7 +340,7 @@ contract LiquidityManager {
|
|||
);
|
||||
}
|
||||
_mint(Stage.DISCOVERY, tickLower, tickUpper, liquidity);
|
||||
harb.burn(harb.balanceOf(address(this)));
|
||||
harb.burn(harb.balanceOf(address(this)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ contract LiquidityManagerTest is Test {
|
|||
lm = new LiquidityManager(factoryAddress, address(weth), address(harberg));
|
||||
lm.setFeeDestination(feeDestination);
|
||||
harberg.setLiquidityManager(address(lm));
|
||||
harberg.setLiquidityPool(address(pool));
|
||||
vm.deal(address(lm), 10 ether);
|
||||
createCSVHeader();
|
||||
}
|
||||
|
|
@ -137,7 +138,7 @@ contract LiquidityManagerTest is Test {
|
|||
vm.warp(timeBefore + (60 * 60 * 5));
|
||||
|
||||
try lm.recenter() {
|
||||
|
||||
|
||||
// Check liquidity positions after slide
|
||||
(uint256 ethFloor, uint256 ethAnchor, uint256 ethDiscovery, uint256 harbergFloor, uint256 harbergAnchor, uint256 harbergDiscovery) = checkLiquidityPositionsAfter("slide");
|
||||
assertGt(ethFloor, ethAnchor, "slide - Floor should hold more ETH than Anchor");
|
||||
|
|
@ -180,7 +181,7 @@ contract LiquidityManagerTest is Test {
|
|||
function getBalancesPool(LiquidityManager.Stage s) internal view returns (int24 currentTick, int24 tickLower, int24 tickUpper, uint256 ethAmount, uint256 harbergAmount) {
|
||||
(,tickLower, tickUpper) = lm.positions(s);
|
||||
(uint128 liquidity, , , ,) = pool.positions(keccak256(abi.encodePacked(address(lm), tickLower, tickUpper)));
|
||||
|
||||
|
||||
// Fetch the current price from the pool
|
||||
uint160 sqrtPriceX96;
|
||||
(sqrtPriceX96, currentTick, , , , , ) = pool.slot0();
|
||||
|
|
@ -425,7 +426,7 @@ contract LiquidityManagerTest is Test {
|
|||
// assertEq(ethDiscovery, 0, "Discovery should not have ETH");
|
||||
// assertEq(harbergFloor, 0, "Floor should have no HARB");
|
||||
// assertGt(harbergAnchor, 0, "Anchor should have HARB");
|
||||
// assertGt(harbergDiscovery, 0, "Discovery should have HARB");
|
||||
// assertGt(harbergDiscovery, 0, "Discovery should have HARB");
|
||||
|
||||
// // Introduce large buy to push into discovery
|
||||
// buy(3 ether);
|
||||
|
|
@ -619,4 +620,4 @@ contract LiquidityManagerTest is Test {
|
|||
assertGt(traderBalanceBefore, traderBalanceAfter, "trader should not have made profit");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue