Uniswap V3 Tutorial

This tutorial shows how to use Uniswap V3 with Dexsnake. Let’s start by connecting to the blockchain (here, we use Base for its relatively low transaction fees).

[1]:
import os

from web3 import Web3


# the code below assumes you have configured the required environment variables
account = os.getenv("WEB3_PUBLIC_KEY")
private_key = os.getenv("WEB3_PRIVATE_KEY")
provider_url = os.getenv("WEB3_PROVIDER_URL")

web3 = Web3(Web3.HTTPProvider(provider_url))

Now, let’s import UniswapV3Factory and find the pair with USDC and WETH.

[2]:
from dexsnake.uniswap_v3 import UniswapV3Factory


factory = UniswapV3Factory(web3)

USDC_address = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
WETH_address = "0x4200000000000000000000000000000000000006"
fee = 3000

pool_address = factory.get_pool(USDC_address, WETH_address, fee)

print(pool_address)
0x6c561B446416E1A00E8E93E221854d6eA4171372

Now, let’s initialize the pool object and fetch the pool’s price.

[3]:
from dexsnake.uniswap_v3 import UniswapV3Pool


pool = UniswapV3Pool(web3, pool_address)

price = pool.get_price()

print(f"Price of 1 {pool.token_0.symbol}: {price} {pool.token_1.symbol}")
Price of 1 WETH: 2588.978258128007 USDC

Now that we know the price, let’s use the router to swap one USDC for WETH. Note that before you can make the trade, you must approve the router contract to spend your USDC.

[4]:
from dexsnake.uniswap_v3 import UniswapV3Router


router = UniswapV3Router(web3)

tx_receipt_approval = pool.token_1.approve(router.contract.address, 1, account, private_key)

tx_receipt_swap = router.exact_input_single(
    amount_in=1,
    amount_out_min=1 / price * 0.99,  # max 1% slippage
    token_in=USDC_address,
    token_out=WETH_address,
    fee=fee,
    recipient=account,
    account=account,
    private_key=private_key,
)

tx_receipt_swap
[4]:
AttributeDict({'blockHash': HexBytes('0xf0f897bcaf7d1e068a6f744f18ae8b68c2165c90a1a3f7cb98a54419e91792ec'),
 'blockNumber': 18641698,
 'contractAddress': None,
 'cumulativeGasUsed': 14798579,
 'effectiveGasPrice': 4698025,
 'from': '0x011b7DD4cAA8E48FbBaef548dB349dfB3D09aA3F',
 'gasUsed': 112757,
 'l1BaseFeeScalar': '0x8dd',
 'l1BlobBaseFee': '0x1',
 'l1BlobBaseFeeScalar': '0x101c12',
 'l1Fee': '0x56ed109ae',
 'l1GasPrice': '0x11a8c1ee1',
 'l1GasUsed': '0x879',
 'logs': [AttributeDict({'address': '0x4200000000000000000000000000000000000006',
   'topics': [HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'),
    HexBytes('0x0000000000000000000000006c561b446416e1a00e8e93e221854d6ea4171372'),
    HexBytes('0x000000000000000000000000011b7dd4caa8e48fbbaef548db349dfb3d09aa3f')],
   'data': HexBytes('0x00000000000000000000000000000000000000000000000000015e3d90cd5b4d'),
   'blockNumber': 18641698,
   'transactionHash': HexBytes('0x62025456457e7020995e3a1f610cedd6fff617867c81b922dba09ac4eb18dccd'),
   'transactionIndex': 90,
   'blockHash': HexBytes('0xf0f897bcaf7d1e068a6f744f18ae8b68c2165c90a1a3f7cb98a54419e91792ec'),
   'logIndex': 350,
   'removed': False}),
  AttributeDict({'address': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
   'topics': [HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'),
    HexBytes('0x000000000000000000000000011b7dd4caa8e48fbbaef548db349dfb3d09aa3f'),
    HexBytes('0x0000000000000000000000006c561b446416e1a00e8e93e221854d6ea4171372')],
   'data': HexBytes('0x00000000000000000000000000000000000000000000000000000000000f4240'),
   'blockNumber': 18641698,
   'transactionHash': HexBytes('0x62025456457e7020995e3a1f610cedd6fff617867c81b922dba09ac4eb18dccd'),
   'transactionIndex': 90,
   'blockHash': HexBytes('0xf0f897bcaf7d1e068a6f744f18ae8b68c2165c90a1a3f7cb98a54419e91792ec'),
   'logIndex': 351,
   'removed': False}),
  AttributeDict({'address': '0x6c561B446416E1A00E8E93E221854d6eA4171372',
   'topics': [HexBytes('0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67'),
    HexBytes('0x0000000000000000000000002626664c2603336e57b271c5c0b26f421741e481'),
    HexBytes('0x000000000000000000000000011b7dd4caa8e48fbbaef548db349dfb3d09aa3f')],
   'data': HexBytes('0xfffffffffffffffffffffffffffffffffffffffffffffffffffea1c26f32a4b300000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000355a8d46a11b7d0a54501000000000000000000000000000000000000000000000000003483f3bfe1c7e8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfb9e'),
   'blockNumber': 18641698,
   'transactionHash': HexBytes('0x62025456457e7020995e3a1f610cedd6fff617867c81b922dba09ac4eb18dccd'),
   'transactionIndex': 90,
   'blockHash': HexBytes('0xf0f897bcaf7d1e068a6f744f18ae8b68c2165c90a1a3f7cb98a54419e91792ec'),
   'logIndex': 352,
   'removed': False})],
 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000108000100000000000000020000000000000000000000000000000000800000008000000002000000000080000000001000000000000800000000000000000000000000000000000000000000000000010000800000004000000000100000000000000000000000000002100000002000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000400000000000000000000000000000000000000000800000000000100000000000000000000040000000000000000000020000000000000'),
 'status': 1,
 'to': '0x2626664c2603336E57B271c5C0b26F421741e481',
 'transactionHash': HexBytes('0x62025456457e7020995e3a1f610cedd6fff617867c81b922dba09ac4eb18dccd'),
 'transactionIndex': 90,
 'type': 0})

You can inspect the transaction on the block explorer: https://basescan.org/tx/0x62025456457e7020995e3a1f610cedd6fff617867c81b922dba09ac4eb18dccd.