1
import json
from web3 import Web3

mainnet_infura_url = '????'
web3 = Web3(Web3.HTTPProvider(mainnet_infura_url)) 
res = web3.isConnected()
print(res)

#mainnet
weth_token = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
wbtc_token =  '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'


uniswap_v3_quoter_abi = json.loads('[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH9","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"quoteExactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"quoteExactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"path","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"view","type":"function"}]')

uniswap_v3_quoter_address = '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'
uniswap_v3_quoter_contract = web3.eth.contract(address = uniswap_v3_quoter_address, abi = uniswap_v3_quoter_abi)

uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
    wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0).call()

and it gave error

---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Input In [1], in <cell line: 25>()
     21 uniswap_v3_quoter_contract = web3.eth.contract(address = uniswap_v3_quoter_address, abi = uniswap_v3_quoter_abi)
     23 int(web3.toWei(0.01, 'ether'))
---> 25 uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
     26     wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0).call()

File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/contract.py:878, in ContractFunction.__call__(self, *args, **kwargs)
    876 else:
    877     clone.kwargs = kwargs
--> 878 clone._set_function_info()
    879 return clone

File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/contract.py:883, in ContractFunction._set_function_info(self)
    881 def _set_function_info(self) -> None:
    882     if not self.abi:
--> 883         self.abi = find_matching_fn_abi(
    884             self.contract_abi,
    885             self.web3.codec,
    886             self.function_identifier,
    887             self.args,
    888             self.kwargs
    889         )
    890     if self.function_identifier in [FallbackFn, ReceiveFn]:
    891         self.selector = encode_hex(b'')

File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/_utils/contracts.py:163, in find_matching_fn_abi(abi, abi_codec, fn_identifier, args, kwargs)
    143     diagnosis = (
    144         "\nAmbiguous argument encoding. "
    145         "Provided arguments can be encoded to multiple functions matching this call."
    146     )
    148 message = (
    149     "\nCould not identify the intended function with name `{name}`, "
    150     "positional argument(s) of type `{arg_types}` and "
   (...)
    160     diagnosis=diagnosis,
    161 )
--> 163 raise ValidationError(message)

ValidationError: 
Could not identify the intended function with name `quoteExactInputSingle`, positional argument(s) of type `(<class 'str'>, <class 'str'>, <class 'int'>, <class 'int'>, <class 'int'>)` and keyword argument(s) of type `{}`.
Found 1 function(s) with the name `quoteExactInputSingle`: ['quoteExactInputSingle(address,address,uint24,uint256,uint160)']
Function invocation failed due to no matching argument types.

I really cannot figure out what's wrong

1
  • hi did you resolved this question??
    – w tms
    Dec 4, 2022 at 8:44

2 Answers 2

1

It looks like you are using the web3.eth.contract method incorrectly. The address parameter should be passed as a keyword argument, like this:

uniswap_v3_quoter_contract = web3.eth.contract(
    address=uniswap_v3_quoter_address, 
    abi=uniswap_v3_quoter_abi
)

Additionally, it looks like you are trying to call a function on the contract without sending a transaction. In order to call a function on a contract, you need to use the call() method on the function object, like this:

amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
    wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0
).call()

This will call the function and return the result, but it will not send a transaction and therefore will not change the state of the contract. If you want to send a transaction and change the state of the contract, you will need to use the sendTransaction() method on the function object. This method takes a transaction object as an argument, which contains information about the transaction, such as the from address, gas limit, and gas price. For example:

tx = {
    'from': '0xYOUR_ADDRESS',
    'gas': 1000000,
    'gasPrice': web3.toWei('1', 'gwei')
}

tx_hash = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
    wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0
).sendTransaction(tx)

This will send a transaction and change the state of the contract, but it will not return the result of the function call. Instead, it will return the transaction hash of the transaction that was sent. You can then use this transaction hash to track the transaction and get the result once it is mined.

Hope this helps!

1

This call fails because of an ABI decoding error. By passing the data as a tuple() you avoid this error.

Replace

    amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
        wbtc_token, weth_token, eth_client.toWei(0.01, 'ether'), 3000, 0
    ).call()

With

    amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
        (wbtc_token, weth_token, eth_client.toWei(0.01, 'ether'), 3000, 0)
    ).call()

Otherwise you will encounter this exception:

web3.exceptions.ValidationError: 
Could not identify the intended function with name `quoteExactInputSingle`, positional argument(s) of type `(<class 'str'>, <class 'str'>, <class 'int'>, <class 'int'>, <class 'int'>)` and keyword argument(s) of type `{}`.
Found 1 function(s) with the name `quoteExactInputSingle`: ['quoteExactInputSingle(tuple)']
Function invocation failed due to improper number of arguments

You can tell the function takes in a tuple by the function signature 'quoteExactInputSingle(tuple)'

And you can see what the function expects in the tuple looking at the quoterv2 code on Etherscan. https://etherscan.io/address/0x61fFE014bA17989E743c5F6cB21bF9697530B21e#code

    function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
        public
        override
        returns (
            uint256 amountOut,
            uint160 sqrtPriceX96After,
            uint32 initializedTicksCrossed,
            uint256 gasEstimate
        )

when you look at the QuoteExactInputSingleParams struct.

QuoteExactInputSingleParams({
                        tokenIn: tokenIn,
                        tokenOut: tokenOut,
                        fee: fee,
                        amountIn: amountIn,
                        sqrtPriceLimitX96: 0
                    }

So it must be a tuple with 5 arguments in the order the are listed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.