wip shift
This commit is contained in:
parent
0edf05a32d
commit
8f7b426daa
1 changed files with 38 additions and 12 deletions
|
|
@ -9,6 +9,7 @@ import "@aperture/uni-v3-lib/LiquidityAmounts.sol";
|
|||
import "@aperture/uni-v3-lib/PoolAddress.sol";
|
||||
import "@aperture/uni-v3-lib/CallbackValidation.sol";
|
||||
import "@openzeppelin/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/utils/math/SignedMath.sol";
|
||||
import {ABDKMath64x64} from "@abdk/ABDKMath64x64.sol";
|
||||
import "./interfaces/IWETH9.sol";
|
||||
import {Harb} from "./Harb.sol";
|
||||
|
|
@ -89,7 +90,10 @@ contract BaseLineLP {
|
|||
// take care of harb
|
||||
harb.mint(token0isWeth ? amount1Owed : amount0Owed);
|
||||
// pack ETH
|
||||
weth.deposit{value: token0isWeth ? amount0Owed : amount1Owed}();
|
||||
uint256 ethOwed = token0isWeth ? amount0Owed : amount1Owed;
|
||||
if (weth.balanceOf(address(this)) < ethOwed) {
|
||||
weth.deposit{value: address(this).balance}();
|
||||
}
|
||||
// do transfers
|
||||
if (amount0Owed > 0) IERC20(poolKey.token0).transfer(msg.sender, amount0Owed);
|
||||
if (amount1Owed > 0) IERC20(poolKey.token1).transfer(msg.sender, amount1Owed);
|
||||
|
|
@ -128,28 +132,30 @@ contract BaseLineLP {
|
|||
return (lastDay, mintedToday);
|
||||
}
|
||||
|
||||
|
||||
function ethIn(Stage s) public view returns (uint256 _ethInPosition) {
|
||||
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(positions[s].tickLower);
|
||||
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(positions[s].tickUpper);
|
||||
if (token0isWeth) {
|
||||
_ethInPosition = LiquidityAmounts.getAmount0ForLiquidity(
|
||||
sqrtRatioAX96, sqrtRatioBX96, positions[s].liquidity
|
||||
sqrtRatioAX96, sqrtRatioBX96, positions[s].liquidity / 2
|
||||
);
|
||||
} else {
|
||||
_ethInPosition = LiquidityAmounts.getAmount1ForLiquidity(
|
||||
sqrtRatioAX96, sqrtRatioBX96, positions[s].liquidity
|
||||
sqrtRatioAX96, sqrtRatioBX96, positions[s].liquidity / 2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
|
||||
|
||||
function tickAtPrice(uint256 tokenAmount, uint256 ethAmount) internal view returns (int24 tick_) {
|
||||
function tickAtPrice(uint256 tokenAmount, uint256 ethAmount) internal returns (int24 tick_) {
|
||||
require(ethAmount > 0, "ETH amount cannot be zero");
|
||||
uint160 sqrtPriceX96;
|
||||
if (tokenAmount == 0) {
|
||||
sqrtPriceX96 = MIN_SQRT_RATIO;
|
||||
} else {
|
||||
emit DEBUG(tokenAmount,ethAmount,0,0,token0isWeth);
|
||||
// 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(
|
||||
|
|
@ -160,6 +166,7 @@ contract BaseLineLP {
|
|||
sqrtPriceX96 = uint160(
|
||||
int160(ABDKMath64x64.sqrt(priceRatio) << 32)
|
||||
);
|
||||
emit DEBUG(uint256(int256(priceRatio >> 64)),uint256(sqrtPriceX96 >> 96),0,0,token0isWeth);
|
||||
}
|
||||
// Proceed as before.
|
||||
tick_ = TickMath.getTickAtSqrtRatio(sqrtPriceX96);
|
||||
|
|
@ -239,13 +246,13 @@ contract BaseLineLP {
|
|||
int24 startTick = token0isWeth ? currentTick + ANCHOR_SPACING : currentTick - ANCHOR_SPACING;
|
||||
|
||||
// all remaining eth will be put into this position
|
||||
uint256 ethInFloor = address(this).balance;
|
||||
uint256 ethInFloor = address(this).balance + weth.balanceOf(address(this));
|
||||
int24 floorTick;
|
||||
// calculate price at which all HARB can be bought back
|
||||
uint256 _outstanding = outstanding();
|
||||
if (_outstanding > 0) {
|
||||
floorTick = tickAtPrice(_outstanding, ethInFloor);
|
||||
emit DEBUG(ethInFloor,0,floorTick,startTick,token0isWeth);
|
||||
emit DEBUG(ethInFloor,_outstanding,floorTick,startTick,token0isWeth);
|
||||
|
||||
// put a position symetrically around the price, startTick being edge on one side
|
||||
floorTick = token0isWeth ? startTick + (floorTick - startTick) : floorTick - (startTick - floorTick);
|
||||
|
|
@ -342,11 +349,11 @@ contract BaseLineLP {
|
|||
int24 anchorTickUpper = positions[Stage.ANCHOR].tickUpper;
|
||||
// center tick can be calculated positive and negative numbers the same
|
||||
int24 centerTick = anchorTickLower + ((anchorTickUpper - anchorTickLower) / 2);
|
||||
int24 amplitudeTick = anchorTickLower + (anchorTickUpper - anchorTickLower) * 3 / 20;
|
||||
uint256 minAmplitude = uint256(uint24((anchorTickUpper - anchorTickLower) * 3 / 20));
|
||||
|
||||
// Determine the correct comparison direction based on token0isWeth
|
||||
bool isUp = token0isWeth ? currentTick < centerTick : currentTick > centerTick;
|
||||
bool isEnough = token0isWeth ? currentTick < amplitudeTick : currentTick > amplitudeTick;
|
||||
bool isEnough = SignedMath.abs(currentTick - centerTick) > minAmplitude;
|
||||
|
||||
// Check Conditions
|
||||
require(isUp, "call slide(), not shift()");
|
||||
|
|
@ -358,21 +365,33 @@ contract BaseLineLP {
|
|||
for (uint256 i=uint256(Stage.FLOOR); i <= uint256(Stage.DISCOVERY); i++) {
|
||||
TokenPosition storage position = positions[Stage(i)];
|
||||
(uint256 amount0, uint256 amount1) = pool.burn(position.tickLower, position.tickUpper, position.liquidity);
|
||||
// the actual amounts collected are returned
|
||||
(amount0, amount1) = pool.collect(
|
||||
address(this),
|
||||
position.tickLower,
|
||||
position.tickUpper,
|
||||
uint128(amount0),
|
||||
uint128(amount1)
|
||||
);
|
||||
if (i == uint256(Stage.ANCHOR)) {
|
||||
ethInAnchor = token0isWeth ? amount0 : amount1;
|
||||
}
|
||||
}
|
||||
// TODO: handle fees
|
||||
|
||||
|
||||
// ## set new positions
|
||||
// reduce Anchor by 10% of new ETH. It will be moved into Floor
|
||||
uint256 initialEthInAnchor = ethIn(Stage.ANCHOR);
|
||||
ethInAnchor -= (ethInAnchor - initialEthInAnchor) * 10 / LIQUIDITY_RATIO_DIVISOR;
|
||||
|
||||
|
||||
// cap anchor size at 10 % of total ETH
|
||||
uint256 ethBalance = address(this).balance;
|
||||
uint256 ethBalance = address(this).balance + weth.balanceOf(address(this));
|
||||
// event DEBUG(uint256 indexed eth, uint256 indexed outstanding, int24 indexed floorTick, int24 startTick, bool ethIs0);
|
||||
emit DEBUG(ethInAnchor,weth.balanceOf(address(this)),0,0, token0isWeth);
|
||||
ethInAnchor = (ethInAnchor > ethBalance / 10) ? ethBalance / 10 : ethInAnchor;
|
||||
|
||||
currentTick = currentTick / TICK_SPACING * TICK_SPACING;
|
||||
_set(sqrtPriceX96, currentTick, ethInAnchor);
|
||||
}
|
||||
|
||||
|
|
@ -403,12 +422,19 @@ contract BaseLineLP {
|
|||
for (uint256 i=uint256(Stage.FLOOR); i <= uint256(Stage.DISCOVERY); i++) {
|
||||
TokenPosition storage position = positions[Stage(i)];
|
||||
if (position.liquidity > 0) {
|
||||
pool.burn(position.tickLower, position.tickUpper, position.liquidity);
|
||||
(uint256 amount0, uint256 amount1) = pool.burn(position.tickLower, position.tickUpper, position.liquidity);
|
||||
(amount0, amount1) = pool.collect(
|
||||
address(this),
|
||||
position.tickLower,
|
||||
position.tickUpper,
|
||||
uint128(amount0),
|
||||
uint128(amount1)
|
||||
);
|
||||
// TODO: handle fees
|
||||
}
|
||||
}
|
||||
|
||||
uint256 ethBalance = address(this).balance;
|
||||
uint256 ethBalance = address(this).balance + weth.balanceOf(address(this));
|
||||
if (ethBalance == 0) {
|
||||
// TODO: set only discovery
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue