Source code for eth_defi.trade

"""Trade outcome analysis.

- Data structures for analysis Uniswap trade outcomes

- Can be used with both Uniswap v2 and Uniswap v3 style DEXes

- Determine and calculate factors like realised price, slippage, paid trading fee

For usage see

- :py:mod:`eth_defi.uniswap_v2.analysis`

- :py:mod:`eth_defi.uniswap_v3.analysis`
"""

from decimal import Decimal
from dataclasses import dataclass
from typing import List, Optional

from eth_typing import HexAddress

from eth_defi.token import TokenDetails


[docs]@dataclass class TradeResult: """A base class for Success/Fail trade result.""" #: How many units of gas we burned gas_used: int #: What as the gas price used in wei. #: Set to `0` if not available. effective_gas_price: int def get_effective_gas_price_gwei(self) -> Decimal: return Decimal(self.effective_gas_price) / Decimal(10**9)
[docs] def get_cost_of_gas(self) -> Decimal: """This will return the gas cost of the transaction in blockchain's native currency e.g. in ETH on Ethereum.""" return Decimal(self.gas_used) * Decimal(self.effective_gas_price) / Decimal(10**18)
[docs]@dataclass class TradeSuccess(TradeResult): """Describe the result of a successful Uniswap swap. See :py:func:`eth_defi.uniswap_v2.analysis.analyse_trade_by_receipt` """ #: Routing path that was used for this trade path: List[HexAddress] | None amount_in: int amount_out_min: int | None amount_out: int #: The price of the trade in some order. #: #: - Uniswap v2: Overall price paid as in token (first in the path) to out token (last in the path). #: #: - Uniswap v3: depends on ticks and order of token0 and token1 in the underlying pool smart contract #: #: Price includes any fees paid during the order routing path. #: #: Note that you get inverse price, if you route ETH-USD or USD-ETH e.g. are you doing buy or sell. #: #: See also :py:meth:`get_human_price` price: Decimal #: Token information bookkeeping amount_in_decimals: int #: Token information bookkeeping amount_out_decimals: int #: Uniswap v3 pool token 0 #: #: Needed to calculate reverse token order. token0: TokenDetails | None #: Uniswap v3 pool token 1 #: #: Needed to calculate reverse token order. token1: TokenDetails | None #: How much was the LP fee #: #: Note: this is the raw amount in terms of the amount in token lp_fee_paid: float | None def __post_init__(self): if self.price is not None: assert isinstance(self.price, Decimal)
[docs] def get_human_price(self, reverse_token_order=False) -> Decimal: """Get the executed price of this trade in a human-readable form. This depends on: - If we are on Uniswap v2 or v3 - If we do buy or sell - If quote token is token0 or token1 in Uniswap v3 pool Example: .. code-block:: python # TODO pass :param reverse_token_order: Base and quote token order. Quote token should be natural quote token like USD or ETH based token of the trade. If `reverse_token_order` is set quote token is `token0` of the pool, otherwise `token1`. """ if reverse_token_order: return Decimal(1) / self.price else: return self.price
[docs]@dataclass class TradeFail(TradeResult): """Describe the result of a failed Uniswap swap. The transaction reverted for a reason or another. """ #: Revert reason if we managed to extract one revert_reason: Optional[str] = None