@xspswap/smart-order-router
Version:
XSwap Protocol V3 Smart Order Router
101 lines • 9.37 kB
JavaScript
import { BigNumber } from '@ethersproject/bignumber';
import { TradeType } from '@x-swap-protocol/sdk-core';
import { InsufficientInputAmountError, InsufficientReservesError, } from '@x-swap-protocol/v2-sdk';
import { CurrencyAmount } from '../../util/amounts';
import { log } from '../../util/log';
import { routeToString } from '../../util/routes';
import { parseEther } from 'ethers/lib/utils';
/**
* Computes quotes for V2 off-chain. Quotes are computed using the balances
* of the pools within each route provided.
*
* @export
* @class V2QuoteProvider
*/
export class V2QuoteProvider {
/* eslint-disable @typescript-eslint/no-empty-function */
constructor() { }
/* eslint-enable @typescript-eslint/no-empty-function */
async getQuotesManyExactIn(amountIns, routes) {
return this.getQuotes(amountIns, routes, TradeType.EXACT_INPUT);
}
async getQuotesManyExactOut(amountOuts, routes) {
return this.getQuotes(amountOuts, routes, TradeType.EXACT_OUTPUT);
}
async getQuotes(amounts, routes, tradeType) {
const routesWithQuotes = [];
const debugStrs = [];
for (const route of routes) {
const amountQuotes = [];
let insufficientInputAmountErrorCount = 0;
let insufficientReservesErrorCount = 0;
for (const amount of amounts) {
try {
if (tradeType == TradeType.EXACT_INPUT) {
let outputAmount = amount.wrapped;
for (const pair of route.pairs) {
// const [outputAmountNew, pr] = pair.getOutputAmount(outputAmount);
const inputReserve = pair.reserveOf(outputAmount.currency);
const outputReserve = pair.reserveOf(outputAmount.currency.equals(pair.token0)
? pair.token1
: pair.token0);
const inputAmountWithFee = parseEther(outputAmount.quotient.toString()).mul(997);
const numerator = inputAmountWithFee.mul(outputReserve.quotient.toString());
const denominator = parseEther(inputReserve.quotient.toString())
.mul(1000)
.add(inputAmountWithFee);
const outputAmountNew = CurrencyAmount.fromRawAmount(outputAmount.currency.equals(pair.token0)
? pair.token1
: pair.token0, numerator.div(denominator).toString());
outputAmount = outputAmountNew;
}
amountQuotes.push({
amount,
quote: BigNumber.from(outputAmount.quotient.toString()),
});
}
else {
let inputAmount = amount.wrapped;
for (let i = route.pairs.length - 1; i >= 0; i--) {
const pair = route.pairs[i];
[inputAmount] = pair.getInputAmount(inputAmount);
}
amountQuotes.push({
amount,
quote: BigNumber.from(inputAmount.quotient.toString()),
});
}
}
catch (err) {
// Can fail to get quotes, e.g. throws InsufficientReservesError or InsufficientInputAmountError.
if (err instanceof InsufficientInputAmountError) {
insufficientInputAmountErrorCount =
insufficientInputAmountErrorCount + 1;
amountQuotes.push({ amount, quote: null });
}
else if (err instanceof InsufficientReservesError) {
insufficientReservesErrorCount = insufficientReservesErrorCount + 1;
amountQuotes.push({ amount, quote: null });
}
else {
throw err;
}
}
}
if (insufficientInputAmountErrorCount > 0 ||
insufficientReservesErrorCount > 0) {
debugStrs.push(`${[
routeToString(route),
]} Input: ${insufficientInputAmountErrorCount} Reserves: ${insufficientReservesErrorCount} }`);
}
routesWithQuotes.push([route, amountQuotes]);
}
if (debugStrs.length > 0) {
log.info({ debugStrs }, `Failed quotes for V2 routes`);
}
return {
routesWithQuotes,
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGUtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3YyL3F1b3RlLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEQsT0FBTyxFQUNMLDRCQUE0QixFQUM1Qix5QkFBeUIsR0FDMUIsTUFBTSx5QkFBeUIsQ0FBQztBQUdqQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFzQjlDOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCLHlEQUF5RDtJQUN6RCxnQkFBZSxDQUFDO0lBQ2hCLHdEQUF3RDtJQUVqRCxLQUFLLENBQUMsb0JBQW9CLENBQy9CLFNBQTJCLEVBQzNCLE1BQWlCO1FBRWpCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRU0sS0FBSyxDQUFDLHFCQUFxQixDQUNoQyxVQUE0QixFQUM1QixNQUFpQjtRQUVqQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVPLEtBQUssQ0FBQyxTQUFTLENBQ3JCLE9BQXlCLEVBQ3pCLE1BQWlCLEVBQ2pCLFNBQW9CO1FBRXBCLE1BQU0sZ0JBQWdCLEdBQXdCLEVBQUUsQ0FBQztRQUVqRCxN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