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"