added harb-lib
This commit is contained in:
parent
ea1b007283
commit
5a8c80e838
15 changed files with 4876 additions and 48 deletions
|
|
@ -212,46 +212,7 @@ contract BaseLineLP {
|
|||
});
|
||||
}
|
||||
|
||||
// call this function when price has moved up 15%
|
||||
function shift() external {
|
||||
// Fetch the current tick from the Uniswap V3 pool
|
||||
(uint160 sqrtPriceX96, int24 currentTick, , , , , ) = pool.slot0();
|
||||
// TODO: check slippage with oracle
|
||||
|
||||
// ## check price moved up
|
||||
{
|
||||
// Check if current tick is within the specified range
|
||||
int24 anchorTickLower = positions[Stage.ANCHOR].tickLower;
|
||||
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;
|
||||
|
||||
// Determine the correct comparison direction based on token0isWeth
|
||||
bool isUp = token0isWeth ? currentTick > centerTick : currentTick < centerTick;
|
||||
bool isEnough = token0isWeth ? currentTick > amplitudeTick : currentTick < amplitudeTick;
|
||||
|
||||
// Check Conditions
|
||||
require(isUp, "call slide(), not shift()");
|
||||
require(isEnough, "amplitude not reached, come back later");
|
||||
}
|
||||
|
||||
// ## scrape positions
|
||||
uint256 ethInAnchor;
|
||||
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);
|
||||
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;
|
||||
|
||||
function _set(uint160 sqrtPriceX96, int24 currentTick, uint256 ethInNewAnchor) internal {
|
||||
// ### set Anchor position
|
||||
uint128 anchorLiquidity;
|
||||
{
|
||||
|
|
@ -261,11 +222,11 @@ contract BaseLineLP {
|
|||
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
|
||||
if (token0isWeth) {
|
||||
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount0(
|
||||
sqrtRatioAX96, sqrtRatioBX96, ethInAnchor
|
||||
sqrtRatioAX96, sqrtRatioBX96, ethInNewAnchor
|
||||
);
|
||||
} else {
|
||||
anchorLiquidity = LiquidityAmounts.getLiquidityForAmount1(
|
||||
sqrtRatioAX96, sqrtRatioBX96, ethInAnchor
|
||||
sqrtRatioAX96, sqrtRatioBX96, ethInNewAnchor
|
||||
);
|
||||
}
|
||||
_mint(tickLower, tickUpper, anchorLiquidity);
|
||||
|
|
@ -322,16 +283,103 @@ contract BaseLineLP {
|
|||
}
|
||||
_mint(tickLower, tickUpper, liquidity);
|
||||
}
|
||||
}
|
||||
|
||||
// call this function when price has moved up 15%
|
||||
function shift() external {
|
||||
require(positions[Stage.ANCHOR].liquidity > 0, "Not initialized");
|
||||
// Fetch the current tick from the Uniswap V3 pool
|
||||
(uint160 sqrtPriceX96, int24 currentTick, , , , , ) = pool.slot0();
|
||||
// TODO: check slippage with oracle
|
||||
|
||||
// ## check price moved up
|
||||
{
|
||||
// Check if current tick is within the specified range
|
||||
int24 anchorTickLower = positions[Stage.ANCHOR].tickLower;
|
||||
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;
|
||||
|
||||
// Determine the correct comparison direction based on token0isWeth
|
||||
bool isUp = token0isWeth ? currentTick > centerTick : currentTick < centerTick;
|
||||
bool isEnough = token0isWeth ? currentTick > amplitudeTick : currentTick < amplitudeTick;
|
||||
|
||||
// Check Conditions
|
||||
require(isUp, "call slide(), not shift()");
|
||||
require(isEnough, "amplitude not reached, come back later!");
|
||||
}
|
||||
|
||||
// ## scrape positions
|
||||
uint256 ethInAnchor;
|
||||
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);
|
||||
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;
|
||||
ethInAnchor = (ethInAnchor > ethBalance / 10) ? ethBalance / 10 : ethInAnchor;
|
||||
|
||||
_set(sqrtPriceX96, currentTick, ethInAnchor);
|
||||
}
|
||||
|
||||
function slide() external {
|
||||
// check price moved down
|
||||
// check price moved down enough
|
||||
// scrape positions
|
||||
// get outstanding upply and capacity
|
||||
// set new positions
|
||||
// burn harb
|
||||
// Fetch the current tick from the Uniswap V3 pool
|
||||
(uint160 sqrtPriceX96, int24 currentTick, , , , , ) = pool.slot0();
|
||||
// TODO: check slippage with oracle
|
||||
|
||||
// ## check price moved down
|
||||
if (positions[Stage.ANCHOR].liquidity > 0) {
|
||||
// Check if current tick is within the specified range
|
||||
int24 anchorTickLower = positions[Stage.ANCHOR].tickLower;
|
||||
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;
|
||||
|
||||
// Determine the correct comparison direction based on token0isWeth
|
||||
bool isDown = token0isWeth ? currentTick < centerTick : currentTick > centerTick;
|
||||
bool isEnough = token0isWeth ? currentTick < amplitudeTick : currentTick > amplitudeTick;
|
||||
|
||||
// Check Conditions
|
||||
require(isDown, "call shift(), not slide()");
|
||||
require(isEnough, "amplitude not reached, diamond hands!");
|
||||
}
|
||||
|
||||
// ## scrape positions
|
||||
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);
|
||||
// TODO: handle fees
|
||||
}
|
||||
}
|
||||
|
||||
uint256 ethBalance = address(this).balance;
|
||||
if (ethBalance == 0) {
|
||||
// TODO: set only discovery
|
||||
return;
|
||||
}
|
||||
uint256 ethInAnchor = ethIn(Stage.ANCHOR);
|
||||
uint256 ethInFloor = ethIn(Stage.FLOOR);
|
||||
|
||||
// use previous ration of Floor to Anchor
|
||||
uint256 ethInNewAnchor = ethBalance * ethInAnchor / (ethInAnchor + ethInFloor);
|
||||
|
||||
// but cap anchor size at 10 % of total ETH
|
||||
ethInNewAnchor = (ethInNewAnchor > ethBalance / 10) ? ethBalance / 10 : ethInNewAnchor;
|
||||
|
||||
_set(sqrtPriceX96, currentTick, ethInNewAnchor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ contract Stake is IStake {
|
|||
if (sharesWanted < minStake) {
|
||||
revert SharesTooLow(receiver, assets, sharesWanted, minStake);
|
||||
}
|
||||
// TODO: check that position size is multiple of minStake
|
||||
|
||||
// run through all suggested positions to snatch
|
||||
for (uint256 i = 0; i < positionsToSnatch.length; i++) {
|
||||
|
|
@ -104,6 +105,8 @@ contract Stake is IStake {
|
|||
// TODO: what if someone calls payTax and exitPosition in the same transaction?
|
||||
_payTax(pos, 0);
|
||||
_exitPosition(positionsToSnatch[i], pos);
|
||||
// TODO: exit positions partially, if needed
|
||||
// TODO: avoid greeving where more positions are freed than needed.
|
||||
}
|
||||
|
||||
// try to make a new position in the free space and hope it is big enough
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue