From a20c2ee2d05e90ccd9d18742d84304f554cd02a2 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Wed, 19 Jul 2023 01:22:29 +0300 Subject: [PATCH] Add util func to get onchain price of uni v3 pool --- eth_defi/uniswap_v3/pool.py | 7 ++++++- eth_defi/uniswap_v3/price.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/eth_defi/uniswap_v3/pool.py b/eth_defi/uniswap_v3/pool.py index 3991e049..38eaed55 100644 --- a/eth_defi/uniswap_v3/pool.py +++ b/eth_defi/uniswap_v3/pool.py @@ -1,10 +1,11 @@ """Uniswap v3 pool data.""" -from decimal import Decimal from dataclasses import dataclass +from decimal import Decimal from typing import Union from eth_typing import HexAddress from web3 import Web3 +from web3.contract import Contract from eth_defi.abi import get_deployed_contract from eth_defi.token import TokenDetails, fetch_erc20_details @@ -33,6 +34,9 @@ class PoolDetails: #: Pool fee as % multiplier, 1 = 100% fee: float + #: Pool contract proxy + pool: Contract + def __repr__(self): return f"Pool {self.address} is {self.token0.symbol}-{self.token1.symbol}, with the fee {self.fee * 100:.04f}%" @@ -72,6 +76,7 @@ def fetch_pool_details(web3, pool_contact_address: Union[str, HexAddress]) -> Po token1, raw_fee, raw_fee / 1_000_000, + pool, ) diff --git a/eth_defi/uniswap_v3/price.py b/eth_defi/uniswap_v3/price.py index 07a8d132..605d26bc 100644 --- a/eth_defi/uniswap_v3/price.py +++ b/eth_defi/uniswap_v3/price.py @@ -3,8 +3,10 @@ from decimal import Decimal from eth_typing import HexAddress +from web3 import Web3 from eth_defi.uniswap_v3.deployment import UniswapV3Deployment +from eth_defi.uniswap_v3.pool import fetch_pool_details from eth_defi.uniswap_v3.utils import encode_path @@ -216,3 +218,23 @@ def estimate_sell_received_amount( return amount, current_block return amount + + +def get_onchain_price( + web3: Web3, + pool_contract_address: str, + block_identifier: int | None = None, + reverse_token_order: bool = False, +): + """Get the current price of a Uniswap pool. + + :param web3: Web3 instance + :param pool_contract_address: Contract address of the pool + :param block_identifier: A specific block to query price + :param reverse_token_order: If set, assume quote token is token0 + :return: Current price + """ + pool_details = fetch_pool_details(web3, pool_contract_address) + _, tick, *_ = pool_details.pool.functions.slot0().call(block_identifier=block_identifier) + + return pool_details.convert_price_to_human(tick, reverse_token_order)