Skip to content

Commit

Permalink
(fix) resolve inaccurate pricing APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
OjusWiZard committed Dec 19, 2023
1 parent 57ff5d3 commit bdc1f56
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 52 deletions.
11 changes: 3 additions & 8 deletions src/connectors/quipuswap/quipuswap.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,21 @@ export function getQuipuTrade(
quipuswap: QuipuSwap,
req: PriceRequest
) {
const baseToken: Token = getFullTokenFromSymbol(
quipuswap,
req.base
);
const requestAmount = new BigNumber(
BigNumber(req.amount).toFixed(baseToken.metadata.decimals).replace('.', '')
req.amount
);

let expectedTrade: TradeInfo;
let expectedAmount: BigNumber;
if (req.side === 'BUY') {
expectedTrade = quipuswap.estimateBuyTrade(
req.quote,
req.base,
req.quote,
requestAmount,
req.allowedSlippage
);
expectedAmount = expectedTrade.inputAmount;
} else {
expectedTrade = quipuswap.estimateBuyTrade(
expectedTrade = quipuswap.estimateSellTrade(
req.base,
req.quote,
requestAmount,
Expand Down
15 changes: 7 additions & 8 deletions src/connectors/quipuswap/quipuswap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ export class QuipuSwap extends QuipuBase {
* @param allowedSlippageStr (Optional) should be of the form '1/10'.
*/
public getAllowedSlippage(allowedSlippageStr?: string): BigNumber {
if (allowedSlippageStr != null && isFractionString(allowedSlippageStr)) {
if (allowedSlippageStr !== undefined && isFractionString(allowedSlippageStr)) {
const fractionSplit = allowedSlippageStr.split('/');
const numerator = BigNumber(fractionSplit[0]);
const denominator = BigNumber(fractionSplit[1]);
if (fractionSplit[0] !== '0')
return numerator.multipliedBy(100).dividedBy(denominator);
}
return BigNumber(QuipuswapConfig.config.allowedSlippage);
const fractionSplit = QuipuswapConfig.config.allowedSlippage.split('/');
const numerator = BigNumber(fractionSplit[0]);
const denominator = BigNumber(fractionSplit[1]);
return BigNumber(numerator.multipliedBy(100).dividedBy(denominator));
}

/**
Expand All @@ -72,8 +75,7 @@ export class QuipuSwap extends QuipuBase {
allowedSlippage?: string
): TradeInfo {
const allowedSlippageBig = this.getAllowedSlippage(allowedSlippage);
const sellingInfo = this.getSellingInfo(baseToken, quoteToken, amount, allowedSlippageBig);
return sellingInfo;
return this.getSellingInfo(baseToken, quoteToken, amount, allowedSlippageBig);
}

/**
Expand All @@ -91,11 +93,8 @@ export class QuipuSwap extends QuipuBase {
baseToken: string,
quoteToken: string,
amount: BigNumber,
allowedSlippage?: string
): TradeInfo {
const allowedSlippageBig = this.getAllowedSlippage(allowedSlippage);
const buyingInfo = this.getBuyingInfo(baseToken, quoteToken, amount, allowedSlippageBig);
return buyingInfo;
return this.getBuyingInfo(baseToken, quoteToken, amount);
}

/**
Expand Down
42 changes: 25 additions & 17 deletions src/connectors/quipuswap/utils/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { STABLESWAP_REFERRAL, networkInfo } from './config/config';
import { QUIPUSWAP_REFERRAL_CODE } from './config/constants';
import { SwapPair } from './shared/types';
import { getWhitelistedPairs } from './api';
import { getRoutePairsCombinations, getTradeWithSlippageTolerance } from './swap.router.sdk.adapters';
import { getRoutePairsCombinations } from './swap.router.sdk.adapters';
import { Trade, getBestTradeExactInput, getBestTradeExactOutput, getTradeInputAmount, getTradeOpParams, getTradeOutputAmount, parseTransferParamsToParamsWithKind } from 'swap-router-sdk';
import { ResponseInterface } from 'swap-router-sdk/dist/interface/response.interface';
import { RoutePair } from 'swap-router-sdk/dist/interface/route-pair.interface';
import { WhitelistedPair } from 'swap-router-sdk/dist/interface/whitelisted-pair.interface';
import { calculateTradeExactInput, calculateTradeExactOutput } from './trade';


export class QuipuBase {
Expand Down Expand Up @@ -111,51 +112,58 @@ export class QuipuBase {
const swapPair: SwapPair = { inputToken, outputToken };
const { outputAmount, trade } = this.getOutputTrade(inputAmount, swapPair);

const bestTradeWithSlippageTolerance = getTradeWithSlippageTolerance(
if (!trade) {
throw new Error('No trade found');
}

const bestTradeWithSlippageTolerance = calculateTradeExactInput(
toAtomic(inputAmount, inputToken),
trade,
slippageTolerance
slippageTolerance.toNumber()
);

if (!bestTradeWithSlippageTolerance) {
throw new Error('No best trade found');
}
const lastBestTrade = bestTradeWithSlippageTolerance[bestTradeWithSlippageTolerance.length - 1];
const outputTokenDecimalPower = BigNumber(10).pow(outputToken.metadata.decimals);
const outputAmountWithSlippage = BigNumber(lastBestTrade.bTokenAmount).div(outputTokenDecimalPower);

return {
trade: bestTradeWithSlippageTolerance,
inputToken: inputToken,
inputAmount: inputAmount,
outputToken: outputToken,
outputAmount: outputAmount,
outputAmount: outputAmountWithSlippage,
price: outputAmount.div(inputAmount),
};
};


protected getBuyingInfo = (outputTokenSymbol: string, inputTokenSymbol: string, outputAmount: BigNumber, slippageTolerance: BigNumber) => {
protected getBuyingInfo = (outputTokenSymbol: string, inputTokenSymbol: string, outputAmount: BigNumber) => {
const inputToken = this.getTokenFromSymbol(inputTokenSymbol);
const outputToken = this.getTokenFromSymbol(outputTokenSymbol);

const swapPair: SwapPair = { inputToken, outputToken };
const { inputAmount, trade } = this.getInputTrade(outputAmount, swapPair);

const bestTradeWithSlippageTolerance = getTradeWithSlippageTolerance(
toAtomic(inputAmount, inputToken),
trade,
slippageTolerance
if (!trade) {
throw new Error('No trade found');
}

const bestTradeWithSlippageTolerance = calculateTradeExactOutput(
toAtomic(outputAmount, outputToken),
trade
);

if (!bestTradeWithSlippageTolerance) {
throw new Error('No best trade found');
}
const firstBestTrade = bestTradeWithSlippageTolerance[0];
const inputTokenDecimalPower = BigNumber(10).pow(inputToken.metadata.decimals);
const inputAmountWithSlippage = BigNumber(firstBestTrade.aTokenAmount).div(inputTokenDecimalPower);

return {
trade: bestTradeWithSlippageTolerance,
inputToken: inputToken,
inputAmount: inputAmount,
inputAmount: inputAmountWithSlippage,
outputToken: outputToken,
outputAmount: outputAmount,
price: outputAmount.div(inputAmount),
price: inputAmount.div(outputAmount),
};
};

Expand Down
8 changes: 8 additions & 0 deletions src/connectors/quipuswap/utils/swap.outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,12 @@ export const findAmmSwapOutput = (aTokenAmount: BigNumber, pair: TradeOperation)
const numerator = aTokenAmountWithFee.times(pair.bTokenPool);
const denominator = pair.aTokenPool.plus(aTokenAmountWithFee);
return numerator.idiv(denominator);
};

export const findAmmSwapInput = (bTokenAmount: BigNumber, pair: TradeOperation) => {
const feeRatio = getPairFeeRatio(pair);
const numerator = pair.aTokenPool.times(bTokenAmount);
const denominator = pair.bTokenPool.minus(bTokenAmount).times(feeRatio);
const input = numerator.idiv(denominator).plus(1);
return input.isGreaterThan(0) ? input : new BigNumber(Infinity);
};
18 changes: 0 additions & 18 deletions src/connectors/quipuswap/utils/swap.router.sdk.adapters.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import BigNumber from "bignumber.js";
import {
TokenStandardEnum,
Trade,
getAllowedRoutePairsCombinations as originalGetAllowedRoutePairsCombinations
} from "swap-router-sdk";
import { RoutePair } from "swap-router-sdk/dist/interface/route-pair.interface";
import { getTokenIdFromSlug, getTokenSlug, isExist, isTezosToken } from "./shared/helpers";
import { SwapPair, Token } from "./shared/types";
import { MAX_HOPS_COUNT } from "./config/constants";
import { calculateTradeExactInput } from "./trade";
import { WhitelistedPair } from "swap-router-sdk/dist/interface/whitelisted-pair.interface";

const FALLBACK_TOKEN_ID = 0;
Expand Down Expand Up @@ -49,18 +46,3 @@ export const getRoutePairsCombinations = (
MAX_HOPS_COUNT
);
};


export const getTradeWithSlippageTolerance = (
inputAmount: BigNumber,
bestTrade: Trade,
tradingSlippage: BigNumber
) => {
const originalValue = calculateTradeExactInput(
inputAmount,
bestTrade,
tradingSlippage.toNumber()
);

return bestTrade && originalValue;
};
55 changes: 54 additions & 1 deletion src/connectors/quipuswap/utils/trade.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BigNumber from "bignumber.js";
import { DexTypeEnum, Trade, TradeOperation } from "swap-router-sdk";
import { findAmmSwapOutput, findFlatCfmmSwapOutput, findPlentyBridgeSwapOutput, findQuipuCurveLikeSwapOutput, findQuipuSwapV3Output, findSpicyWrapOutput } from "./swap.outputs";
import { findAmmSwapInput, findAmmSwapOutput, findFlatCfmmSwapOutput, findPlentyBridgeSwapOutput, findQuipuCurveLikeSwapOutput, findQuipuSwapV3Output, findSpicyWrapOutput } from "./swap.outputs";


const findSwapOutput = (aTokenAmount: BigNumber, pair: TradeOperation) => {
Expand Down Expand Up @@ -63,3 +63,56 @@ export const calculateTradeExactInput = (inputAssetAmount: BigNumber, routePairs

return trade;
};

const findSwapInput = (bTokenAmount: BigNumber, pair: TradeOperation) => {
switch (pair.dexType) {
case DexTypeEnum.Youves:
case DexTypeEnum.PlentyStableSwap:
case DexTypeEnum.PlentyCtez:
// return findFlatCfmmSwapInput(bTokenAmount, pair);
return BigNumber(Infinity);

case DexTypeEnum.QuipuSwapCurveLike:
// return findQuipuCurveLikeSwapInput(bTokenAmount, pair);
return new BigNumber(Infinity);

case DexTypeEnum.PlentyBridge:
return new BigNumber(0);

case DexTypeEnum.QuipuSwapV3:
// return findQuipuSwapV3Input(bTokenAmount, pair);
return new BigNumber(Infinity);

case DexTypeEnum.YupanaWtez:
return bTokenAmount;

default:
return findAmmSwapInput(bTokenAmount, pair);
}
};

const getTradeOperationExactOutput = (bTokenAmount: BigNumber, pair: TradeOperation) => ({
...pair,
bTokenAmount: bTokenAmount,
aTokenAmount: findSwapInput(bTokenAmount, pair)
});

export const calculateTradeExactOutput = (outputAssetAmount: BigNumber, routePairs: Trade) => {
const trade = [];

if (routePairs.length > 0) {
const lastTradeIndex = routePairs.length - 1;
const firstTradeOperation = getTradeOperationExactOutput(outputAssetAmount, routePairs[lastTradeIndex]);
trade.unshift(firstTradeOperation);

if (routePairs.length > 1) {
for (let i = lastTradeIndex - 1; i >= 0; i--) {
const previousTradeInput = trade[0].aTokenAmount;
const tradeOperation = getTradeOperationExactOutput(previousTradeInput, routePairs[i]);
trade.unshift(tradeOperation);
}
}
}

return trade;
};

0 comments on commit bdc1f56

Please sign in to comment.