Hi I am trying to mock the process of buying and selling token through uniswap v2 router.
I start with a local network fork anvil --fork-url https://mainnet.infura.io/xxx
Then I have to do 2 things under the test account (which has 1,000 eth):
- wrap eth by calling
deposit
- buy $uni token with $weth through
swapExactETHForTokens
.
The full code is available at https://gist.github.com/reinforcementwonder/a2a26b514ca065c2344be269d4d08824
I give a minimum example here:
import time
from abi import UNISWAPV2_ROUTER_ABI, UNISWAPV2_LP_ABI
from web3 import Account, Web3
from eth_utils import to_checksum_address
from util import Token, account_status_for_tokens_and_pool
# setup our account and chain connection - we will use ganache here
chain_id = 1
rpc_endpoint = "http://127.0.0.1:8545" # our local ganache instance
web3 = Web3(Web3.HTTPProvider(rpc_endpoint))
account = Account.from_key(
"anvil-secret-key")
WETH_TOKEN_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
UNI_TOKEN_ADDRESS = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
UNI_WETH_POOL_ADDRESS = "0xd3d2e2692501a5c9ca623199d38826e513033a17"
UNISWAP_V2_SWAP_ROUTER_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
router_contract = web3.eth.contract(
address=to_checksum_address(UNISWAP_V2_SWAP_ROUTER_ADDRESS), abi=UNISWAPV2_ROUTER_ABI)
# ------------------ SETUP ------------------
WETH = Token(to_checksum_address(WETH_TOKEN_ADDRESS), "WETH", 18)
TARGET_TOKEN = Token(to_checksum_address(UNI_TOKEN_ADDRESS), "UNI", 18)
pool_contract = web3.eth.contract(
address=to_checksum_address(UNI_WETH_POOL_ADDRESS), abi=UNISWAPV2_LP_ABI)
# ------------------ FINISH SETUP ------------------
# DEPOSIT WETH
eth_to_wrap = Web3.to_wei(10, 'ether')
tx = WETH.contract.functions.deposit().build_transaction({
'chainId': chain_id,
"from": account.address,
'gas': 1_000_000,
"maxPriorityFeePerGas": web3.eth.max_priority_fee,
"maxFeePerGas": 500 * 10**10,
'nonce': web3.eth.get_transaction_count(account.address),
'value': eth_to_wrap
})
signed_buy_tx = web3.eth.account.sign_transaction(tx, account.key)
tx_hash = web3.eth.send_raw_transaction(signed_buy_tx.rawTransaction)
receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
if receipt and receipt['status'] == 1:
print(
f"[WRAP ETH]tx hash: {Web3.to_hex(tx_hash)} confirmed at [{receipt['blockNumber']}]")
print("eth balance before buy", WETH.contract.functions.balanceOf(
account.address).call()/10**18)
before_buy_eth_balance = web3.eth.get_balance(account.address)/10**18
# prepare the swap function call parameters
buy_path = [WETH.address, TARGET_TOKEN.address]
# amount_to_buy_for =
amount_to_buy_for = Web3.to_wei(1, 'ether')
buy_tx_params = {
"nonce": web3.eth.get_transaction_count(account.address),
"from": account.address,
"chainId": chain_id,
"gas": 1_000_000,
"maxPriorityFeePerGas": web3.eth.max_priority_fee,
"maxFeePerGas": 500 * 10**10,
"value": amount_to_buy_for,
}
buy_tx = router_contract.functions.swapExactETHForTokens(
0, # min amount out
buy_path,
account.address,
int(time.time())+180 # deadline now + 180 sec
).build_transaction(buy_tx_params)
signed_buy_tx = web3.eth.account.sign_transaction(buy_tx, account.key)
tx_hash = web3.eth.send_raw_transaction(signed_buy_tx.rawTransaction)
receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
if receipt and receipt['status'] == 1:
print(
f"[BUY] tx hash: {Web3.to_hex(tx_hash)} confirmed at [{receipt['blockNumber']}]")
print("eth balance after buy",
WETH.contract.functions.balanceOf(account.address).call()/10**18)
However, I find the balance of weth for my account did not change, as reflected in the output:
[WRAP ETH]tx hash: 0xc53e44cbca6fcc6d544ce6128f42ea67b1f39c62a541cb83dfdf78fdb988a4f5 confirmed at [19034035]
eth balance before buy 10.0
[BUY] tx hash: 0x2a99b2c0129464852d0fae56bf9290d7b5f05ac5a9d7aa05187f1d35e56fbefd confirmed at [19034036]
eth balance after buy 10.0
This is really strange. Appreciate anyone can give some advice.