UNPKG

@hikaru-fi/swap-router

Version:

Package for calculating optimal path for executing swaps

144 lines (131 loc) 4.02 kB
const { toBN } = require("web3-utils"); const { WeightedPool } = require ("../poolMath/weightedPool/weightedPool"); const { SwapTypes } = require ("../utils/types"); const { getPoolsOfInterest } = require ("./filtering"); const ZERO = toBN(0); /** * @typedef SwapPath * @property {String} poolAddress * @property {String} vaultAddress * @property {String} tokenIn * @property {String} tokenOut */ /** * @typedef SwapRoute * @property {SwapPath[]} path */ /** * @param {WeightedPool} pool * @param {String} tokenIn * @param {String} tokenOut * @returns {SwapRoute} */ function getSwapPath( pool, tokenIn, tokenOut ) { return { path: [{ poolAddress: pool.address, vaultAddress: pool.vaultAddress, tokenIn, tokenOut }] } } /** * * @param {WeightedPool[]} pools * @param {String[]} tokens * @returns {SwapRoute} */ function createMultipleSwapsPath( pools, tokens ) { const firstPool = pools[0]; const secondPool = pools[1]; const tokenIn = tokens[0]; const hopToken = tokens[1]; const tokenOut = tokens[2]; return { path: [{ poolAddress: firstPool.address, vaultAddress: firstPool.vaultAddress, tokenIn, tokenOut: hopToken }, { poolAddress: secondPool.address, vaultAddress: secondPool.vaultAddress, tokenIn: hopToken, tokenOut }] } } /** * * @param {import("./poolCache").PoolDictionary} pools * @param {String} tokenIn * @param {String} tokenOut * @param {BN} amountIn * @returns {SwapRoute[][]} */ function producePaths( pools, tokenIn, tokenOut ) { const [direct, hopsIn, hopsOut] = getPoolsOfInterest(pools, tokenIn, tokenOut); const directPaths = []; for (const poolAddress in direct) { directPaths.push( getSwapPath(direct[poolAddress][0], tokenIn, tokenOut) ); } const hopPaths = []; for (const hopToken in hopsIn) { if (hopsOut[hopToken]) { let highestNormalizedLiquidityFirst = ZERO; let highestNormalizedLiquidityFirstPool = undefined; let highestNormalizedLiqiuditySecond = ZERO; let highestNormalizedLiquiditySecondPool = undefined; for (const poolIn of hopsIn[hopToken]) { const normalizedLiquidity = poolIn.getNormalizedLiquidity(tokenIn, hopToken); if ( normalizedLiquidity.gte( highestNormalizedLiquidityFirst ) ) { highestNormalizedLiquidityFirst = normalizedLiquidity; highestNormalizedLiquidityFirstPool = poolIn; } } for (const poolOut of hopsOut[hopToken]) { const normalizedLiquidity = poolOut.getNormalizedLiquidity(hopToken, tokenOut); if ( normalizedLiquidity.gte( highestNormalizedLiqiuditySecond ) ) { highestNormalizedLiqiuditySecond = normalizedLiquidity; highestNormalizedLiquiditySecondPool = poolOut; } } if ( !!highestNormalizedLiquidityFirstPool && !!highestNormalizedLiquiditySecondPool ) { hopPaths.push( createMultipleSwapsPath( [highestNormalizedLiquidityFirstPool, highestNormalizedLiquiditySecondPool], [tokenIn, hopToken, tokenOut] ) ) } } } return [directPaths, hopPaths]; } module.exports = { getSwapPath, createMultipleSwapsPath, producePaths }