I am simply trying to call a method in Uniswap QuoterV2 and keep getting errors that the arguments aren't correct. This is my relevant code:
import QuoterABI from '@uniswap/v3-periphery/artifacts/contracts/interfaces/IQuoterV2.sol/IQuoterV2.json'
const UNISWAP_QUOTER_ADDRESS = '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a'
const quoterContract = new ethers.Contract(UNISWAP_QUOTER_ADDRESS, QuoterABI.abi, provider);
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
tokenIn.address,
tokenOut.address,
pool.fee,
amountIn,
0
);
This returns an error:
reason: 'too many arguments: passed to contract',
code: 'UNEXPECTED_ARGUMENT',
count: 5,
expectedCount: 1
While all the examples I found online pass in 5 parameters, why is it that I need to turn the parameters into a single parameter like this:
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
[
tokenIn.address,
tokenOut.address,
pool.fee,
amountIn,
0
]
);
Sure, now it doesn't complain about the wrong number of parameters but instead now it complains about value out of bounds:
reason: 'value out-of-bounds',
code: 'INVALID_ARGUMENT',
argument: 'fee',
value: BigNumber { _hex: '0x5af3107a4000', _isBigNumber: true }
I took a look at the ABI I'm using here: https://www.npmjs.com/package/@uniswap/v3-periphery?activeTab=code
Relevant function is here:
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "tokenIn",
"type": "address"
},
{
"internalType": "address",
"name": "tokenOut",
"type": "address"
},
{
"internalType": "uint256",
"name": "amountIn",
"type": "uint256"
},
{
"internalType": "uint24",
"name": "fee",
"type": "uint24"
},
{
"internalType": "uint160",
"name": "sqrtPriceLimitX96",
"type": "uint160"
}
],
"internalType": "struct IQuoterV2.QuoteExactInputSingleParams",
"name": "params",
"type": "tuple"
}
],
"name": "quoteExactInputSingle",
"outputs": [
{
"internalType": "uint256",
"name": "amountOut",
"type": "uint256"
},
{
"internalType": "uint160",
"name": "sqrtPriceX96After",
"type": "uint160"
},
{
"internalType": "uint32",
"name": "initializedTicksCrossed",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "gasEstimate",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
It says that it takes in a tuple
? But why does every example pass in 5 separate parameters. Also, the order of the parameters shows amountIn
should be the 3rd parameter not the 4th, even if I update that I still get the same error. I'm really frusturated here spent the whole day debugging and keep running into various errors with this, any help is appreciated.
EDIT: Thank you for your help, I've tried again and still having these issues. This is my code:
const UNISWAP_QUOTER_ADDRESS = '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a';
const QUOTERv2_ABI = '[{"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"},{"internalType":"uint160[]","name":"sqrtPriceX96AfterList","type":"uint160[]"},{"internalType":"uint32[]","name":"initializedTicksCrossedList","type":"uint32[]"},{"internalType":"uint256","name":"gasEstimate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct IQuoterV2.QuoteExactInputSingleParams","name":"params","type":"tuple"}],"name":"quoteExactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96After","type":"uint160"},{"internalType":"uint32","name":"initializedTicksCrossed","type":"uint32"},{"internalType":"uint256","name":"gasEstimate","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"},{"internalType":"uint160[]","name":"sqrtPriceX96AfterList","type":"uint160[]"},{"internalType":"uint32[]","name":"initializedTicksCrossedList","type":"uint32[]"},{"internalType":"uint256","name":"gasEstimate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct IQuoterV2.QuoteExactOutputSingleParams","name":"params","type":"tuple"}],"name":"quoteExactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96After","type":"uint160"},{"internalType":"uint32","name":"initializedTicksCrossed","type":"uint32"},{"internalType":"uint256","name":"gasEstimate","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"}]';
const quoterContract = new ethers.Contract(UNISWAP_QUOTER_ADDRESS, QUOTERv2_ABI, provider);
console.log(tokenIn.address);
console.log(tokenOut.address);
console.log(amountIn);
console.log(pool.fee);
const params = {
tokenIn: tokenIn.address,
tokenOut: tokenOut.address,
amountIn: amountIn,
fee: pool.fee,
sqrtPriceLimitX96: 0,
};
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
params
);
Console.log shows that the tokenIn and tokenOut are just public addresses, the amountIn is a BigNum and pool.fee is 3000. I'm getting this error when I run it:
Error: invalid BigNumber value (argument="value", value=[{"type":"BigNumber","hex":"0x12c5e263a5dadc1d6466cad1"},{"type":"BigNumber","hex":"0xaba3e92070893071a033a27bfddb"},0,{"type":"BigNumber","hex":"0x017b5c"}], code=INVALID_ARGUMENT, version=bignumber/5.7.0)
As you see it's still complaining about a wrong BigNumber value, but I'm not sure where it's coming from because the only BigNumber I'm passing in is the amountIn and that number is: BigNumber { _hex: '0x0de0b6b3a7640000', _isBigNumber: true } according to console.log.
EDIT3: Nevermind, actually the call to Quoter 2 was correct and I was getting the error above further down in my code where I was trying to print the output of quoter, but because my console.log statements were for the old quoter the output couldn't be parsed and gave me an error. So happy to solve this and have to pay more attention to where the errors are coming from.
Uniswap QuoterV2
?