fix default trigger price for bonk
by generally restricting significant decimals on prices, instead using the in or output banks decimals.
This commit is contained in:
parent
b1a159d58f
commit
5a5976dc63
|
@ -23,7 +23,11 @@ import { SIZE_INPUT_UI_KEY } from '../../utils/constants'
|
|||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import SwapSlider from './SwapSlider'
|
||||
import PercentageSelectButtons from './PercentageSelectButtons'
|
||||
import { floorToDecimal, formatCurrencyValue } from 'utils/numbers'
|
||||
import {
|
||||
floorToDecimal,
|
||||
floorToDecimalSignificance,
|
||||
formatCurrencyValue,
|
||||
} from 'utils/numbers'
|
||||
import { withValueLimit } from './MarketSwapForm'
|
||||
import ReduceInputTokenInput from './ReduceInputTokenInput'
|
||||
import ReduceOutputTokenInput from './ReduceOutputTokenInput'
|
||||
|
@ -48,6 +52,11 @@ import { SwapFormTokenListType } from './SwapFormTokenList'
|
|||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const priceToDisplayString = (price: number | Decimal | string): string => {
|
||||
const val = floorToDecimalSignificance(price, 6)
|
||||
return val.toFixed(val.dp())
|
||||
}
|
||||
|
||||
type LimitSwapFormProps = {
|
||||
showTokenSelect: SwapFormTokenListType
|
||||
setShowTokenSelect: Dispatch<SetStateAction<SwapFormTokenListType>>
|
||||
|
@ -82,10 +91,6 @@ const getSellTokenBalance = (inputBank: Bank | undefined) => {
|
|||
return balance
|
||||
}
|
||||
|
||||
const isReducingShort = (inputBank: Bank | undefined) => {
|
||||
return getSellTokenBalance(inputBank) < 0
|
||||
}
|
||||
|
||||
const getOrderTypeMultiplier = (
|
||||
orderType: OrderTypes,
|
||||
flipPrices: boolean,
|
||||
|
@ -183,50 +188,36 @@ const LimitSwapForm = ({
|
|||
|
||||
const quotePrice = useMemo(() => {
|
||||
if (!inputBank || !outputBank) return 0
|
||||
const quote = flipPrices
|
||||
? floorToDecimal(
|
||||
outputBank.uiPrice / inputBank.uiPrice,
|
||||
inputBank.mintDecimals,
|
||||
).toNumber()
|
||||
: floorToDecimal(
|
||||
inputBank.uiPrice / outputBank.uiPrice,
|
||||
outputBank.mintDecimals,
|
||||
).toNumber()
|
||||
return quote
|
||||
return flipPrices
|
||||
? outputBank.uiPrice / inputBank.uiPrice
|
||||
: inputBank.uiPrice / outputBank.uiPrice
|
||||
}, [flipPrices, inputBank, outputBank])
|
||||
|
||||
const isReducingShort = useMemo(() => {
|
||||
if (!mangoAccount || !inputBank) return false
|
||||
return mangoAccount.getTokenBalanceUi(inputBank) < 0
|
||||
}, [inputBank])
|
||||
|
||||
// set default trigger price
|
||||
useEffect(() => {
|
||||
if (!quotePrice || triggerPrice || showTokenSelect) return
|
||||
const reducingShort = isReducingShort(inputBank)
|
||||
const multiplier = getOrderTypeMultiplier(
|
||||
OrderTypes.STOP_LOSS,
|
||||
flipPrices,
|
||||
reducingShort,
|
||||
isReducingShort,
|
||||
)
|
||||
const decimals = !flipPrices ? inputBankDecimals : outputBankDecimals
|
||||
setTriggerPrice((quotePrice * multiplier).toFixed(decimals))
|
||||
}, [
|
||||
flipPrices,
|
||||
inputBankDecimals,
|
||||
outputBankDecimals,
|
||||
quotePrice,
|
||||
showTokenSelect,
|
||||
triggerPrice,
|
||||
inputBank,
|
||||
])
|
||||
setTriggerPrice(priceToDisplayString(quotePrice * multiplier))
|
||||
}, [flipPrices, quotePrice, showTokenSelect, triggerPrice, isReducingShort])
|
||||
|
||||
// flip trigger price and set amount out when chart direction is flipped
|
||||
useLayoutEffect(() => {
|
||||
if (!quotePrice) return
|
||||
const reducingShort = isReducingShort(inputBank)
|
||||
const multiplier = getOrderTypeMultiplier(
|
||||
orderType,
|
||||
flipPrices,
|
||||
reducingShort,
|
||||
isReducingShort,
|
||||
)
|
||||
const decimals = flipPrices ? inputBankDecimals : outputBankDecimals
|
||||
const price = (quotePrice * multiplier).toFixed(decimals)
|
||||
const price = priceToDisplayString(quotePrice * multiplier)
|
||||
setTriggerPrice(price)
|
||||
if (amountInAsDecimal?.gt(0)) {
|
||||
const amountOut = getAmountOut(
|
||||
|
@ -236,7 +227,7 @@ const LimitSwapForm = ({
|
|||
)
|
||||
setAmountOutFormValue(amountOut.toString())
|
||||
}
|
||||
}, [flipPrices, inputBankDecimals, orderType, outputBankDecimals, inputBank])
|
||||
}, [flipPrices, orderType, isReducingShort])
|
||||
|
||||
const triggerPriceDifference = useMemo(() => {
|
||||
if (!quotePrice) return 0
|
||||
|
@ -253,18 +244,21 @@ const LimitSwapForm = ({
|
|||
}
|
||||
|
||||
const hasBorrowToRepay = useMemo(() => {
|
||||
if (
|
||||
// orderType !== OrderTypes.REPAY_BORROW ||
|
||||
!outputBank ||
|
||||
!mangoAccount
|
||||
)
|
||||
return
|
||||
const balance = mangoAccount.getTokenBalanceUi(outputBank)
|
||||
const roundedBalance = floorToDecimal(
|
||||
balance,
|
||||
outputBank.mintDecimals,
|
||||
).toNumber()
|
||||
return balance && balance < 0 ? Math.abs(roundedBalance) : 0
|
||||
// if (
|
||||
// // orderType !== OrderTypes.REPAY_BORROW ||
|
||||
// !outputBank ||
|
||||
// !mangoAccount
|
||||
// )
|
||||
// return
|
||||
// const balance = mangoAccount.getTokenBalanceUi(outputBank)
|
||||
// const roundedBalance = floorToDecimal(
|
||||
// balance,
|
||||
// outputBank.mintDecimals,
|
||||
// ).toNumber()
|
||||
// return balance && balance < 0 ? Math.abs(roundedBalance) : 0
|
||||
|
||||
// TODO: not sure if this concept is still needed
|
||||
return 0
|
||||
}, [mangoAccount, orderType, outputBank])
|
||||
|
||||
// check if the borrowed amount exceeds the net borrow limit in the current period
|
||||
|
@ -511,8 +505,7 @@ const LimitSwapForm = ({
|
|||
|
||||
const amountIn = amountInAsDecimal.toNumber()
|
||||
|
||||
const isReduceLong =
|
||||
mangoAccount.getTokenBalanceUi(inputBank) > 0 ? true : false
|
||||
const isReduceLong = !isReducingShort
|
||||
|
||||
try {
|
||||
let tx
|
||||
|
@ -636,6 +629,7 @@ const LimitSwapForm = ({
|
|||
triggerPrice,
|
||||
amountInAsDecimal,
|
||||
amountOutFormValue,
|
||||
isReducingShort,
|
||||
])
|
||||
|
||||
const orderDescription = useMemo(() => {
|
||||
|
@ -665,7 +659,7 @@ const LimitSwapForm = ({
|
|||
amount: amountOut,
|
||||
priceUnit: quoteString,
|
||||
symbol: outputBankName,
|
||||
triggerPrice: floorToDecimal(triggerPrice, inputBankDecimals),
|
||||
triggerPrice: priceToDisplayString(triggerPrice),
|
||||
})
|
||||
} else {
|
||||
const depositAmount = floorToDecimal(
|
||||
|
@ -677,10 +671,12 @@ const LimitSwapForm = ({
|
|||
depositAmount: depositAmount,
|
||||
priceUnit: quoteString,
|
||||
symbol: outputBankName,
|
||||
triggerPrice: floorToDecimal(triggerPrice, inputBankDecimals),
|
||||
triggerPrice: priceToDisplayString(triggerPrice),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const action = isReducingShort ? t('trade:buying') : t('trade:selling')
|
||||
|
||||
const orderTypeString =
|
||||
orderType === OrderTypes.STOP_LOSS
|
||||
? !flipPrices
|
||||
|
@ -691,11 +687,12 @@ const LimitSwapForm = ({
|
|||
: t('trade:falls-to')
|
||||
|
||||
return t('trade:trigger-order-desc', {
|
||||
action: action,
|
||||
amount: floorToDecimal(amountInFormValue, inputBankDecimals),
|
||||
orderType: orderTypeString,
|
||||
priceUnit: quoteString,
|
||||
symbol: inputBankName,
|
||||
triggerPrice: floorToDecimal(triggerPrice, inputBankDecimals),
|
||||
triggerPrice: priceToDisplayString(triggerPrice),
|
||||
})
|
||||
}
|
||||
}, [
|
||||
|
@ -709,6 +706,7 @@ const LimitSwapForm = ({
|
|||
outputBankDecimals,
|
||||
outputBankName,
|
||||
triggerPrice,
|
||||
isReducingShort,
|
||||
])
|
||||
|
||||
const triggerPriceSuffix = useMemo(() => {
|
||||
|
@ -736,13 +734,14 @@ const LimitSwapForm = ({
|
|||
setFormErrors({})
|
||||
const newType = type as OrderTypes
|
||||
setOrderType(newType)
|
||||
const reducingShort = isReducingShort(inputBank)
|
||||
const triggerMultiplier = getOrderTypeMultiplier(
|
||||
newType,
|
||||
flipPrices,
|
||||
reducingShort,
|
||||
isReducingShort,
|
||||
)
|
||||
const trigger = (quotePrice * triggerMultiplier).toString()
|
||||
const trigger = priceToDisplayString(
|
||||
quotePrice * triggerMultiplier,
|
||||
).toString()
|
||||
setTriggerPrice(trigger)
|
||||
if (amountInAsDecimal.gt(0)) {
|
||||
const amountOut = getAmountOut(
|
||||
|
@ -753,7 +752,7 @@ const LimitSwapForm = ({
|
|||
setAmountOutFormValue(amountOut)
|
||||
}
|
||||
},
|
||||
[flipPrices, quotePrice, setFormErrors, inputBank],
|
||||
[flipPrices, quotePrice, setFormErrors, isReducingShort],
|
||||
)
|
||||
|
||||
const onClick = !connected
|
||||
|
@ -832,9 +831,6 @@ const LimitSwapForm = ({
|
|||
thousandSeparator=","
|
||||
allowNegative={false}
|
||||
isNumericString={true}
|
||||
decimalScale={
|
||||
flipPrices ? inputBankDecimals : outputBankDecimals || 6
|
||||
}
|
||||
name="triggerPrice"
|
||||
id="triggerPrice"
|
||||
className="h-10 w-full rounded-lg bg-th-input-bkg p-3 pl-8 font-mono text-sm text-th-fgd-1 focus:outline-none md:hover:bg-th-bkg-1"
|
||||
|
@ -884,7 +880,8 @@ const LimitSwapForm = ({
|
|||
/>
|
||||
{
|
||||
// orderType === OrderTypes.REPAY_BORROW &&
|
||||
!hasBorrowToRepay ? null : orderDescription ? (
|
||||
//!hasBorrowToRepay ? null : orderDescription ? (
|
||||
orderDescription ? (
|
||||
<div className="mt-4">
|
||||
<InlineNotification
|
||||
desc={
|
||||
|
|
|
@ -114,11 +114,11 @@
|
|||
"trades": "Trades",
|
||||
"trigger-price": "Trigger Price",
|
||||
"trigger-order": "Trigger Order",
|
||||
"trigger-order-desc": "{{amount}} {{symbol}} if the oracle price {{orderType}} {{triggerPrice}} {{priceUnit}}",
|
||||
"trigger-order-desc": "{{action}} {{amount}} {{symbol}} if the oracle price {{orderType}} {{triggerPrice}} {{priceUnit}}",
|
||||
"trigger-orders": "Trigger Orders",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,10 +97,29 @@ export const floorToDecimal = (
|
|||
decimals: number,
|
||||
): Decimal => {
|
||||
const decimal = value instanceof Decimal ? value : new Decimal(value)
|
||||
|
||||
return decimal.toDecimalPlaces(decimals, Decimal.ROUND_FLOOR)
|
||||
}
|
||||
|
||||
// Significant digits before the dot count against the number of decimals
|
||||
// to show. When maxSignificantDecimals is 2:
|
||||
// 0.012345 -> 0.012
|
||||
// 0.12345 -> 0.12
|
||||
// 1.12345 -> 1.1
|
||||
// 12.345 -> 12.3
|
||||
// 123.456 -> 123
|
||||
// 1234.567 -> 1234
|
||||
export const floorToDecimalSignificance = (
|
||||
value: number | string | Decimal,
|
||||
maxSignificantDecimals: number,
|
||||
): Decimal => {
|
||||
const number = Number(value)
|
||||
const log = Math.log10(Math.abs(number))
|
||||
const decimal = new Decimal(value)
|
||||
return decimal.toDecimalPlaces(
|
||||
Math.max(0, Math.floor(-log + maxSignificantDecimals - Number.EPSILON)),
|
||||
)
|
||||
}
|
||||
|
||||
const usdFormatter0 = Intl.NumberFormat('en', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
|
|
Loading…
Reference in New Issue