This commit is contained in:
JulesCrown 2024-04-11 07:28:54 +02:00
parent 2b3b981bfa
commit d9ee15f812
3 changed files with 156 additions and 65 deletions

View file

@ -80,13 +80,23 @@ contract BaseLineLP {
token0isWeth = _WETH9 < _harb;
}
event UniCallback(uint256 indexed amount0Owed, uint256 indexed amount1Owed);
function uniswapV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external {
CallbackValidation.verifyCallback(factory, poolKey);
// take care of harb
harb.mint(token0isWeth ? amount1Owed : amount0Owed);
// pack ETH
weth.deposit{value: token0isWeth ? amount0Owed : amount1Owed}();
// ## mint harb if needed
if (amount0Owed > 0) IERC20(poolKey.token0).transfer(msg.sender, amount0Owed);
if (amount1Owed > 0) IERC20(poolKey.token1).transfer(msg.sender, amount1Owed);
}
receive() external payable {
}
function createPosition(Stage positionIndex, int24 tickLower, int24 tickUpper, uint256 amount) internal {
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
@ -108,50 +118,6 @@ contract BaseLineLP {
}
// called once at the beginning
function deployLiquidity(int24 startTick, uint256 amount) external {
require(positions[Stage.FLOOR].liquidity == 0, "already set up");
require(positions[Stage.ANCHOR].liquidity == 0, "already set up");
require(positions[Stage.DISCOVERY].liquidity == 0, "already set up");
harb.mint(amount);
int24 tickLower;
int24 tickUpper;
// create floor
if (token0isWeth) {
tickLower = startTick;
tickUpper = startTick + 200;
createPosition(Stage.FLOOR, tickLower, tickUpper, amount / 10);
} else {
tickLower = startTick - 200;
tickUpper = startTick;
createPosition(Stage.FLOOR, tickLower, tickUpper, amount / 10);
}
// create anchor
if (token0isWeth) {
tickLower += 201;
tickUpper += 601;
createPosition(Stage.ANCHOR, tickLower, tickUpper, amount / 20);
} else {
tickLower -= 601;
tickUpper -= 201;
createPosition(Stage.ANCHOR, tickLower, tickUpper, amount / 10);
}
// create discovery
if (token0isWeth) {
tickLower += 601;
tickUpper += 11001;
createPosition(Stage.DISCOVERY, tickLower, tickUpper, harb.balanceOf(address(this)));
} else {
tickLower -= 11001;
tickUpper -= 601;
createPosition(Stage.DISCOVERY, tickLower, tickUpper, harb.balanceOf(address(this)));
}
}
function outstanding() public view returns (uint256 _outstanding) {
_outstanding = harb.totalSupply() - harb.balanceOf(address(pool)) - harb.balanceOf(address(this));
}
@ -174,18 +140,25 @@ contract BaseLineLP {
}
}
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
function tickAtPrice(uint256 tokenAmount, uint256 ethAmount) internal view returns (int24 tick_) {
require(ethAmount > 0, "ETH amount cannot be zero");
// 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.
int128 priceRatio = ABDKMath64x64.div(
int128(int256(tokenAmount)),
int128(int256(ethAmount))
);
// Convert the price ratio into a sqrt price in the format expected by Uniswap's TickMath.
uint160 sqrtPriceX96 = uint160(
int160(ABDKMath64x64.sqrt(priceRatio) << 32)
);
uint160 sqrtPriceX96;
if (tokenAmount == 0) {
sqrtPriceX96 = MIN_SQRT_RATIO;
} 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.
int128 priceRatio = ABDKMath64x64.div(
int128(int256(tokenAmount)),
int128(int256(ethAmount))
);
// Convert the price ratio into a sqrt price in the format expected by Uniswap's TickMath.
sqrtPriceX96 = uint160(
int160(ABDKMath64x64.sqrt(priceRatio) << 32)
);
}
// Proceed as before.
tick_ = TickMath.getTickAtSqrtRatio(sqrtPriceX96);
tick_ = tick_ / TICK_SPACING * TICK_SPACING;
@ -235,20 +208,22 @@ contract BaseLineLP {
return amount;
}
event FLOOR_TICK(int24 indexed floorTick, int24 indexed startTick);
function _set(uint160 sqrtPriceX96, int24 currentTick, uint256 ethInNewAnchor) internal {
// ### set Anchor position
uint128 anchorLiquidity;
{
int24 tickLower = currentTick - 300;
int24 tickUpper = currentTick + 300;
int24 tickLower = currentTick - 400;
int24 tickUpper = currentTick + 400;
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
if (token0isWeth) {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(
sqrtRatioAX96, sqrtRatioBX96, ethInNewAnchor
);
} else {
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(
sqrtRatioAX96, sqrtRatioBX96, ethInNewAnchor
);
}
@ -257,14 +232,16 @@ contract BaseLineLP {
// ### set Floor position
{
int24 startTick = token0isWeth ? currentTick - 301 : currentTick + 301;
int24 startTick = token0isWeth ? currentTick - 400 : currentTick + 400;
// all remaining eth will be put into this position
uint256 ethInFloor = address(this).balance;
// calculate price at which all HARB can be bought back
int24 floorTick = tickAtPrice(outstanding(), ethInFloor);
emit FLOOR_TICK(floorTick, startTick);
// put a position symetrically around the price, startTick being edge on one side
floorTick = token0isWeth ? floorTick - (startTick - floorTick) : startTick + (floorTick - startTick);
emit FLOOR_TICK(floorTick, startTick);
// calculate liquidity
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(floorTick);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(startTick);
@ -281,8 +258,8 @@ contract BaseLineLP {
// ## set Discovery position
{
int24 tickLower = token0isWeth ? currentTick + 301 : currentTick - 11301;
int24 tickUpper = token0isWeth ? currentTick + 11301 : currentTick - 301;
int24 tickLower = token0isWeth ? currentTick + 401 : currentTick - 11401;
int24 tickUpper = token0isWeth ? currentTick + 11401 : currentTick - 401;
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
// discovery with 1.5 times as much liquidity per tick as anchor
@ -316,9 +293,10 @@ contract BaseLineLP {
if(amount < harbInDiscovery) {
// calculate new ticks so that discovery liquidity is still
// deeper than anchor, but less wide
int24 tickWidth = int24(int256(11000 * amount / harbInDiscovery)) + 301;
tickLower = token0isWeth ? currentTick + 301 : currentTick - tickWidth;
tickUpper = token0isWeth ? currentTick + tickWidth : currentTick - 301;
int24 tickWidth = int24(int256(11000 * amount / harbInDiscovery)) + 401;
tickWidth = tickWidth / TICK_SPACING * TICK_SPACING;
tickLower = token0isWeth ? currentTick + 401 : currentTick - tickWidth;
tickUpper = token0isWeth ? currentTick + tickWidth : currentTick - 401;
sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
liquidity = LiquidityAmounts.getLiquidityForAmounts(
@ -423,11 +401,15 @@ contract BaseLineLP {
uint256 ethInFloor = ethIn(Stage.FLOOR);
// use previous ration of Floor to Anchor
uint256 ethInNewAnchor = ethBalance * ethInAnchor / (ethInAnchor + ethInFloor);
uint256 ethInNewAnchor = ethBalance / 10;
if (ethInFloor > 0) {
ethInNewAnchor = ethBalance * ethInAnchor / (ethInAnchor + ethInFloor);
}
// but cap anchor size at 10 % of total ETH
ethInNewAnchor = (ethInNewAnchor > ethBalance / 10) ? ethBalance / 10 : ethInNewAnchor;
currentTick = currentTick / TICK_SPACING * TICK_SPACING;
_set(sqrtPriceX96, currentTick, ethInNewAnchor);
}