forked from Badger-Finance/badger-multisig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from ebtc-protocol/feat/univ3-helpers
feat: intro univ3 and prep seeding scripting for ebtc/wbtc pool
- Loading branch information
Showing
16 changed files
with
1,667 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
from .ebtc import eBTC | ||
from .uni_v3 import UniV3 | ||
from .cow import Cow | ||
|
||
|
||
class ApeApis: | ||
def init_ebtc(self): | ||
self.ebtc = eBTC(self) | ||
|
||
def init_uni_v3(self): | ||
self.uni_v3 = UniV3(self) | ||
|
||
def init_cow(self, prod=False): | ||
self.cow = Cow(self, prod=prod) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from math import floor | ||
from rich.pretty import pprint | ||
|
||
|
||
Q128 = 2 ** 128 | ||
|
||
LABELS = { | ||
"pool_positions": [ | ||
"liquidity", | ||
"feeGrowthInside0LastX128", | ||
"feeGrowthInside1LastX128", | ||
"tokensOwed0", | ||
"tokensOwed1", | ||
], | ||
"positions": [ | ||
"nonce", | ||
"operator", | ||
"token0", | ||
"token1", | ||
"fee", | ||
"tickLower", | ||
"tickUpper", | ||
"liquidity", | ||
"feeGrowthInside0LastX128", | ||
"feeGrowthInside1LastX128", | ||
"tokensOwed0", | ||
"tokensOwed1", | ||
], | ||
"ticks": [ | ||
"liquidityGross", | ||
"liquidityNet", | ||
"feeGrowthOutside0X128", | ||
"feeGrowthOutside1X128", | ||
"tickCumulativeOutside", | ||
"secondsPerLiquidityOutsideX128", | ||
"secondsOutside", | ||
"initialized", | ||
], | ||
} | ||
|
||
|
||
def print_position(nfp, position_id): | ||
position_info = nfp.positions(position_id) | ||
|
||
position = dict(zip(LABELS["positions"], position_info)) | ||
pprint(position) | ||
|
||
return position_info | ||
|
||
|
||
def calc_accum_fees(feeGrowthInsideX128, feeGrowthInsideLastX128, liquidity): | ||
# https://github.com/Uniswap/v3-core/blob/c05a0e2c8c08c460fb4d05cfdda30b3ad8deeaac/contracts/libraries/Position.sol#L60-L76 | ||
return floor((feeGrowthInsideX128 - feeGrowthInsideLastX128) * liquidity / Q128) | ||
|
||
|
||
def calc_all_accum_fees(nfp, v3_pool_obj, position_id): | ||
"""given a uni_v3 nfp manager, pool and position id, calculate its | ||
accumulated fees expressed per underlying asset""" | ||
|
||
position = dict(zip(LABELS["positions"], nfp.positions(position_id))) | ||
|
||
lower = position["tickLower"] | ||
upper = position["tickUpper"] | ||
|
||
ticks_lower = dict(zip(LABELS["ticks"], v3_pool_obj.ticks(lower))) | ||
ticks_upper = dict(zip(LABELS["ticks"], v3_pool_obj.ticks(upper))) | ||
|
||
global0 = v3_pool_obj.feeGrowthGlobal0X128() | ||
global1 = v3_pool_obj.feeGrowthGlobal1X128() | ||
|
||
outside_lower0 = ticks_lower["feeGrowthOutside0X128"] | ||
outside_lower1 = ticks_lower["feeGrowthOutside1X128"] | ||
|
||
outside_upper0 = ticks_upper["feeGrowthOutside0X128"] | ||
outside_upper1 = ticks_upper["feeGrowthOutside1X128"] | ||
|
||
inside0 = global0 - outside_lower0 - outside_upper0 | ||
inside1 = global1 - outside_lower1 - outside_upper1 | ||
|
||
last0 = position["feeGrowthInside0LastX128"] | ||
last1 = position["feeGrowthInside1LastX128"] | ||
|
||
return ( | ||
calc_accum_fees(inside0, last0, position["liquidity"]), | ||
calc_accum_fees(inside1, last1, position["liquidity"]), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
from math import ceil | ||
|
||
BASE = 1.0001 | ||
Q128 = 2 ** 128 | ||
Q96 = 2 ** 96 | ||
Q32 = 2 ** 32 | ||
MAXUINT256 = 2 ** 256 - 1 | ||
|
||
|
||
def maxLiquidityForAmount0(sqrtA, sqrtB, amount): | ||
# https://github.com/Uniswap/v3-sdk/blob/d139f73823145a5ba5d90ef2f61ff33ff02b6a92/src/utils/maxLiquidityForAmounts.ts#L32-L41 | ||
if sqrtA > sqrtB: | ||
sqrtA, sqrtB = sqrtB, sqrtA | ||
|
||
numerator = (amount * sqrtA) * sqrtB | ||
denominator = Q96 * (sqrtB - sqrtA) | ||
|
||
return numerator / denominator | ||
|
||
|
||
def maxLiquidityForAmount1(sqrtA, sqrtB, amount): | ||
# https://github.com/Uniswap/v3-sdk/blob/d139f73823145a5ba5d90ef2f61ff33ff02b6a92/src/utils/maxLiquidityForAmounts.ts#L50-L55 | ||
if sqrtA > sqrtB: | ||
sqrtA, sqrtB = sqrtB, sqrtA | ||
|
||
numerator = amount * Q96 | ||
denominator = sqrtB - sqrtA | ||
|
||
return numerator / denominator | ||
|
||
|
||
def maxLiquidityForAmounts(sqrtCurrent, sqrtA, sqrtB, amount0, amount1): | ||
# https://github.com/Uniswap/v3-sdk/blob/d139f73823145a5ba5d90ef2f61ff33ff02b6a92/src/utils/maxLiquidityForAmounts.ts#L68-L91 | ||
if sqrtCurrent <= sqrtA: | ||
return maxLiquidityForAmount0(sqrtA, sqrtB, amount0) | ||
elif sqrtCurrent < sqrtB: | ||
liq0 = maxLiquidityForAmount0(sqrtCurrent, sqrtB, amount0) | ||
liq1 = maxLiquidityForAmount1(sqrtA, sqrtCurrent, amount1) | ||
return liq0 if liq0 < liq1 else liq1 | ||
else: | ||
return maxLiquidityForAmount1(sqrtA, sqrtB, amount1) | ||
|
||
|
||
def getAmount0Delta(sqrtA, sqrtB, liquidity, roundUp=False): | ||
# https://github.com/Uniswap/v3-sdk/blob/12f3b7033bd70210a4f117b477cdaec027a436f6/src/utils/sqrtPriceMath.ts#L25-L36 | ||
if sqrtA > sqrtB: | ||
sqrtA, sqrtB = sqrtB, sqrtA | ||
|
||
shift_liquidity = liquidity * (1 << 96) | ||
sqrt_substraction = sqrtB - sqrtA | ||
|
||
numerator = (shift_liquidity * sqrt_substraction) / sqrtB | ||
|
||
return ceil(numerator / sqrtA) if roundUp else numerator / sqrtA | ||
|
||
|
||
def getAmount1Delta(sqrtA, sqrtB, liquidity, roundUp=False): | ||
# https://github.com/Uniswap/v3-sdk/blob/12f3b7033bd70210a4f117b477cdaec027a436f6/src/utils/sqrtPriceMath.ts#L38-L46 | ||
if sqrtA > sqrtB: | ||
sqrtA, sqrtB = sqrtB, sqrtA | ||
|
||
numerator = liquidity * (sqrtB - sqrtA) | ||
denominator = Q96 | ||
|
||
return ceil(numerator / denominator) if roundUp else numerator / denominator | ||
|
||
|
||
def getAmountsForLiquidity(sqrtCurrent, sqrtA, sqrtB, liquidity): | ||
# https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/LiquidityAmounts.sol#L120 | ||
if sqrtA > sqrtB: | ||
sqrtA, sqrtB = sqrtB, sqrtA | ||
|
||
amount0 = 0 | ||
amount1 = 0 | ||
|
||
if sqrtCurrent < sqrtA: | ||
amount0 = getAmount0Delta(sqrtA, sqrtB, liquidity) | ||
elif sqrtCurrent < sqrtB: | ||
amount0 = getAmount0Delta(sqrtCurrent, sqrtB, liquidity) | ||
amount1 = getAmount1Delta(sqrtA, sqrtCurrent, liquidity) | ||
else: | ||
amount1 = getAmount1Delta(sqrtA, sqrtB, liquidity) | ||
|
||
return amount0, amount1 | ||
|
||
|
||
# https://github.com/Balt2/Uniswapv3Research/blob/main/SqrtPriceMath.py | ||
def rshift(val, n): | ||
return (val) >> n | ||
|
||
|
||
def mulShift(val, mulBy): | ||
return rshift(val * mulBy, 128) | ||
|
||
|
||
def getSqrtRatioAtTick(tick): | ||
absTick = abs(tick) | ||
ratio = ( | ||
0xFFFCB933BD6FAD37AA2D162D1A594001 | ||
if ((absTick & 0x1) != 0) | ||
else 0x100000000000000000000000000000000 | ||
) | ||
if (absTick & 0x2) != 0: | ||
ratio = mulShift(ratio, 0xFFF97272373D413259A46990580E213A) | ||
if (absTick & 0x4) != 0: | ||
ratio = mulShift(ratio, 0xFFF2E50F5F656932EF12357CF3C7FDCC) | ||
if (absTick & 0x8) != 0: | ||
ratio = mulShift(ratio, 0xFFE5CACA7E10E4E61C3624EAA0941CD0) | ||
if (absTick & 0x10) != 0: | ||
ratio = mulShift(ratio, 0xFFCB9843D60F6159C9DB58835C926644) | ||
if (absTick & 0x20) != 0: | ||
ratio = mulShift(ratio, 0xFF973B41FA98C081472E6896DFB254C0) | ||
if (absTick & 0x40) != 0: | ||
ratio = mulShift(ratio, 0xFF2EA16466C96A3843EC78B326B52861) | ||
if (absTick & 0x80) != 0: | ||
ratio = mulShift(ratio, 0xFE5DEE046A99A2A811C461F1969C3053) | ||
if (absTick & 0x100) != 0: | ||
ratio = mulShift(ratio, 0xFCBE86C7900A88AEDCFFC83B479AA3A4) | ||
if (absTick & 0x200) != 0: | ||
ratio = mulShift(ratio, 0xF987A7253AC413176F2B074CF7815E54) | ||
if (absTick & 0x400) != 0: | ||
ratio = mulShift(ratio, 0xF3392B0822B70005940C7A398E4B70F3) | ||
if (absTick & 0x800) != 0: | ||
ratio = mulShift(ratio, 0xE7159475A2C29B7443B29C7FA6E889D9) | ||
if (absTick & 0x1000) != 0: | ||
ratio = mulShift(ratio, 0xD097F3BDFD2022B8845AD8F792AA5825) | ||
if (absTick & 0x2000) != 0: | ||
ratio = mulShift(ratio, 0xA9F746462D870FDF8A65DC1F90E061E5) | ||
if (absTick & 0x4000) != 0: | ||
ratio = mulShift(ratio, 0x70D869A156D2A1B890BB3DF62BAF32F7) | ||
if (absTick & 0x8000) != 0: | ||
ratio = mulShift(ratio, 0x31BE135F97D08FD981231505542FCFA6) | ||
if (absTick & 0x10000) != 0: | ||
ratio = mulShift(ratio, 0x9AA508B5B7A84E1C677DE54F3E99BC9) | ||
if (absTick & 0x20000) != 0: | ||
ratio = mulShift(ratio, 0x5D6AF8DEDB81196699C329225EE604) | ||
if (absTick & 0x40000) != 0: | ||
ratio = mulShift(ratio, 0x2216E584F5FA1EA926041BEDFE98) | ||
if (absTick & 0x80000) != 0: | ||
ratio = mulShift(ratio, 0x48A170391F7DC42444E8FA2) | ||
|
||
if tick > 0: | ||
ratio = MAXUINT256 / ratio | ||
|
||
if ratio % Q32 > 0: | ||
return ratio / Q32 + 1 | ||
else: | ||
return ratio / Q32 |
Oops, something went wrong.