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.