Swaps
Getting a Quote
The process involves using the quoteExactInputSingle
function to fetch a quote for swapping a specific token pair. In this example, we’ll focus on the USDC - WIP pair. The function requires input parameters such as the token being swapped, the token being received, the amount to swap, and the swap fee.
The swap fee represents the portion of the trade allocated to liquidity providers. It is one of the key identifiers of a Pool, along with the input and output tokens.
The steps include:
Computing the Pool’s deployment address
Referencing the Pool contract and fetching metadata
Using the Quoter contract to get a quote
At the end of this process, you’ll be able to retrieve a quote for the given token pair and input amount programmatically.
Example Configuration
Here is a basic example configuration:
import { Token } from '@storyhunt/sdk-core';
interface ExampleConfig {
rpc: {
local: string;
mainnet: string;
};
tokens: {
in: Token;
amountIn: number;
out: Token;
poolFee: number;
};
}
export const CurrentConfig: ExampleConfig = {
rpc: {
local: 'http://localhost:8545',
testnet: 'https://odyssey.storyrpc.io',
},
tokens: {
in: USDC_TOKEN,
amountIn: 1000,
out: WIP_TOKEN,
poolFee: FeeAmount.MEDIUM,
},
};
The rpc
endpoint and tokens can be updated as needed to connect to the desired environment or Pool.
Computing the Pool’s Deployment Address
To interact with the USDC - WIP Pool contract, compute its deployment address using the SDK’s utility function:
import { computePoolAddress } from '@storyhunt/v3-sdk';
const currentPoolAddress = computePoolAddress({
factoryAddress: POOL_FACTORY_CONTRACT_ADDRESS,
tokenA: CurrentConfig.tokens.in,
tokenB: CurrentConfig.tokens.out,
fee: CurrentConfig.tokens.poolFee,
});
Each Storyhunt V3 Pool is uniquely identified by the input token, output token, and fee. These parameters, along with the PoolFactory contract address, determine the Pool’s deployment address.
Referencing the Pool Contract and Fetching Metadata
Once the Pool address is computed, use it to create a reference to the Pool contract:
import { ethers } from 'ethers';
const provider = new ethers.providers.JsonRpcProvider(CurrentConfig.rpc.testnet);
const poolContract = new ethers.Contract(
currentPoolAddress,
IStoryhuntV3PoolABI.abi,
provider
);
The Pool contract’s ABI can be imported from the Storyhunt SDK core package. Use the contract instance to fetch relevant metadata:
const [token0, token1, fee, liquidity, slot0] = await Promise.all([
poolContract.token0(),
poolContract.token1(),
poolContract.fee(),
poolContract.liquidity(),
poolContract.slot0(),
]);
These values are essential inputs for quoting functions.
Referencing the Quoter Contract and Getting a Quote
Use the Quoter contract to fetch trade quotes without executing the trade:
const quoterContract = new ethers.Contract(
QUOTER_CONTRACT_ADDRESS,
Quoter.abi,
provider
);
const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
CurrentConfig.tokens.in.address,
CurrentConfig.tokens.out.address,
CurrentConfig.tokens.poolFee,
fromReadableAmount(
CurrentConfig.tokens.amountIn,
CurrentConfig.tokens.in.decimals
).toString(),
0
);
The fromReadableAmount()
function converts token amounts to their smallest units based on the token’s decimals. The result is the estimated number of output tokens for the swap.
Quoting Methods
The Quoter contract offers four methods:
quoteExactInputSingle
: Estimates output for a given input amount in a single pool.quoteExactInput
: Estimates output for a given input amount across multiple pools.quoteExactOutputSingle
: Estimates input required for a given output amount in a single pool.quoteExactOutput
: Estimates input required for a given output amount across multiple pools.
For multi-pool trades, use quoteExactInput
or quoteExactOutput
. Keep in mind that Pool liquidity limits the maximum token output available for a swap.