ShadeSwap Multi-Hop Routing
This page contains an example router that determines the optimal path for maximizing the users output tokens received
Router
Determine Possible Paths
Returns possible paths through one or multiple pools to complete a trade of two tokens.
function getPossiblePaths({
inputTokenContractAddress,
outputTokenContractAddress,
maxHops,
pairs,
}:{
inputTokenContractAddress:string,
outputTokenContractAddress:string
maxHops: number // max number of pairs used
pairs: BatchPairsInfo
}): string[][]
function getPossiblePaths({
inputTokenContractAddress,
outputTokenContractAddress,
maxHops,
pairs,
}:{
inputTokenContractAddress:string,
outputTokenContractAddress:string
maxHops: number // max number of pairs used
pairs: BatchPairsInfo
}): string[][]
See Batch Pairs Query for input type BatchPairsInfo.
WARNING
Increasing the max hops too much can cause decreased performance due to the large amount of computations required to calculate all routes. The current recommendation is 4 max based on the route paths available, but this is subject to change as more pairs are supported over time.
Calculate Route
Calculates the output amount received for a given path
function calculateRoute({
inputTokenAmount,
inputTokenContractAddress,
path,
pairs,
tokens,
}:{
inputTokenAmount: BigNumber, // amount in uDenom
inputTokenContractAddress: string,
path: string[], // path determined by getPossiblePaths
pairs: BatchPairsInfo,
tokens: TokensConfig, // list of all possible swap tokens
}): Route
function calculateRoute({
inputTokenAmount,
inputTokenContractAddress,
path,
pairs,
tokens,
}:{
inputTokenAmount: BigNumber, // amount in uDenom
inputTokenContractAddress: string,
path: string[], // path determined by getPossiblePaths
pairs: BatchPairsInfo,
tokens: TokensConfig, // list of all possible swap tokens
}): Route
TIP
We pass in a list of all possible tokens (TokensConfig) so that we have access to their decimals for uDenom conversions. This is not the most elegant solution as it may be preferable to reference your own data store for token data. In that case, you can create your own route calculator and use the ShadeJS one as a guide.
WARNING
Ensure tokenConfig contains no duplicate tokens as this will trigger an error in order to prevent a bad config from being used.
type TokenConfig = {
tokenContractAddress: string,
decimals: number,
}
type TokensConfig = TokenConfig[]
type TokenConfig = {
tokenContractAddress: string,
decimals: number,
}
type TokensConfig = TokenConfig[]
output
type Route = {
inputAmount: BigNumber,
quoteOutputAmount: BigNumber,
quoteShadeDaoFee: BigNumber,
quoteLPFee: BigNumber,
priceImpact: BigNumber,
inputTokenContractAddress: string,
outputTokenContractAddress: string,
path: string[],
gasMultiplier: number, // multiplier which is to be applied
// to the base gas cost of a swap
};
type Route = {
inputAmount: BigNumber,
quoteOutputAmount: BigNumber,
quoteShadeDaoFee: BigNumber,
quoteLPFee: BigNumber,
priceImpact: BigNumber,
inputTokenContractAddress: string,
outputTokenContractAddress: string,
path: string[],
gasMultiplier: number, // multiplier which is to be applied
// to the base gas cost of a swap
};
Calculate All Possible Routes
Retrieves all potential route options and the outputs of each route. Returns an array of routes in the order that will give the highest quoted output amount. This function utilizes both getPossiblePaths and calculateRoute.
function getRoutes({
inputTokenAmount,
inputTokenContractAddress,
outputTokenContractAddress,
maxHops,
pairs,
tokens,
}: {
inputTokenAmount: BigNumber,
inputTokenContractAddress: string,
outputTokenContractAddress: string,
maxHops: number,
pairs: BatchPairsInfo,
tokens: TokensConfig,
}): Route[]
function getRoutes({
inputTokenAmount,
inputTokenContractAddress,
outputTokenContractAddress,
maxHops,
pairs,
tokens,
}: {
inputTokenAmount: BigNumber,
inputTokenContractAddress: string,
outputTokenContractAddress: string,
maxHops: number,
pairs: BatchPairsInfo,
tokens: TokensConfig,
}): Route[]
WARNING
This function optimizes for maximizing the output token amount only. It does NOT factor in the value of the gas for the extra hops (i.e. gas multiplier) relative to the value of tokens received. This will especially impact small trades where there is perceived arbitrage opportunities through certain paths, without factoring in the gas cost to perform the arbitrage. It is recommended that you create your own route calculator to handle token values and use the one provided here as a guide.
TIP
Any errors encountered during a route calculation (ex: stableswap price impact tolerance exceeded, bad token config, missing pair data, etc.) will result in skipping this route as an option in the output. Errors in all possible routes will return an empty array, meaning that no successful route exists. You are encouraged to modify this example router if you wish to collect specific errors on each possible route and do something with that error data.