From 5e879c1c6936cd2a551c306ecf16c62276bafc23 Mon Sep 17 00:00:00 2001
From: tjs
Date: Fri, 2 Sep 2022 19:52:07 -0400
Subject: [PATCH] prevent leverage slider from converting swap input to string
use Decimal in more places
---
components/swap/JupiterRouteInfo.tsx | 10 +++-----
components/swap/LeverageSlider.tsx | 5 ++--
components/swap/SwapForm.tsx | 26 +++++++++----------
components/swap/useJupiter.ts | 9 +++----
components/swap/useTokenMax.tsx | 38 +++++++++++++++-------------
package.json | 2 +-
yarn.lock | 14 +++++-----
7 files changed, 53 insertions(+), 51 deletions(-)
diff --git a/components/swap/JupiterRouteInfo.tsx b/components/swap/JupiterRouteInfo.tsx
index fc735809..546b3ecb 100644
--- a/components/swap/JupiterRouteInfo.tsx
+++ b/components/swap/JupiterRouteInfo.tsx
@@ -93,9 +93,8 @@ const JupiterRouteInfo = ({
const amountOut = useMemo(() => {
if (!selectedRoute || !outputTokenInfo) return
- return toUiDecimals(
- JSBI.toNumber(selectedRoute.outAmount),
- outputTokenInfo.decimals
+ return new Decimal(selectedRoute.outAmount.toString()).div(
+ 10 ** outputTokenInfo.decimals
)
}, [selectedRoute, outputTokenInfo])
@@ -256,14 +255,13 @@ const JupiterRouteInfo = ({
{swapRate ? (
<>
1 {inputTokenInfo!.name} ≈{' '}
- {formatDecimal(amountOut / amountIn.toNumber(), 6)}{' '}
+ {amountOut.div(amountIn).toFixed()}{' '}
{outputTokenInfo?.symbol}
>
) : (
<>
1 {outputTokenInfo?.symbol} ≈{' '}
- {formatDecimal(amountIn.toNumber() / amountOut, 6)}{' '}
- {inputTokenInfo!.name}
+ {amountIn.div(amountOut).toFixed()} {inputTokenInfo!.name}
>
)}
diff --git a/components/swap/LeverageSlider.tsx b/components/swap/LeverageSlider.tsx
index 51b8b47b..e0ca5397 100644
--- a/components/swap/LeverageSlider.tsx
+++ b/components/swap/LeverageSlider.tsx
@@ -1,3 +1,4 @@
+import Decimal from 'decimal.js'
import { ChangeEvent, useEffect, useRef, useState } from 'react'
import mangoStore from '../../store/mangoStore'
import { useTokenMax } from './useTokenMax'
@@ -30,7 +31,7 @@ const LeverageSlider = ({
useEffect(() => {
if (amount) {
- onChange(amount.toString())
+ onChange(new Decimal(amount).toFixed())
setValue(amount)
}
}, [amount])
@@ -82,7 +83,7 @@ export const SwapLeverageSlider = ({
) : (
)}
diff --git a/components/swap/SwapForm.tsx b/components/swap/SwapForm.tsx
index 849f56d6..676ecb36 100644
--- a/components/swap/SwapForm.tsx
+++ b/components/swap/SwapForm.tsx
@@ -82,7 +82,7 @@ const SwapForm = () => {
}, [routes])
useEffect(() => {
- setAmountInFormValue('0')
+ setAmountInFormValue('')
}, [useMargin])
const handleAmountInChange = useCallback((e: NumberFormatValues) => {
@@ -168,7 +168,7 @@ const SwapForm = () => {
},
{
mintPk: new PublicKey(outputTokenInfo.address),
- uiTokenAmount: amountOut,
+ uiTokenAmount: amountOut.toNumber(),
},
],
HealthType.maint
@@ -188,9 +188,9 @@ const SwapForm = () => {
const showHealthImpact = !!inputTokenInfo && !!outputTokenInfo && !!amountOut
- const showInsufficientBalance =
- (!useMargin && amountIn.toNumber() > tokenMax) ||
- (useMargin && amountIn.toNumber() > amountWithBorrow)
+ const showInsufficientBalance = useMargin
+ ? amountWithBorrow.lt(amountIn)
+ : tokenMax.lt(amountIn)
return (
@@ -321,7 +321,7 @@ const SwapForm = () => {
) : (
- {amountOut ? numberFormat.format(amountOut) : ''}
+ {amountOut ? numberFormat.format(amountOut.toNumber()) : ''}
)}
@@ -419,9 +419,9 @@ const MaxSwapAmount = ({
useMargin,
decimals,
}: {
- amountWithBorrow: number
+ amountWithBorrow: Decimal
setAmountIn: (x: string) => void
- tokenMax: number
+ tokenMax: Decimal
useMargin: boolean
decimals: number
}) => {
@@ -441,7 +441,7 @@ const MaxSwapAmount = ({
{t('max')}:
- {maxAmount < 1 ? maxAmount.toFixed(decimals) : maxAmount}
+ {maxAmount.toFixed()}
)
@@ -456,20 +456,20 @@ const PercentageSelectButtons = ({
amountIn: string
decimals: number
setAmountIn: (x: string) => any
- tokenMax: number
+ tokenMax: Decimal
}) => {
const [sizePercentage, setSizePercentage] = useState('')
useEffect(() => {
- if (tokenMax > 0 && Number(amountIn) === tokenMax) {
+ if (tokenMax.gt(0) && tokenMax.eq(amountIn)) {
setSizePercentage('100')
}
}, [amountIn, tokenMax])
const handleSizePercentage = (percentage: string) => {
setSizePercentage(percentage)
- if (tokenMax > 0) {
- let amount = new Decimal(tokenMax).mul(percentage).div(100)
+ if (tokenMax.gt(0)) {
+ let amount = tokenMax.mul(percentage).div(100)
if (percentage !== '100') {
amount = floorToDecimal(amount, decimals)
}
diff --git a/components/swap/useJupiter.ts b/components/swap/useJupiter.ts
index cd499c56..60bdf04e 100644
--- a/components/swap/useJupiter.ts
+++ b/components/swap/useJupiter.ts
@@ -17,12 +17,12 @@ type useJupiterPropTypes = {
type RouteParams = {
routes: RouteInfo[]
- amountOut: number
+ amountOut: Decimal
}
const defaultComputedInfo = {
routes: [],
- amountOut: 0,
+ amountOut: new Decimal(0),
}
const useJupiter = ({
@@ -96,9 +96,8 @@ const useJupiter = ({
setComputedInfo({
routes: routesInfosWithoutRaydium,
- amountOut: toUiDecimals(
- JSBI.toNumber(bestRoute.outAmount),
- outputTokenInfo.decimals!
+ amountOut: new Decimal(bestRoute.outAmount.toString()).div(
+ 10 ** outputTokenInfo.decimals!
),
})
}
diff --git a/components/swap/useTokenMax.tsx b/components/swap/useTokenMax.tsx
index 6f111e26..7dac0040 100644
--- a/components/swap/useTokenMax.tsx
+++ b/components/swap/useTokenMax.tsx
@@ -2,7 +2,8 @@ import { Bank, Group, MangoAccount } from '@blockworks-foundation/mango-v4'
import Decimal from 'decimal.js'
import { useMemo } from 'react'
import mangoStore from '../../store/mangoStore'
-import { floorToDecimal, formatDecimal } from '../../utils/numbers'
+import { floorToDecimal } from '../../utils/numbers'
+import useMangoAccount from '../shared/useMangoAccount'
export const getMaxWithdrawForBank = (
group: Group,
@@ -22,49 +23,52 @@ export const getMaxWithdrawForBank = (
}
export const useTokenMax = (useMargin = true) => {
- const mangoAccount = mangoStore((s) => s.mangoAccount.current)
+ const { mangoAccount } = useMangoAccount()
const inputBank = mangoStore((s) => s.swap.inputBank)
const outputBank = mangoStore((s) => s.swap.outputBank)
- const slippage = mangoStore((s) => s.swap.slippage)
const tokenInMax = useMemo(() => {
const group = mangoStore.getState().group
if (!group || !inputBank || !mangoAccount || !outputBank)
- return { amount: 0.0, decimals: 6, amountWithBorrow: 0.0 }
+ return {
+ amount: new Decimal(0.0),
+ decimals: 6,
+ amountWithBorrow: new Decimal(0.0),
+ }
const inputBankFromGroup = group.getFirstBankByMint(inputBank.mint)
- const tokenBalance = parseFloat(
- formatDecimal(
- mangoAccount?.getTokenBalanceUi(inputBankFromGroup),
- inputBankFromGroup.mintDecimals
- )
+ const tokenBalance = floorToDecimal(
+ mangoAccount?.getTokenBalanceUi(inputBankFromGroup),
+ inputBankFromGroup.mintDecimals
)
const inputBankVaultBalance = group.getTokenVaultBalanceByMintUi(
inputBank.mint
)
- const maxAmountWithoutMargin = tokenBalance > 0 ? tokenBalance : 0
+ const maxAmountWithoutMargin = tokenBalance.gt(0)
+ ? tokenBalance
+ : new Decimal(0)
const maxUiAmountWithBorrow = floorToDecimal(
mangoAccount?.getMaxSourceUiForTokenSwap(
group,
inputBank.mint,
outputBank.mint,
- 0.98 - slippage / 10
+ 1
)!,
inputBank.mintDecimals
)
const maxAmount = useMargin
- ? Math.min(
+ ? Decimal.min(
maxAmountWithoutMargin,
inputBankVaultBalance,
- maxUiAmountWithBorrow!.toNumber()
+ maxUiAmountWithBorrow!
)
- : Math.min(maxAmountWithoutMargin, inputBankVaultBalance)
+ : Decimal.min(maxAmountWithoutMargin, inputBankVaultBalance)
- const maxAmountWithBorrow = Math.min(
- maxUiAmountWithBorrow!.toNumber(),
+ const maxAmountWithBorrow = Decimal.min(
+ maxUiAmountWithBorrow!,
inputBankVaultBalance
)
@@ -73,7 +77,7 @@ export const useTokenMax = (useMargin = true) => {
amountWithBorrow: maxAmountWithBorrow,
decimals: inputBank.mintDecimals,
}
- }, [inputBank, mangoAccount, outputBank, slippage, useMargin])
+ }, [inputBank, mangoAccount, outputBank, useMargin])
return tokenInMax
}
diff --git a/package.json b/package.json
index f17e53e6..af43f9c4 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
"react": "18.0.0",
"react-dom": "18.0.0",
"react-flip-numbers": "^3.0.5",
- "react-number-format": "4.5.4",
+ "react-number-format": "^4.9.2",
"react-window": "^1.8.7",
"recharts": "^2.1.12",
"zustand": "^4.1.1"
diff --git a/yarn.lock b/yarn.lock
index 2b485925..0e32350f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1014,9 +1014,9 @@
tweetnacl "^1.0.0"
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.3":
- version "1.56.0"
- resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.56.0.tgz#312bccde0ddeeffa7a48af16a945cc4d1f863395"
- integrity sha512-YfQAIvsllVP3Y5QSs/TdJJFwTgFQuXybg+ouwyNE8cmq3+r2Nmvsj69DGWGbN41jy0is8foZf0yruuLQfWxOmQ==
+ version "1.56.2"
+ resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.56.2.tgz#5212e8b147ebc216ea5a7aa99d5b555ebe41f9bd"
+ integrity sha512-ByWfNA8H/1EB4g0749uhkQ0zZZAQealzRmmT3UMIv3xe0DeHwnrzQUavBtAlHNMrKqLHu8kd+XtPci6zreMjjA==
dependencies:
"@babel/runtime" "^7.12.5"
"@noble/ed25519" "^1.7.0"
@@ -4318,10 +4318,10 @@ react-native-url-polyfill@^1.3.0:
dependencies:
whatwg-url-without-unicode "8.0.0-3"
-react-number-format@4.5.4:
- version "4.5.4"
- resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-4.5.4.tgz#b644d79a90fcad2f1009eb0b9a14eb0ddd6c0083"
- integrity sha512-DZm4YhJ7B+bbOA+Jgn/ckA9DPcKxrJWHXir4nA1YIeqKZ15XYa/uVLwZohlEcGUKqqx6ZeXppOU4eZczBenHOg==
+react-number-format@^4.9.2:
+ version "4.9.3"
+ resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-4.9.3.tgz#338500fe9c61b1ac73c8d6dff4ec97dd13fd2b50"
+ integrity sha512-am1A1xYAbENuKJ+zpM7V+B1oRTSeOHYltqVKExznIVFweBzhLmOBmyb1DfIKjHo90E0bo1p3nzVJ2NgS5xh+sQ==
dependencies:
prop-types "^15.7.2"