Skip to content

mmsaki/uv4

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UV4

PyPI - Version Publish Tests GitHub last commit codecov PyPI - Downloads X (formerly Twitter) Follow

Math utils for Uniswap v4.

Install

pip install uv4

Q64.96

  • Q64.96 Fixed Point convertions
    • Convert decimal to Q64.96
    • Convert Q64.96 to decimal
    • Get 64 bit string
    • Get 96 bit string

Usage

>>> from uv4 import Q6496
>>> value = 1.0001
>>> q = Q6496(value)
>>> q.from_decimal()
79236085330515764027303304731
>>> q.to_decimal()
Decimal('1.00009999999999999999999999999957590837735318405341065472330397412292768422048538923263549804688')
>>> q.get_64_bits_string()
'0000000000000000000000000000000000000000000000000000000000000001'
>>> q.get_96_bits_precision_string()
'000000000000011010001101101110001011101011000111000100001100101100101001010111101001111000011011'
>>> q.to_Q6496_binary_string()
'0b0000000000000000000000000000000000000000000000000000000000000001000000000000011010001101101110001011101011000111000100001100101100101001010111101001111000011011'
>>> q.value
Decimal('1.0001')
>>> q.q_number
79236085330515764027303304731

TickMath & Sqrt Prices

>>> from uv4 import TickMath
>>> tick = 10
>>> tick_spacing = 1
>>> t = TickMath(tick, tick_spacing)
>>> t.to_price()
Decimal('1.0010004501200210025202100120004500100001')
>>> t.to_sqrt_price()
Decimal('1.00050010001000050001')
>>> t.to_sqrt_price_x96()
79267784519130042428790663799
  • get price at tick
  • get tick at price
  • get Q64.96 price at tick
  • get tick at Q64.96 price
  • get Q64.96 price from price
  • get price from Q64.96 price

Hooks

>>> from uv4 import Hook
>>> address = 0x00000000000000000000000000000000000000b5
>>> h = Hook(address)
>>> h.has_after_swap_flag()
False
>>> h.has_before_swap_flag()
True

Liquidity amounts within and outside range

  • Amount of token0 within range
  • Amount of token1 within range
  • Amount of token0 outside range
  • Amount of token1 outside range

Usage:

from uv4 import Liquidity, TickMath

liq = Liquidity()
tm = TickMath()

# https://app.uniswap.org/positions/v4/ethereum/1
position_liquidity = 555103547015
tick_lower = -887270
tick_upper = 887270
sqrt_price = 1260437594239115943190250841240651

tick = tm.from_sqrt_pricex96(sqrt_price)
price = tm.to_price(tick)
price_upper = tm.to_price(tick_upper)
price_lower = tm.to_price(tick_lower)

token0, token1 = liq.calculate_position_holdings(
    position_liquidity,
    price,
    price_upper,
    price_lower,
)
print("token0 amount == ", round(token0 / 10**6, 4), "USDC")
print("token1 amount == ", round(token1 / 10**18, 4), "ETH")

Result:

token0 amount ==  34.8933 USDC
token1 amount ==  0.0088 ETH
  • token0 = $34.89 USDC
  • token1 = 0.0088 ETH

LP Fees earned

  • Amount of token0 in uncollected fees
  • Amount of token1 in uncollected fees

Usage:

from uv4 import Liquidity

liq = Liquidity()

# example position https://app.uniswap.org/positions/v3/ethereum/37
position_liquidity = 10860507277202
feeGrowthGlobal0 = 5247194057753078598628514306485795
feeGrowthGlobal1 = 2233111119924828986464996298702686253189413
feeGrowthOutside0_lower = 96197287712989292312469866057737
feeGrowthOutside0_upper = 437757860306982806877467479294063
feeGrowthInside0 = 0
feeGrowthOutside1_lower = 20741530393032227016498669306435785133483
feeGrowthOutside1_upper = 101747371833570761666428696605043869042568
feeGrowthInside1 = 0
tick_lower = 192180
tick_upper = 193380
tick = 193397

fees0, fees1 = liq.calculate_uncollected_fees(
    position_liquidity,
    feeGrowthGlobal0,
    feeGrowthGlobal1,
    feeGrowthOutside0_lower,
    feeGrowthOutside0_upper,
    feeGrowthInside0,
    feeGrowthOutside1_lower,
    feeGrowthOutside1_upper,
    feeGrowthInside1,
    tick_lower,
    tick_upper,
    tick,
)
print("fees0 == ", round(fees0 / 10**6, 4), "USDC")
print("fees1 == ", round(fees1 / 10**18, 4), "ETH")

Result:

fees0 ==  10.9013 USDC
fees1 ==  0.0026 ETH
  • fees0 = $10.90 USDC
  • fees1 = 0.0026 ETH

🧪 Run Tests

Dependencies:

  • pytest
  • pytest-watcher

Run command

pytest -s -v --no-header
# or
ptw . -s -v --no-header

About

uniwap v4 utils

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages