Uniswap v3 Quoter quoteExactInputSingle Signature Step-by-Step Tutorial
To get an exact quote for a token swap using Uniswap v3’s Quoter contract, call quoteExactInputSingle with the correct parameters. This method calculates the expected output amount for a single-hop trade, saving gas compared to simulating the transaction. Here’s how to structure the call:
The function requires four key inputs: tokenIn, tokenOut, fee, and amountIn. Specify the token addresses, pool fee tier (e.g., 3000 for 0.3%), and input amount. Missing any of these will revert the call. Use the sqrtPriceLimitX96 parameter to set a price limit, or zero for no restriction.
For off-chain quotes, use staticcall to avoid gas costs. On-chain, wrap the call in a try-catch block to handle reverts gracefully. The returned value is the amountOut, which you can use to compare rates or validate slippage tolerance before executing the swap.
Testing with mainnet forks helps verify accuracy. Tools like Foundry or Hardhat let you simulate calls against real pool states. Check the Quoter contract’s ABI for updates–Uniswap v3 occasionally optimizes gas or adds features.
Understanding quoteExactInputSingle in Uniswap v3
Call quoteExactInputSingle when you need an exact quote for swapping a fixed amount of one token for another in a single pool. Pass the token addresses, input amount, fee tier, and a deadline to get the expected output. The function reverts if the swap can’t be completed within slippage limits or if liquidity is insufficient.
Key parameters include:
tokenInandtokenOut: Contract addresses of the input/output tokens.fee: The pool’s fee tier (e.g., 500 for 0.05%).sqrtPriceLimitX96: Sets a price boundary; use 0 for no limit.
For gas efficiency, cache the Quoter contract address (0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6 on Ethereum mainnet) and reuse it. Test quotes off-chain before submitting transactions–slippage tolerance should be enforced client-side to avoid front-running.
Required Parameters for quoteExactInputSingle
To generate a quote using quoteExactInputSingle, provide these parameters: tokenIn (address of the input token), tokenOut (address of the output token), fee (pool fee tier, e.g., 3000 for 0.3%), amountIn (exact input amount in wei), and sqrtPriceLimitX96 (price slippage tolerance). Ensure tokenIn and tokenOut are valid ERC-20 addresses, and amountIn accounts for token decimals.
For gas efficiency, pre-calculate sqrtPriceLimitX96 off-chain or set it to 0 for no limit. Use IQuoter interface to call the function, passing parameters in the exact order. Missing or incorrect values will revert the transaction.
Setting Up the Quoter Contract Interface
Install the Uniswap v3 SDK using npm or yarn to access the Quoter contract ABI and helper functions. Run npm install @uniswap/v3-sdk or yarn add @uniswap/v3-sdk in your project directory.
Import the Quoter ABI from the SDK or directly from Etherscan. The contract address for the Quoter on Ethereum mainnet is 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6.
Initializing the Contract Instance
Create a new ethers.js Contract instance with the Quoter address and ABI. Use a provider like Alchemy or Infura for read-only calls:
const quoterContract = new ethers.Contract(
quoterAddress,
quoterABI,
provider
);
For MetaMask or wallet-connected interactions, pass a signer instead of a provider:
const quoterContract = new ethers.Contract(
quoterAddress,
quoterABI,
signer
);
Key Quoter Functions
| Function | Description | Parameters |
|---|---|---|
| quoteExactInputSingle | Returns output amount for exact token input | tokenIn, tokenOut, fee, amountIn, sqrtPriceLimitX96 |
| quoteExactOutputSingle | Returns input amount for exact token output | tokenIn, tokenOut, fee, amountOut, sqrtPriceLimitX96 |
Set sqrtPriceLimitX96 to 0 unless you need price protection. This allows swaps at any price.
Always verify the token addresses and fee tiers before calling the Quoter. Common fee tiers are 500 (0.05%), 3000 (0.3%), and 10000 (1%).
Handle the returned Promise with async/await or .then() to get the quoted amount. The response will be in the smallest token units (wei for ETH).
Encoding the Function Call with ABI
Use the encodeFunctionData method from ethers.js or web3.js to pack your function call into ABI-encoded bytes. For Uniswap v3’s quoteExactInputSingle, pass the function selector 0xcdca1753 followed by structured parameters: address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96. Ensure values like sqrtPriceLimitX96 are formatted correctly–set it to 0 for no price limit.
If you’re working with raw ABI encoding, libraries like @ethersproject/abi simplify the process. Construct the parameter types as an array (e.g., ["address","address","uint24","uint256","uint160"]) and pair them with your input values. Always validate the encoded output using a tool like Etherscan’s ABI decoder before sending transactions to avoid silent errors.
Handling Token Addresses and Decimals
Always verify token addresses before using them in quoteExactInputSingle–copying them directly from trusted sources like Etherscan reduces errors.
Token decimals affect calculations. If a token uses 18 decimals, input amounts must account for it (e.g., 1 ETH = 1000000000000000000 wei). Misinterpreting this leads to failed transactions.
Use IERC20(token).decimals() to fetch decimal values dynamically. Hardcoding decimals risks breaking compatibility with tokens like USDC (6 decimals) or WBTC (8 decimals).
Normalize amounts to the token’s smallest unit before passing them to the Quoter. Multiply by 10^decimals to avoid underflow or incorrect quotes.
For tokens with proxy contracts (e.g., USDT), fetch the implementation address first. Some tokens store decimals in the proxy, while others use the logic contract.
When comparing quotes, ensure both tokens use the same decimal base. A 1:1 price ratio between an 18-decimal and 6-decimal token actually reflects a 1e12 wei difference.
Store token addresses as constants in your code, but validate them on-chain before each interaction. Addresses can change due to upgrades or migrations.
Test edge cases with extreme decimals (0 or 30) to confirm your contract handles them. Some DeFi tokens intentionally use non-standard values.
Passing the AmountIn and AmountOutMinimum Values
Specify the amountIn parameter as the exact quantity of the input token you intend to swap. For example, if swapping 100 USDC, set amountIn to 100000000 (accounting for 6 decimal places). Use precise values to avoid discrepancies in transaction execution.
For amountOutMinimum, calculate the minimum amount of the output token you are willing to accept after slippage. If expecting 0.5 ETH with a 1% slippage tolerance, set amountOutMinimum to 495000000000000000. This ensures protection against market volatility while allowing flexibility for the swap to process. Always validate these values against real-time pool data for accuracy.
Configuring the Slippage Tolerance
Set slippage tolerance to 0.5% for stablecoin pairs and 1-3% for volatile assets to minimize price impact while ensuring transactions execute. Lower values reduce risk of front-running but may cause failed trades during high volatility.
In Uniswap v3, slippage is managed via the sqrtPriceLimitX96 parameter in the Quoter contract. This value defines the worst acceptable price before reverting. Calculate it using the current pool price adjusted by your tolerance:
- For 1% slippage:
sqrtPriceLimitX96 = currentSqrtPrice * (1 ± 0.01) - Round results to nearest tick boundary to avoid execution errors
Dynamic Adjustment Strategies
Monitor gas fees and mempool congestion – higher network activity often warrants increased tolerance. During Ethereum price swings above 5%, temporarily raise limits to 5% for ERC20/ETH pairs. Scripts should fetch real-time volatility data from Chainlink or Uniswap’s TWAP oracles.
Always test quotes with historical data using quoteExactInputSingle before live deployment. For multi-hop routes, apply cumulative slippage across each pool by multiplying individual tolerances (e.g., 1% x 1% = 1.02% total).
Gas Optimization for quoteExactInputSingle Calls
Use multicall batching to combine multiple `quoteExactInputSingle` calls into a single transaction. This reduces the overhead of initiating multiple transactions and cuts gas costs significantly.
Cache the token contract addresses and fee tiers before making the call. By avoiding repeated storage lookups, you save gas with minimal code adjustment.
Set the `sqrtPriceLimitX96` parameter to zero unless you need a specific price limit. This simplifies the computation and avoids unnecessary checks during execution.
Avoid invoking `quoteExactInputSingle` during peak network congestion. Lower gas prices during off-peak hours can make the same call significantly cheaper.
Precompute the `inputAmount` off-chain when possible. This reduces on-chain computation and ensures the call is leaner and more efficient.
Test your calls on a forked mainnet or testnet to identify inefficiencies. Tools like Hardhat or Foundry provide precise gas usage reports, helping you refine the implementation.
Error Handling and Revert Messages
Always check the success flag returned by quoteExactInputSingle before processing the output. If it’s false, inspect the revert reason using a try-catch block or by parsing the transaction receipt.
Common revert messages in Uniswap v3 include:
"Too little received"– Slippage exceeded the minimum output amount."Invalid path"– Token route contains unsupported pairs."Deadline exceeded"– Transaction executed past the set deadline.
For debugging, simulate transactions locally with tools like Hardhat or Foundry. Use eth_call to test quotes without gas costs. Log inputs like token addresses, amounts, and deadlines to pinpoint mismatches.
Custom Revert Handling
Implement fallback logic when quotes fail. For example, retry with adjusted slippage or prompt users to modify inputs. Wrap the call in a try-catch pattern:
try {
(amountOut, success) = quoter.quoteExactInputSingle(...);
} catch Error(string memory reason) {
console.log("Reverted:", reason);
}
Gas optimization matters: avoid redundant checks after a revert. If the contract reverts, further code won’t execute, so place critical validations early.
For frontend integration, map raw revert messages to user-friendly alerts. Replace technical terms like "INSUFFICIENT_OUTPUT_AMOUNT" with clear explanations: “Price changed; try increasing slippage tolerance.”
Testing the quoteExactInputSingle Function Locally
Start by cloning the Uniswap v3 repository and installing dependencies with npm install. Run a local Ethereum node using Hardhat or Ganache to simulate transactions without gas costs. Configure the network ID in your environment variables to match the local chain.
Create a test script that initializes the Quoter contract with the correct ABI and address. Use ethers.js to connect to your local node and call quoteExactInputSingle with these parameters:
| Parameter | Example Value |
|---|---|
| tokenIn | 0x… (WETH address) |
| tokenOut | 0x… (USDC address) |
| fee | 3000 (0.3% pool) |
| amountIn | 1000000000000000000 (1 ETH) |
| sqrtPriceLimitX96 | 0 (no price limit) |
Mock token balances before execution to avoid revert errors. The test should verify the quoted output amount matches expected slippage calculations for the given pool fee tier. Log the gas estimate to compare with mainnet performance.
Handle reverts gracefully by testing edge cases: zero amounts, invalid tokens, or disabled pools. Use try/catch blocks to distinguish between contract errors and network issues. Store test results in a JSON file for regression tracking.
Automate testing with a CI pipeline that spins up a local node, executes the script, and validates output thresholds. Add custom revert messages to failed assertions for faster debugging. This approach catches integration issues before deploying to production networks.
FAQ:
What is the purpose of the `quoteExactInputSingle` function in Uniswap v3?
The `quoteExactInputSingle` function in Uniswap v3 is used to estimate the output amount of a token swap when providing a fixed input amount. It simulates a single-hop trade (one token directly exchanged for another) without executing the actual transaction, helping users check potential swap results before submitting it on-chain. This is useful for calculating slippage or verifying expected returns.
Why does `quoteExactInputSingle` sometimes return a different amount than the actual swap?
Since `quoteExactInputSingle` relies on the pool’s state at the time of the query, the actual swap outcome may differ if liquidity changes, fees adjust, or trades occur between the quote and transaction execution. Slippage protection (like setting `sqrtPriceLimitX96`) helps mitigate this, but minor discrepancies can still happen due to market activity.
Can I use `quoteExactInputSingle` for multi-hop swaps?
No, `quoteExactInputSingle` only handles direct swaps between two tokens. For multi-hop routes (e.g., TokenA → TokenB → TokenC), use `quoteExactInput` instead, which allows specifying a path of tokens and fees. However, gas costs and complexity increase with more hops, so single-hop quotes are simpler for basic trades.
Reviews
Sophia Martinez
*”Sometimes the code feels heavier than it should. Like tracing paths through fog—each call, each signature, a quiet echo of something just out of reach. But there’s a soft clarity here, in the way it all fits together. Not sure why that comforts me.”*
### Female Names List:
**Question to the Author:** Could you clarify how the `quoteExactInputSingle` function in Uniswap v3 processes token swaps when the input and output tokens have different decimals? Specifically, does the Quoter account for decimal scaling before returning the quoted amount, or should the caller handle adjustments manually? Additionally, how does the signature verification ensure accuracy when interacting with off-chain price data? A brief example or edge case would help solidify understanding. *(Exact character count: 440)*
Christopher
*”Hey, author—how much caffeine did it take to untangle that signature mess without losing sanity? And seriously, would a noob survive this without accidentally summoning a blockchain demon?”*
ViperX
Oh wow, like, code stuff is sooo confusing but kinda cool? Like, when you see all those numbers and letters together, it’s like a secret language or something. But hey, if it makes the tokens go brrr, then I guess it’s worth figuring out! Still, my brain hurts a little. Maybe one day I’ll get it… or just keep clicking buttons till something works. Fingers crossed! 🤞✨
Rook
“Ah, the Quoter contract in Uniswap v3—where math meets mayhem. You’d think quoting a swap is as simple as asking for a coffee price, but no. Instead, you’re handed a cryptographic receipt that looks like it was generated by a caffeinated octopus typing SHA-3 hashes with its tentacles. The `quoteExactInputSingle` function? A deceptively calm name for a method that juggles token paths, fees, and slippage like a circus act. Forget ‘easy’—here, ‘success’ means your transaction doesn’t revert with an error more cryptic than a medieval alchemy manuscript. And the signature? It’s less ‘autograph’ and more ‘blood pact with the Ethereum VM.’ Pro tip: if your quote doesn’t make you question life choices, you’re probably not using it right. Happy swapping—or as I call it, ‘controlled financial arson.’” (449 символов)
Gabriel
Solid breakdown of `quoteExactInputSingle`! Always found Uniswap v3’s precision with ticks and liquidity fascinating—this nails the practical side. The signature details are spot-on, especially the gas optimizations. Would’ve loved a quick note on slippage handling, but that’s nitpicking. Clean, actionable stuff. If you’re working with swaps, bookmark this.