docs
docs copied to clipboard
Referencing the Quoter contract and getting a quote added for QuoterV2 as well
Referencing the Quoter contract and getting a quote
To get quotes for trades, Uniswap has deployed a Quoter Contract. We will use this contract to fetch the output amount we can expect for our trade, without actually executing the trade. Check out the full code for the following snippets in quote.ts
Like we did for the Pool contract, we need to construct an instance of an ethers Contract
for our Quoter contract in order to interact with it:
const quoterContract = new ethers.Contract(
QUOTER_CONTRACT_ADDRESS,
Quoter.abi,
getProvider()
)
We get access to the contract's ABI through the @uniswap/v3-periphery package, which holds the periphery smart contracts of the Uniswap V3 protocol:
import Quoter from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
We get the QUOTE_CONTRACT_ADDRESS for our chain from Github.
We can now use our Quoter contract to obtain the quote.
In an ideal world, the quoter functions would be view
functions, which would make them very easy to query on-chain with minimal gas costs. However, the Uniswap V3 Quoter contracts rely on state-changing calls designed to be reverted to return the desired data. This means calling the quoter will be very expensive and should not be called on-chain.
To get around this difficulty, we can use the callStatic
method provided by the ethers.js Contract
instances.
This is a useful method that submits a state-changing transaction to an Ethereum node, but asks the node to simulate the state change, rather than to execute it. Our script can then return the result of the simulated state change:
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
token0,
token1,
fee,
fromReadableAmount(
CurrentConfig.tokens.amountIn,
CurrentConfig.tokens.in.decimals
).toString(),
0
)
The fromReadableAmount()
function creates the amount of the smallest unit of a token from the full unit amount and the decimals.
The result of the call is the number of output tokens you'd receive for the quoted swap.
It should be noted that quoteExactInputSingle
is only 1 of 4 different methods that the quoter offers:
-
quoteExactInputSingle
- given the amount you want to swap, produces a quote for the amount out for a swap of a single pool -
quoteExactInput
- given the amount you want to swap, produces a quote for the amount out for a swap over multiple pools -
quoteExactOutputSingle
- given the amount you want to get out, produces a quote for the amount in for a swap over a single pool -
quoteExactOutput
- given the amount you want to get out, produces a quote for the amount in for a swap over multiple pools
If we want to trade two tokens that do not share a pool with each other, we will need to make swaps over multiple pools.
This is where the quoteExactInput
and quoteExactOutput
methods come in.
We will dive deeper into routing in the routing guide.
For the exactOutput
and exactOutputSingle
methods, we need to keep in mind that a pool can not give us more than the amount of Tokens it holds.
If we try to get a quote on an output of 100 WETH from a Pool that only holds 50 WETH, the function call will fail.
Referencing the QuoterV2 contract and getting a quote
const quoterV2Contract = new ethers.Contract(
QUOTER_V2_CONTRACT_ADDRESS,
QuoterV2.abi,
getProvider()
)
We get the QUOTE_V2_CONTRACT_ADDRESS for our chain from V3 refrence deployments.
We get access to the contract's ABI through the @uniswap/v3-periphery package, which holds the periphery smart contracts of the Uniswap V3 protocol:
import Quoter as QuoterV2 from '@uniswap/v3-periphery/artifacts/contracts/lens/QuoterV2.sol/QuoterV2.json'
Let's get the quote for our tokens, where "Quoter" takes multiple arguments in quoteExactInputSingle(), QuoterV2 takes only one argument in the form of an object
const quote = await quoterContract.callStatic.quoteExactInputSingle(
{
tokenIn: tokenIn.address, // tokenIn is of type Token
tokenOut: tokenOut.address, // tokenOut is of type Token
fee: fee, // eg. 3000
amountIn: fromReadableAmount(amountIn, tokenIn.decimals).toString(),
sqrtPriceLimitX96: 0,
}
);
console.log(quote.amountOut);
This will return you "amountOut" , "gasEstimate", "initializedTicksCrossed" and "sqrtPriceX96After"
-
AmountOut: The tokens or cryptocurrency received in a Uniswap swap transaction.
-
Gas Estimate: Estimated amount of gas required for executing a Uniswap transaction on the Ethereum network.
-
InitializedTicksCrossed: In Uniswap V3, indicates whether liquidity has crossed certain price thresholds within a liquidity range.
-
SqrtPriceX96After: Square root of the price after a Uniswap V3 transaction, essential for determining pricing accuracy.