Source code for eth_defi.uniswap_v2.utils

"""Uniswap v2 helper functions.

`Mostly lifted from Uniswap-v2-py MIT licensed by Asynctomatic <https://github.com/nosofa/uniswap-v2-py>`_.
"""
from typing import Tuple

from eth_typing import HexAddress, HexStr
from web3 import Web3

from eth_defi.utils import ZERO_ADDRESS_STR

#: Ethereum 0x0000000000000000000000000000000000000000 addresss
ZERO_ADDRESS = ZERO_ADDRESS_STR


[docs]def sort_tokens(token_a: HexAddress, token_b: HexAddress) -> Tuple[HexAddress, HexAddress]: """Put lower address first, as Uniswap wants.""" assert token_a != token_b, f"Received bad token pair {token_a}:{token_b}" (token_0, token_1) = (token_a, token_b) if int(token_a, 16) < int(token_b, 16) else (token_b, token_a) assert token_0 != ZERO_ADDRESS return token_0, token_1
# Liften from uniswap-v2-py by Asynctomatic
[docs]def pair_for(factory: HexAddress, token_a: HexAddress, token_b: HexAddress, magical_hash: HexStr) -> HexAddress: """Deduct the Uniswap pair contract address :param factory: Factory contract address :param token_a: Base token :param token_b: Quote token :param magical_hash: Init code hash of the Uniswap instance. Set None to use the default Sushiswap hash. :return: Pair contract address """ prefix = Web3.to_hex(hexstr="ff") token_a = Web3.to_checksum_address(token_a) token_b = Web3.to_checksum_address(token_b) encoded_tokens = Web3.solidity_keccak(["address", "address"], sort_tokens(token_a, token_b)) suffix = Web3.to_hex(hexstr=magical_hash) raw = Web3.solidity_keccak(["bytes", "address", "bytes", "bytes"], [prefix, factory, encoded_tokens, suffix]) return Web3.to_checksum_address(Web3.to_hex(raw)[-40:])