83 lines
3.2 KiB
TypeScript
83 lines
3.2 KiB
TypeScript
import { CurrencyAmount, Fraction, JSBI, Percent, TokenAmount, Trade } from '@pancakeswap/sdk'
|
|
import {
|
|
BLOCKED_PRICE_IMPACT_NON_EXPERT,
|
|
ALLOWED_PRICE_IMPACT_HIGH,
|
|
ALLOWED_PRICE_IMPACT_LOW,
|
|
ALLOWED_PRICE_IMPACT_MEDIUM,
|
|
} from '../config/constants'
|
|
|
|
import { Field } from '../state/swap/actions'
|
|
import { basisPointsToPercent } from './index'
|
|
|
|
const BASE_FEE = new Percent(JSBI.BigInt(25), JSBI.BigInt(10000))
|
|
const ONE_HUNDRED_PERCENT = new Percent(JSBI.BigInt(10000), JSBI.BigInt(10000))
|
|
const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE)
|
|
|
|
// computes price breakdown for the trade
|
|
export function computeTradePriceBreakdown(trade?: Trade | null): {
|
|
priceImpactWithoutFee: Percent | undefined
|
|
realizedLPFee: CurrencyAmount | undefined | null
|
|
} {
|
|
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
|
|
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
|
|
const realizedLPFee = !trade
|
|
? undefined
|
|
: ONE_HUNDRED_PERCENT.subtract(
|
|
trade.route.pairs.reduce<Fraction>(
|
|
(currentFee: Fraction): Fraction => currentFee.multiply(INPUT_FRACTION_AFTER_FEE),
|
|
ONE_HUNDRED_PERCENT,
|
|
),
|
|
)
|
|
|
|
// remove lp fees from price impact
|
|
const priceImpactWithoutFeeFraction = trade && realizedLPFee ? trade.priceImpact.subtract(realizedLPFee) : undefined
|
|
|
|
// the x*y=k impact
|
|
const priceImpactWithoutFeePercent = priceImpactWithoutFeeFraction
|
|
? new Percent(priceImpactWithoutFeeFraction?.numerator, priceImpactWithoutFeeFraction?.denominator)
|
|
: undefined
|
|
|
|
// the amount of the input that accrues to LPs
|
|
const realizedLPFeeAmount =
|
|
realizedLPFee &&
|
|
trade &&
|
|
(trade.inputAmount instanceof TokenAmount
|
|
? new TokenAmount(trade.inputAmount.token, realizedLPFee.multiply(trade.inputAmount.raw).quotient)
|
|
: CurrencyAmount.ether(realizedLPFee.multiply(trade.inputAmount.raw).quotient))
|
|
|
|
return { priceImpactWithoutFee: priceImpactWithoutFeePercent, realizedLPFee: realizedLPFeeAmount }
|
|
}
|
|
|
|
// computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips
|
|
export function computeSlippageAdjustedAmounts(
|
|
trade: Trade | undefined,
|
|
allowedSlippage: number,
|
|
): { [field in Field]?: CurrencyAmount } {
|
|
const pct = basisPointsToPercent(allowedSlippage)
|
|
return {
|
|
[Field.INPUT]: trade?.maximumAmountIn(pct),
|
|
[Field.OUTPUT]: trade?.minimumAmountOut(pct),
|
|
}
|
|
}
|
|
|
|
export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3 | 4 {
|
|
if (!priceImpact?.lessThan(BLOCKED_PRICE_IMPACT_NON_EXPERT)) return 4
|
|
if (!priceImpact?.lessThan(ALLOWED_PRICE_IMPACT_HIGH)) return 3
|
|
if (!priceImpact?.lessThan(ALLOWED_PRICE_IMPACT_MEDIUM)) return 2
|
|
if (!priceImpact?.lessThan(ALLOWED_PRICE_IMPACT_LOW)) return 1
|
|
return 0
|
|
}
|
|
|
|
export function formatExecutionPrice(trade?: Trade, inverted?: boolean): string {
|
|
if (!trade) {
|
|
return ''
|
|
}
|
|
return inverted
|
|
? `${trade.executionPrice.invert().toSignificant(6)} ${trade.inputAmount.currency.symbol} / ${
|
|
trade.outputAmount.currency.symbol
|
|
}`
|
|
: `${trade.executionPrice.toSignificant(6)} ${trade.outputAmount.currency.symbol} / ${
|
|
trade.inputAmount.currency.symbol
|
|
}`
|
|
}
|