polygonsmartcontractsweb3pyuniswap

Unable to swap Tokens for Tokens Web3Py


I am trying to swap WETH for USDC using SushiSwap Router with Polygon. This is my current code:

import web3
from web3.middleware import geth_poa_middleware
import time

def swap(node, account_address, pvt_key, contract_address, contract_abi, action_type):
    #imagine we are trade on weth-usdc
    weth_addr = '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619'
    usdc_addr = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174'
    
    #connect to polygon node
    w3 = web3.Web3(web3.Web3.HTTPProvider(node))
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)
    
    contract_addr = web3.Web3.toChecksumAddress(contract_address.lower())
    contract = w3.eth.contract(contract_addr, abi=contract_abi)

    gasPrice = w3.toWei(30, 'gwei')

    amount_in = 0.001
    amount_out_min = 0.00001
    path = [weth_addr, usdc_addr]
    deadline = int(time.time()+1000)
    
    build_txn = contract.functions.swapExactTokensForTokens(amount_in, amount_out_min, [weth_addr, usdc_addr], account_address, deadline).buildTransaction({'chainId': 137,'gas': int(300000),'gasPrice': gasPrice,'nonce': w3.eth.get_transaction_count(account_address),"value": 0,})

#we are acting on polygon blockchain
node = 'https://polygon-rpc.com'

account_from = {
    'private_key': 'XXX',
    'address': 'XXX'
    }

contract_address = '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506'
contract_abi = ''''''

#actions available are two: buy or swap. buy=1, sell=0.
action = 0

#call function
swap(node, account_from['address'], account_from['private_key'], contract_address, contract_abi, action)

I think that everything is fine, but when trying to build the tnx i got this error:

Found 1 function(s) with the name `swapExactTokensForTokens`: ['swapExactTokensForTokens(uint256,uint256,address[],address,uint256)']
Function invocation failed due to no matching argument types.

Does somebody know why? Thanks


Solution

  • The function swapExactTokensForTokens (and similar functions) expect all parameters passed as integers. One reason for this is that Solidity does not have floating point numbers. Further, the amounts should be converted from the human-readable format to internal representation (wei for ETH, decimal units for other tokens).

    One way to do it is by adding these lines before the swapExactTokensForTokens call:

    amount_in = int(amount_in * (10**token_in_decimals))
    amount_out_min = int(amount_out_min * (10**token_out_decimals)) 
    

    In the example, token_in_decimals should be set to 18 (for WETH) and token_out_decimals to 6 (for USDC).