From d335fba468adf7d21eb54d3d25e1edc2ede00f23 Mon Sep 17 00:00:00 2001 From: Septs Date: Thu, 9 Dec 2021 12:46:27 +0800 Subject: [PATCH 1/6] refactor: improve big number practice --- packages/dashboard/package.json | 1 + .../components/FungibleTokenTable/index.tsx | 2 +- .../FungibleTokenTableRow/index.tsx | 3 +- .../components/Transfer/TransferERC20.tsx | 9 ++- .../components/Transfer/TransferERC721.tsx | 4 +- packages/mask/package.json | 1 + .../mask/src/components/shared/TokenPrice.tsx | 5 +- .../Wallet/ContractInteraction/index.tsx | 10 ++-- .../Wallet/GasSetting/GasSetting1559.tsx | 31 +++++----- .../pages/Wallet/ReplaceTransaction/index.tsx | 9 +-- .../Wallet/Transfer/Prior1559Transfer.tsx | 17 +++--- .../pages/Wallet/Transfer/Transfer1559.tsx | 56 +++++++++---------- .../SNSAdaptor/ListingByHighestBidCard.tsx | 8 +-- .../SNSAdaptor/ListingByPriceCard.tsx | 11 ++-- .../Collectible/SNSAdaptor/ListingTab.tsx | 3 +- .../SNSAdaptor/MakeOfferDialog.tsx | 5 +- .../Collectible/SNSAdaptor/OfferTab.tsx | 2 +- .../Collectible/SNSAdaptor/OrderRow.tsx | 3 +- .../mask/src/plugins/Collectible/helpers.ts | 16 ++---- .../src/plugins/Collectible/hooks/useAsset.ts | 5 +- .../mask/src/plugins/Collectible/utils.ts | 3 +- .../Gitcoin/SNSAdaptor/DonateDialog.tsx | 4 +- .../GoodGhosting/UI/GameActionDialog.tsx | 6 +- .../mask/src/plugins/GoodGhosting/utils.ts | 5 +- .../plugins/ITO/SNSAdaptor/ConfirmDialog.tsx | 2 +- .../src/plugins/ITO/SNSAdaptor/CreateForm.tsx | 3 +- .../mask/src/plugins/ITO/SNSAdaptor/ITO.tsx | 4 +- .../src/plugins/ITO/SNSAdaptor/PoolInList.tsx | 2 +- .../plugins/ITO/SNSAdaptor/ShareDialog.tsx | 3 +- .../src/plugins/ITO/SNSAdaptor/SwapDialog.tsx | 13 ++--- .../src/plugins/ITO/SNSAdaptor/SwapGuide.tsx | 10 +--- .../plugins/ITO/SNSAdaptor/UnlockDialog.tsx | 5 +- .../plugins/ITO/SNSAdaptor/hooks/useFill.ts | 3 +- .../ITO/SNSAdaptor/hooks/useSwapCallback.ts | 4 +- .../SNSAdaptor/components/DrawDialog.tsx | 6 +- .../src/plugins/MaskBox/hooks/useContext.ts | 10 ++-- .../MaskBox/hooks/useOpenBoxTransaction.ts | 4 +- .../plugins/PoolTogether/UI/DepositDialog.tsx | 5 +- .../SNSAdaptor/RedPacketERC20Form.tsx | 10 +--- .../SNSAdaptor/hooks/useCreateCallback.tsx | 2 +- .../SNSAdaptor/trader/ConfirmDialog.tsx | 3 +- .../SNSAdaptor/trader/Gas1559Settings.tsx | 24 ++++---- .../Trader/SNSAdaptor/trader/TradeForm.tsx | 5 +- .../Trader/SNSAdaptor/trader/Trader.tsx | 8 +-- .../Trader/SNSAdaptor/trader/TraderInfo.tsx | 5 +- .../src/plugins/Trader/apis/balancer/index.ts | 3 +- .../apis/bancor/calculateMinimumReturn.ts | 7 ++- .../Trader/apis/coinmarketcap/index.ts | 6 +- .../src/plugins/Trader/apis/dodo/index.ts | 4 +- .../src/plugins/Trader/apis/uniswap/index.ts | 6 +- .../src/plugins/Trader/constants/trader.ts | 3 +- .../src/plugins/Trader/helpers/uniswap.ts | 3 +- .../Trader/trader/0x/useTradeComputed.ts | 3 +- .../Trader/trader/balancer/useTradeAmount.ts | 2 +- .../trader/balancer/useTradeComputed.ts | 3 +- .../plugins/Trader/trader/bancor/useTrade.ts | 6 +- .../Trader/trader/bancor/useTradeComputed.ts | 9 ++- .../Trader/trader/dodo/useTradeComputed.ts | 6 +- .../Trader/trader/native/useTradeComputed.ts | 3 +- .../plugins/Trader/trader/uniswap/useTrade.ts | 3 +- .../Trader/trader/uniswap/useTradeComputed.ts | 3 +- .../Trader/trader/useAllTradeComputed.ts | 7 ++- .../Trader/trader/useTradeApproveComputed.ts | 3 +- .../GasSettingDialog/GasSetting1559.tsx | 35 ++++++------ .../GasSettingDialog/GasSettingBar.tsx | 4 +- .../TransactionDescription.tsx | 13 +++-- .../src/plugins/Wallet/services/assets.ts | 9 +-- .../plugins/Wallet/services/transactions.ts | 8 +-- .../src/plugins/dHEDGE/UI/InvestDialog.tsx | 5 +- packages/mask/src/plugins/dHEDGE/utils.ts | 2 +- .../UI/EthereumWalletConnectedBoundary.tsx | 3 +- .../Flow/src/apis/getFungibleAssets.ts | 7 +-- packages/plugins/Flow/src/helpers/token.ts | 8 +-- packages/web3-shared/base/utils/number.ts | 50 ++++++++++++++++- .../evm/hooks/useERC20TokenApproveCallback.ts | 2 +- .../hooks/useERC20TokenTransferCallback.ts | 2 +- .../hooks/useNativeTokenTransferCallback.ts | 2 +- .../hooks/useNativeTokenWrapperCallback.ts | 2 +- packages/web3-shared/evm/package.json | 1 + packages/web3-shared/evm/utils/formatter.ts | 13 ++--- packages/web3-shared/evm/utils/index.ts | 1 - packages/web3-shared/evm/utils/number.ts | 24 -------- pnpm-lock.yaml | 6 ++ 83 files changed, 321 insertions(+), 306 deletions(-) delete mode 100644 packages/web3-shared/evm/utils/number.ts diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 6ff6c2e6d2c1..38ac87e088c0 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -22,6 +22,7 @@ "@masknet/shared-base": "workspace:*", "@masknet/storybook-shared": "workspace:*", "@masknet/theme": "workspace:*", + "@masknet/web3-shared-base": "workspace:*", "@masknet/web3-shared-evm": "workspace:*", "@msgpack/msgpack": "^2.7.1", "@servie/events": "^3.0.0", diff --git a/packages/dashboard/src/pages/Wallets/components/FungibleTokenTable/index.tsx b/packages/dashboard/src/pages/Wallets/components/FungibleTokenTable/index.tsx index 55bd58f465c1..f46991878f64 100644 --- a/packages/dashboard/src/pages/Wallets/components/FungibleTokenTable/index.tsx +++ b/packages/dashboard/src/pages/Wallets/components/FungibleTokenTable/index.tsx @@ -178,7 +178,7 @@ export const TokenTableUI = memo(({ onSwap, onSend, isLoading Utils?.formatBalance?.(second.balance, second.token.decimals) ?? '', ) - if (firstValue.eq(secondValue)) return 0 + if (firstValue.isEqualTo(secondValue)) return 0 return Number(firstValue.lt(secondValue)) }) diff --git a/packages/dashboard/src/pages/Wallets/components/FungibleTokenTableRow/index.tsx b/packages/dashboard/src/pages/Wallets/components/FungibleTokenTableRow/index.tsx index 1a8196221d31..6f4b8406a407 100644 --- a/packages/dashboard/src/pages/Wallets/components/FungibleTokenTableRow/index.tsx +++ b/packages/dashboard/src/pages/Wallets/components/FungibleTokenTableRow/index.tsx @@ -15,6 +15,7 @@ import { import { useDashboardI18N } from '../../../../locales' import { ChangeNetworkTip } from './ChangeNetworkTip' import { getTokenUSDValue } from '../../utils/getTokenUSDValue' +import { pow10 } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ icon: { @@ -111,7 +112,7 @@ export const FungibleTokenTableRow = memo(({ asset, onSend, {asset.price?.[CurrencyType.USD] - ? new BigNumber(asset.price[CurrencyType.USD] ?? '').gt(new BigNumber(10).pow(-6)) + ? new BigNumber(asset.price[CurrencyType.USD] ?? '').gt(pow10(-6)) ? Utils?.formatCurrency?.(Number.parseFloat(asset.price[CurrencyType.USD] ?? ''), '$') : '<0.000001' : '-'} diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx index 917d06912882..c6f43901004e 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx @@ -6,8 +6,6 @@ import { formatWeiToEther, FungibleTokenDetailed, isEIP1559Supported, - isGreaterThan, - isZero, TransactionStateType, useChainId, useFungibleTokenBalance, @@ -16,6 +14,7 @@ import { useNativeTokenDetailed, useTokenTransferCallback, } from '@masknet/web3-shared-evm' +import { isGreaterThan, isZero, leftShift, multipliedBy } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { NetworkPluginID, useLookupAddress, useNetworkDescriptor, useWeb3State } from '@masknet/plugin-infra' import { FormattedAddress, TokenAmountPanel } from '@masknet/shared' @@ -75,7 +74,7 @@ export const TransferERC20 = memo(({ token }) => { //#endregion // transfer amount - const transferAmount = new BigNumber(amount || '0').shiftedBy(selectedToken.decimals).toFixed() + const transferAmount = leftShift(amount || '0', selectedToken.decimals).toFixed() const erc20GasLimit = useGasLimit( selectedToken.type, selectedToken.address, @@ -91,7 +90,7 @@ export const TransferERC20 = memo(({ token }) => { const gasFee = useMemo(() => { const price = is1559Supported && maxFee ? new BigNumber(maxFee) : gasPrice - return new BigNumber(gasLimit).multipliedBy(price) + return multipliedBy(gasLimit, price) }, [gasLimit, gasPrice, maxFee, is1559Supported]) const gasFeeInUsd = formatWeiToEther(gasFee).multipliedBy(nativeTokenPrice) @@ -120,7 +119,7 @@ export const TransferERC20 = memo(({ token }) => { //#region validation const validationMessage = useMemo(() => { if (!transferAmount || isZero(transferAmount)) return t.wallets_transfer_error_amount_absence() - if (isGreaterThan(new BigNumber(amount).shiftedBy(selectedToken.decimals).toFixed(), maxAmount)) + if (isGreaterThan(leftShift(amount, selectedToken.decimals).toFixed(), maxAmount)) return t.wallets_transfer_error_insufficient_balance({ symbol: selectedToken.symbol ?? '' }) if (!address) return t.wallets_transfer_error_address_absence() if (!EthereumAddress.isValid(address)) return t.wallets_transfer_error_invalid_address() diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC721.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC721.tsx index 6b76168c8489..158ed10ae92c 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC721.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC721.tsx @@ -28,7 +28,6 @@ import { Controller, useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import TuneIcon from '@mui/icons-material/Tune' -import BigNumber from 'bignumber.js' import { useNativeTokenPrice } from './useNativeTokenPrice' import { useNavigate } from 'react-router' import { RoutePaths } from '../../../../type' @@ -39,6 +38,7 @@ import { TransferTab } from './types' import { NetworkPluginID, useLookupAddress, useNetworkDescriptor, useWeb3State } from '@masknet/plugin-infra' import { NetworkType } from '@masknet/public-api' import { useUpdateEffect } from 'react-use' +import { multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ disabled: { @@ -144,7 +144,7 @@ export const TransferERC721 = memo(() => { // gas price const { value: defaultGasPrice = '0' } = useGasPrice() const gasPrice = gasConfig.gasPrice || defaultGasPrice - const gasFee = useMemo(() => new BigNumber(gasLimit).multipliedBy(gasPrice), [gasLimit, gasPrice]) + const gasFee = useMemo(() => multipliedBy(gasLimit, gasPrice), [gasLimit, gasPrice]) const gasFeeInUsd = formatWeiToEther(gasFee).multipliedBy(nativeTokenPrice) // dialog diff --git a/packages/mask/package.json b/packages/mask/package.json index c849fa249621..2adc6f150887 100644 --- a/packages/mask/package.json +++ b/packages/mask/package.json @@ -31,6 +31,7 @@ "@masknet/shared-base": "workspace:*", "@masknet/theme": "workspace:*", "@masknet/web3-contracts": "workspace:*", + "@masknet/web3-shared-base": "workspace:*", "@masknet/web3-shared-evm": "workspace:*", "@msgpack/msgpack": "^2.7.1", "@servie/events": "^3.0.0", diff --git a/packages/mask/src/components/shared/TokenPrice.tsx b/packages/mask/src/components/shared/TokenPrice.tsx index a85a7a31296e..4fb43cca6b78 100644 --- a/packages/mask/src/components/shared/TokenPrice.tsx +++ b/packages/mask/src/components/shared/TokenPrice.tsx @@ -1,7 +1,8 @@ import type { FC, HTMLProps } from 'react' -import BigNumber from 'bignumber.js' +import type BigNumber from 'bignumber.js' import { ChainId, CurrencyType, isSameAddress, ZERO_ADDRESS } from '@masknet/web3-shared-evm' import { useNativeTokenPrice, useTokenPrice } from '../../plugins/Wallet/hooks/useTokenPrice' +import { multipliedBy } from '@masknet/web3-shared-base' interface TokenPriceProps extends Omit, 'children'> { chainId: ChainId @@ -20,5 +21,5 @@ export const TokenPrice: FC = ({ const tokenPrice = useTokenPrice(chainId, contractAddress?.toLowerCase(), currencyType) const nativeTokenPrice = useNativeTokenPrice(chainId) const price = isSameAddress(contractAddress, ZERO_ADDRESS) ? nativeTokenPrice : tokenPrice - return ${new BigNumber(amount).multipliedBy(price).toFixed(2)} + return ${multipliedBy(amount, price).toFixed(2)} } diff --git a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx index 14b8d85c2c57..d5534aadf222 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx @@ -30,6 +30,7 @@ import { useNativeTokenPrice, useTokenPrice } from '../../../../../plugins/Walle import { LoadingPlaceholder } from '../../../components/LoadingPlaceholder' import { toHex } from 'web3-utils' import { NetworkPluginID, useReverseAddress, useWeb3State } from '@masknet/plugin-infra' +import { isGreaterThan, pow10, rightShift } from '@masknet/web3-shared-base' const useStyles = makeStyles()(() => ({ container: { @@ -281,8 +282,7 @@ const ContractInteraction = memo(() => { // token estimated value const tokenPrice = useTokenPrice(chainId, !isNativeTokenInteraction ? token?.address : undefined) const nativeTokenPrice = useNativeTokenPrice(nativeToken?.chainId) - const tokenValueUSD = new BigNumber(tokenAmount) - .shiftedBy(-(tokenDecimals ?? 0)) + const tokenValueUSD = rightShift(tokenAmount, tokenDecimals ?? 0) .times((!isNativeTokenInteraction ? tokenPrice : nativeTokenPrice) ?? 0) .toString() @@ -334,7 +334,7 @@ const ContractInteraction = memo(() => { {tokenDecimals !== undefined ? ( <> - {new BigNumber(formatBalance(tokenAmount, tokenDecimals)).isGreaterThan(10 ** 9) ? ( + {isGreaterThan(formatBalance(tokenAmount, tokenDecimals), pow10(9)) ? ( 'infinite' ) : ( { )} - {new BigNumber(tokenValueUSD).isGreaterThan(10 ** 9) ? ( + {isGreaterThan(tokenValueUSD, pow10(9)) ? ( 'infinite' ) : ( @@ -382,7 +382,7 @@ const ContractInteraction = memo(() => { {t('popups_wallet_contract_interaction_total')} - {new BigNumber(totalUSD).isGreaterThan(10 ** 9) ? ( + {isGreaterThan(totalUSD, pow10(9)) ? ( 'infinite' ) : ( diff --git a/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx b/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx index 17d77bc6ed8a..e51be1378d31 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx @@ -24,6 +24,14 @@ import { useHistory } from 'react-router-dom' import { useNativeTokenPrice } from '../../../../../plugins/Wallet/hooks/useTokenPrice' import { PopupRoutes } from '@masknet/shared-base' import { toHex, fromWei } from 'web3-utils' +import { + isGreaterThan, + isGreaterThanOrEqualTo, + isLessThan, + isLessThanOrEqualTo, + isPositive, + multipliedBy, +} from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ options: { @@ -187,19 +195,16 @@ export const GasSetting1559 = memo(() => { .string() .min(1, t('wallet_transfer_error_gas_limit_absence')) .refine( - (gasLimit) => new BigNumber(gasLimit).isGreaterThanOrEqualTo(minGasLimit ?? 0), + (gasLimit) => isGreaterThanOrEqualTo(gasLimit, minGasLimit ?? 0), t('popups_wallet_gas_fee_settings_min_gas_limit_tips', { limit: minGasLimit }), ), maxPriorityFeePerGas: zod .string() .min(1, t('wallet_transfer_error_max_priority_fee_absence')) - .refine( - (value) => new BigNumber(value).isPositive(), - t('wallet_transfer_error_max_priority_gas_fee_positive'), - ), + .refine(isPositive, t('wallet_transfer_error_max_priority_gas_fee_positive')), maxFeePerGas: zod.string().min(1, t('wallet_transfer_error_max_fee_absence')), }) - .refine((data) => new BigNumber(data.maxPriorityFeePerGas).isLessThanOrEqualTo(data.maxFeePerGas), { + .refine((data) => isLessThanOrEqualTo(data.maxPriorityFeePerGas, data.maxFeePerGas), { message: t('wallet_transfer_error_max_priority_gas_fee_imbalance'), path: ['maxFeePerGas'], }) @@ -300,13 +305,12 @@ export const GasSetting1559 = memo(() => { //#region These are additional form rules that need to be prompted for but do not affect the validation of the form const maxPriorFeeHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxPriorityFeePerGas).isLessThan(gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) + if (isLessThan(maxPriorityFeePerGas, gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) return t('wallet_transfer_error_max_priority_gas_fee_too_low') if ( - new BigNumber(maxPriorityFeePerGas).isGreaterThan( - new BigNumber(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0).multipliedBy( - HIGH_FEE_WARNING_MULTIPLIER, - ), + isGreaterThan( + maxPriorityFeePerGas, + multipliedBy(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_priority_gas_fee_too_high') @@ -315,10 +319,11 @@ export const GasSetting1559 = memo(() => { const maxFeeGasHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxFeePerGas).isLessThan(gasOptions?.estimatedBaseFee ?? 0)) + if (isLessThan(maxFeePerGas, gasOptions?.estimatedBaseFee ?? 0)) return t('wallet_transfer_error_max_fee_too_low') if ( - new BigNumber(maxFeePerGas).isGreaterThan( + isGreaterThan( + maxFeePerGas, new BigNumber(gasOptions?.high?.suggestedMaxFeePerGas ?? 0).multipliedBy(HIGH_FEE_WARNING_MULTIPLIER), ) ) diff --git a/packages/mask/src/extension/popups/pages/Wallet/ReplaceTransaction/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ReplaceTransaction/index.tsx index fd4dbf358bd5..0861d2598eb1 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/ReplaceTransaction/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/ReplaceTransaction/index.tsx @@ -28,6 +28,7 @@ import { useAsyncFn } from 'react-use' import { useContainer } from 'unstated-next' import { WalletContext } from '../hooks/useWalletContext' import Services from '../../../../service' +import { isPositive, multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles()({ container: { @@ -96,10 +97,7 @@ const ReplaceTransaction = memo(() => { ? zod .string() .min(1, t('wallet_transfer_error_max_priority_fee_absence')) - .refine( - (value) => new BigNumber(value).isPositive(), - t('wallet_transfer_error_max_priority_gas_fee_positive'), - ) + .refine(isPositive, t('wallet_transfer_error_max_priority_gas_fee_positive')) : zod.string().optional(), maxFeePerGas: is1559 ? zod.string().min(1, t('wallet_transfer_error_max_fee_absence')) @@ -135,8 +133,7 @@ const ReplaceTransaction = memo(() => { const gasPriceEIP1559 = new BigNumber(maxFeePerGas ? maxFeePerGas : 0) const gasPricePrior1559 = new BigNumber(gasPrice ? gasPrice : 0) - const gasFee = new BigNumber(is1559 ? gasPriceEIP1559 : gasPricePrior1559) - .multipliedBy(gas ?? 0) + const gasFee = multipliedBy(is1559 ? gasPriceEIP1559 : gasPricePrior1559, gas ?? 0) .integerValue() .toFixed() diff --git a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx index d8f4528ffd6f..180b9d175adb 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx @@ -10,14 +10,13 @@ import { formatGweiToWei, formatWeiToGwei, formatEthereumAddress, - isGreaterThan, - isZero, useChainId, useGasLimit, useTokenTransferCallback, useWallet, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isZero, isGreaterThan, isGreaterThanOrEqualTo, leftShift, multipliedBy } from '@masknet/web3-shared-base' import { Controller, FormProvider, useForm, useFormContext } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { useAsync, useAsyncFn, useUpdateEffect } from 'react-use' @@ -155,18 +154,18 @@ export const Prior1559Transfer = memo(({ selectedAsset, amount: zod .string() .refine((amount) => { - const transferAmount = new BigNumber(amount || '0').shiftedBy(selectedAsset?.token.decimals ?? 0) + const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) return !!transferAmount || !isZero(transferAmount) }, t('wallet_transfer_error_amount_absence')) .refine((amount) => { - const transferAmount = new BigNumber(amount || '0').shiftedBy(selectedAsset?.token.decimals ?? 0) + const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) return !isGreaterThan(transferAmount, selectedAsset?.balance ?? 0) }, t('wallet_transfer_error_insufficient_balance', { token: selectedAsset?.token.symbol })), gasLimit: zod .string() .min(1, t('wallet_transfer_error_gas_limit_absence')) .refine( - (gasLimit) => new BigNumber(gasLimit).isGreaterThanOrEqualTo(minGasLimitContext), + (gasLimit) => isGreaterThanOrEqualTo(gasLimit, minGasLimitContext), t('popups_wallet_gas_fee_settings_min_gas_limit_tips', { limit: minGasLimitContext }), ), gasPrice: zod.string().min(1, t('wallet_transfer_error_gas_price_absence')), @@ -206,7 +205,7 @@ export const Prior1559Transfer = memo(({ selectedAsset, const { value: minGasLimit, error } = useGasLimit( selectedAsset?.token.type, selectedAsset?.token.address, - new BigNumber(!!amount ? amount : 0).shiftedBy(selectedAsset?.token.decimals ?? 0).toFixed(), + leftShift(!!amount ? amount : 0, selectedAsset?.token.decimals).toFixed(), EthereumAddress.isValid(address) ? address : '', ) //#endregion @@ -220,7 +219,7 @@ export const Prior1559Transfer = memo(({ selectedAsset, let amount_ = new BigNumber(tokenBalance || '0') amount_ = selectedAsset?.token.type === EthereumTokenType.Native - ? amount_.minus(new BigNumber(30000).multipliedBy(gasPrice)) + ? amount_.minus(multipliedBy(30000, gasPrice)) : amount_ return amount_.toFixed() @@ -246,9 +245,7 @@ export const Prior1559Transfer = memo(({ selectedAsset, const [{ loading }, onSubmit] = useAsyncFn( async (data: zod.infer) => { - const transferAmount = new BigNumber(data.amount || '0') - .shiftedBy(selectedAsset?.token.decimals || 0) - .toFixed() + const transferAmount = leftShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() await transferCallback(transferAmount, data.address, { gasPrice: toHex(formatGweiToWei(data.gasPrice).toString()), gas: new BigNumber(data.gasLimit).toNumber(), diff --git a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx index 8966ced1f8be..aa2385bf18f4 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx @@ -7,8 +7,6 @@ import { formatEthereumAddress, formatGweiToEther, formatGweiToWei, - isGreaterThan, - isZero, useChainId, useFungibleTokenBalance, useGasLimit, @@ -16,6 +14,16 @@ import { useTokenTransferCallback, useWallet, } from '@masknet/web3-shared-evm' +import { + isZero, + isGreaterThan, + isGreaterThanOrEqualTo, + isPositive, + isLessThan, + isLessThanOrEqualTo, + leftShift, + multipliedBy, +} from '@masknet/web3-shared-base' import { z as zod } from 'zod' import { EthereumAddress } from 'wallet.ts' import BigNumber from 'bignumber.js' @@ -189,40 +197,33 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM amount: zod .string() .refine((amount) => { - const transferAmount = new BigNumber(amount || '0').shiftedBy( - selectedAsset?.token.decimals ?? 0, - ) + const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) return !!transferAmount || !isZero(transferAmount) }, t('wallet_transfer_error_amount_absence')) .refine((amount) => { - const transferAmount = new BigNumber(amount || '0').shiftedBy( - selectedAsset?.token.decimals ?? 0, - ) + const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) return !isGreaterThan(transferAmount, selectedAsset?.balance ?? 0) }, t('wallet_transfer_error_insufficient_balance', { token: selectedAsset?.token.symbol })), gasLimit: zod .string() .min(1, t('wallet_transfer_error_gas_limit_absence')) .refine( - (gasLimit) => new BigNumber(gasLimit).isGreaterThanOrEqualTo(minGasLimitContext), + (gasLimit) => isGreaterThanOrEqualTo(gasLimit, minGasLimitContext), t('popups_wallet_gas_fee_settings_min_gas_limit_tips', { limit: minGasLimitContext }), ), maxPriorityFeePerGas: zod .string() .min(1, t('wallet_transfer_error_max_priority_fee_absence')) - .refine( - (value) => new BigNumber(value).isPositive(), - t('wallet_transfer_error_max_priority_gas_fee_positive'), - ) + .refine(isPositive, t('wallet_transfer_error_max_priority_gas_fee_positive')) .refine((value) => { - return new BigNumber(value).isGreaterThanOrEqualTo( - estimateGasFees?.low.suggestedMaxPriorityFeePerGas ?? 0, - ) + return isGreaterThanOrEqualTo(value, estimateGasFees?.low.suggestedMaxPriorityFeePerGas ?? 0) }, t('wallet_transfer_error_max_priority_gas_fee_too_low')) .refine( (value) => - new BigNumber(value).isLessThan( - new BigNumber(estimateGasFees?.high.suggestedMaxPriorityFeePerGas ?? 0).multipliedBy( + isLessThan( + value, + multipliedBy( + estimateGasFees?.high.suggestedMaxPriorityFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER, ), ), @@ -232,23 +233,22 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM .string() .min(1, t('wallet_transfer_error_max_fee_absence')) .refine( - (value) => - new BigNumber(value).isGreaterThanOrEqualTo( - estimateGasFees?.low.suggestedMaxFeePerGas ?? 0, - ), + (value) => isGreaterThanOrEqualTo(value, estimateGasFees?.low.suggestedMaxFeePerGas ?? 0), t('wallet_transfer_error_max_fee_too_low'), ) .refine( (value) => - new BigNumber(value).isLessThan( - new BigNumber(estimateGasFees?.high.suggestedMaxFeePerGas ?? 0).multipliedBy( + isLessThan( + value, + multipliedBy( + estimateGasFees?.high.suggestedMaxFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER, ), ), t('wallet_transfer_error_max_fee_too_high'), ), }) - .refine((data) => new BigNumber(data.maxPriorityFeePerGas).isLessThanOrEqualTo(data.maxFeePerGas), { + .refine((data) => isLessThanOrEqualTo(data.maxPriorityFeePerGas, data.maxFeePerGas), { message: t('wallet_transfer_error_max_priority_gas_fee_imbalance'), path: ['maxFeePerGas'], }) @@ -295,7 +295,7 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM const { value: minGasLimit } = useGasLimit( selectedAsset?.token.type, selectedAsset?.token.address, - new BigNumber(amount ?? 0).shiftedBy(selectedAsset?.token.decimals ?? 0).toFixed(), + leftShift(amount ?? 0, selectedAsset?.token.decimals).toFixed(), EthereumAddress.isValid(address) ? address : registeredAddress, ) //#endregion @@ -344,9 +344,7 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM const [{ loading }, onSubmit] = useAsyncFn( async (data: zod.infer) => { - const transferAmount = new BigNumber(data.amount || '0') - .shiftedBy(selectedAsset?.token.decimals || 0) - .toFixed() + const transferAmount = leftShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() //If input address is ens domain, use registeredAddress to transfer if (Utils?.isValidDomain?.(data.address)) { diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByHighestBidCard.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByHighestBidCard.tsx index 59a3f0a83b5d..5c3c4dbcf00b 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByHighestBidCard.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByHighestBidCard.tsx @@ -4,12 +4,11 @@ import { makeStyles } from '@masknet/theme' import { EthereumTokenType, FungibleTokenDetailed, - isLessThan, isNative, - isZero, FungibleTokenWatched, useAccount, } from '@masknet/web3-shared-evm' +import { isZero, isLessThan } from '@masknet/web3-shared-base' import formatDateTime from 'date-fns/format' import { useI18N } from '../../../utils' import { ActionButtonPromise } from '../../../extension/options-page/DashboardComponents/ActionButton' @@ -18,7 +17,8 @@ import { EthereumWalletConnectedBoundary } from '../../../web3/UI/EthereumWallet import { DateTimePanel } from '../../../web3/UI/DateTimePanel' import type { useAsset } from '../hooks/useAsset' import { PluginCollectibleRPC } from '../messages' -import { toAsset, toUnixTimestamp } from '../helpers' +import { toAsset } from '../helpers' +import getUnixTime from 'date-fns/getUnixTime' const useStyles = makeStyles()((theme) => ({ footer: { @@ -79,7 +79,7 @@ export function ListingByHighestBidCard(props: ListingByHighestBidCardProps) { }), accountAddress: account, startAmount: Number.parseFloat(amount), - expirationTime: toUnixTimestamp(expirationDateTime), + expirationTime: getUnixTime(expirationDateTime), englishAuctionReservePrice: Number.parseFloat(reservePrice), waitForHighestBid: true, paymentTokenAddress: token.value.address, // english auction must be erc20 token diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByPriceCard.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByPriceCard.tsx index 90c68d1116cf..8314a68e31e6 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByPriceCard.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingByPriceCard.tsx @@ -5,12 +5,12 @@ import { makeStyles } from '@masknet/theme' import { EthereumTokenType, FungibleTokenDetailed, - isGreaterThan, isNative, - isZero, FungibleTokenWatched, useAccount, } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' +import { isGreaterThan } from '@masknet/web3-shared-base' import formatDateTime from 'date-fns/format' import { useI18N } from '../../../utils' import { ActionButtonPromise } from '../../../extension/options-page/DashboardComponents/ActionButton' @@ -18,8 +18,9 @@ import { SelectTokenAmountPanel } from '../../ITO/SNSAdaptor/SelectTokenAmountPa import { EthereumWalletConnectedBoundary } from '../../../web3/UI/EthereumWalletConnectedBoundary' import { DateTimePanel } from '../../../web3/UI/DateTimePanel' import { PluginCollectibleRPC } from '../messages' -import { toAsset, toUnixTimestamp } from '../helpers' +import { toAsset } from '../helpers' import type { useAsset } from '../hooks/useAsset' +import getUnixTime from 'date-fns/getUnixTime' const useStyles = makeStyles()((theme) => { return { @@ -109,8 +110,8 @@ export function ListingByPriceCard(props: ListingByPriceCardProps) { accountAddress: account, startAmount: Number.parseFloat(amount), endAmount: endingPriceChecked && endingAmount ? Number.parseFloat(endingAmount) : undefined, - listingTime: futureTimeChecked ? toUnixTimestamp(scheduleTime) : undefined, - expirationTime: endingPriceChecked ? toUnixTimestamp(expirationTime) : undefined, + listingTime: futureTimeChecked ? getUnixTime(scheduleTime) : undefined, + expirationTime: endingPriceChecked ? getUnixTime(expirationTime) : undefined, buyerAddress: privacyChecked ? buyerAddress : undefined, }) }, [ diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingTab.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingTab.tsx index 0792becf8664..8f38ed8aa79c 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingTab.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/ListingTab.tsx @@ -9,7 +9,8 @@ import { OrderRow } from './OrderRow' import { TableListPagination } from './Pagination' import { CollectibleProvider } from '../types' import { LoadingTable } from './LoadingTable' -import { isZero, useAccount } from '@masknet/web3-shared-evm' +import { useAccount } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => { return { diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/MakeOfferDialog.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/MakeOfferDialog.tsx index 1b9f8133adca..c2d2ab518dc8 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/MakeOfferDialog.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/MakeOfferDialog.tsx @@ -31,9 +31,10 @@ import { EthereumWalletConnectedBoundary } from '../../../web3/UI/EthereumWallet import type { useAsset } from '../hooks/useAsset' import { DateTimePanel } from '../../../web3/UI/DateTimePanel' import { PluginCollectibleRPC } from '../messages' -import { toAsset, toUnixTimestamp } from '../helpers' +import { toAsset } from '../helpers' import { PluginTraderMessages } from '../../Trader/messages' import { Trans } from 'react-i18next' +import getUnixTime from 'date-fns/getUnixTime' const useStyles = makeStyles()((theme) => { return { @@ -100,7 +101,7 @@ export function MakeOfferDialog(props: MakeOfferDialogProps) { }), accountAddress: account, startAmount: Number.parseFloat(amount), - expirationTime: !isAuction ? toUnixTimestamp(expirationDateTime) : undefined, + expirationTime: !isAuction ? getUnixTime(expirationDateTime) : undefined, paymentTokenAddress: token.value.type === EthereumTokenType.Native ? undefined : token.value.address, }) }, [asset?.value, token, account, amount, expirationDateTime, isAuction]) diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/OfferTab.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/OfferTab.tsx index da68dd1fd395..3d916aef78ae 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/OfferTab.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/OfferTab.tsx @@ -9,7 +9,7 @@ import { OrderRow } from './OrderRow' import { TableListPagination } from './Pagination' import { CollectibleProvider } from '../types' import { LoadingTable } from './LoadingTable' -import { isZero } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => { return { diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/OrderRow.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/OrderRow.tsx index 6d4d282d2630..84951b770149 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/OrderRow.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/OrderRow.tsx @@ -4,7 +4,8 @@ import { Avatar, Link, TableCell, TableRow, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import { AssetOrder, CollectibleProvider } from '../types' import formatDistanceToNow from 'date-fns/formatDistanceToNow' -import { ChainId, formatBalance, isZero, resolveAddressLinkOnExplorer } from '@masknet/web3-shared-evm' +import { ChainId, formatBalance, resolveAddressLinkOnExplorer } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' import { CollectibleState } from '../hooks/useCollectibleState' import { Account } from './Account' import { FormattedBalance } from '@masknet/shared' diff --git a/packages/mask/src/plugins/Collectible/helpers.ts b/packages/mask/src/plugins/Collectible/helpers.ts index 3d7ec6fafba2..3757077379a2 100644 --- a/packages/mask/src/plugins/Collectible/helpers.ts +++ b/packages/mask/src/plugins/Collectible/helpers.ts @@ -1,10 +1,11 @@ import type { Asset, OpenSeaFungibleToken, WyvernSchemaName } from 'opensea-js/lib/types' -import BigNumber from 'bignumber.js' import { ChainId, createERC20Token, createNativeToken } from '@masknet/web3-shared-evm' import { createRenderWithMetadata, createTypedMessageMetadataReader } from '../../protocols/typed-message' import { PLUGIN_META_KEY, RaribleIPFSURL } from './constants' import type { CollectibleJSON_Payload, CollectibleToken } from './types' import schema from './schema.json' +import { rightShift } from '@masknet/web3-shared-base' +import type BigNumber from 'bignumber.js' export const CollectibleMetadataReader = createTypedMessageMetadataReader( PLUGIN_META_KEY, @@ -30,17 +31,8 @@ export function toTokenIdentifier(token?: CollectibleToken) { return `${token.contractAddress}_${token.tokenId}` } -export function toDecimalAmount(weiAmount: string, decimals: number) { - return new BigNumber(weiAmount).shiftedBy(-decimals).toNumber() -} - -export function toUnixTimestamp(date: Date) { - return Math.floor(date.getTime() / 1000) -} - -export function toDate(timestamp: number) { - if (timestamp === 0) return null - return new Date(timestamp * 1000) +export function toDecimalAmount(weiAmount: BigNumber.Value, decimals: number) { + return rightShift(weiAmount, decimals).toNumber() } export function toRaribleImage(url?: string) { diff --git a/packages/mask/src/plugins/Collectible/hooks/useAsset.ts b/packages/mask/src/plugins/Collectible/hooks/useAsset.ts index 8665c523872e..9344f7126bab 100644 --- a/packages/mask/src/plugins/Collectible/hooks/useAsset.ts +++ b/packages/mask/src/plugins/Collectible/hooks/useAsset.ts @@ -9,10 +9,11 @@ import { useTokenConstants, } from '@masknet/web3-shared-evm' import BigNumber from 'bignumber.js' +import fromUnixTime from 'date-fns/fromUnixTime' import { first, head, uniqBy } from 'lodash-unified' import { useAsyncRetry } from 'react-use' import { OpenSeaAccountURL } from '../constants' -import { toDate, toTokenDetailed, toTokenIdentifier } from '../helpers' +import { toTokenDetailed, toTokenIdentifier } from '../helpers' import { PluginCollectibleRPC } from '../messages' import { CollectibleProvider, CollectibleToken } from '../types' import { getOrderUnitPrice } from '../utils' @@ -91,7 +92,7 @@ export function useAsset(provider: CollectibleProvider, token?: CollectibleToken end_time: openSeaResponse.endTime ? new Date(openSeaResponse.endTime) : desktopOrder - ? toDate(Number.parseInt(desktopOrder.listing_time as unknown as string, 10)) + ? fromUnixTime(desktopOrder.listing_time) : null, order_payment_tokens: desktopOrder?.payment_token_contract ? [toTokenDetailed(chainId, desktopOrder.payment_token_contract)] diff --git a/packages/mask/src/plugins/Collectible/utils.ts b/packages/mask/src/plugins/Collectible/utils.ts index 77d484e17d11..e5c506cda905 100644 --- a/packages/mask/src/plugins/Collectible/utils.ts +++ b/packages/mask/src/plugins/Collectible/utils.ts @@ -8,6 +8,7 @@ import { } from './constants' import { ChainId, formatBalance } from '@masknet/web3-shared-evm' import type { AssetEvent } from './types' +import { multipliedBy } from '@masknet/web3-shared-base' export function checkUrl(url: string): boolean { const protocol = 'https://' @@ -70,7 +71,7 @@ export function getOrderUSDPrice(currentPrice?: string, usdPrice?: string, decim const price = formatBalance(usdPrice, 0) const quantity = formatBalance(currentPrice, decimals) - return new BigNumber(price).multipliedBy(quantity).toFixed(2, 1).toString() + return multipliedBy(price, quantity).toFixed(2, 1).toString() } export function getLastSalePrice(lastSale: AssetEvent | null) { diff --git a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx index aaa80374a1ca..038211a9134b 100644 --- a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx +++ b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx @@ -11,7 +11,6 @@ import { } from '@masknet/web3-shared-evm' import { DialogContent, Link, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' -import BigNumber from 'bignumber.js' import { useCallback, useEffect, useMemo, useState } from 'react' import { Trans } from 'react-i18next' import { v4 as uuid } from 'uuid' @@ -28,6 +27,7 @@ import { TokenAmountPanel } from '../../../web3/UI/TokenAmountPanel' import { SelectTokenDialogEvent, WalletMessages } from '../../Wallet/messages' import { useDonateCallback } from '../hooks/useDonateCallback' import { PluginGitcoinMessages } from '../messages' +import { leftShift } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ paper: { @@ -112,7 +112,7 @@ export function DonateDialog(props: DonateDialogProps) { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = new BigNumber(rawAmount || '0').shiftedBy(token?.decimals ?? 0) + const amount = leftShift(rawAmount || '0', token?.decimals) //#endregion //#region blocking diff --git a/packages/mask/src/plugins/GoodGhosting/UI/GameActionDialog.tsx b/packages/mask/src/plugins/GoodGhosting/UI/GameActionDialog.tsx index 4ad514ba3955..51ef10098ffb 100644 --- a/packages/mask/src/plugins/GoodGhosting/UI/GameActionDialog.tsx +++ b/packages/mask/src/plugins/GoodGhosting/UI/GameActionDialog.tsx @@ -7,7 +7,7 @@ import type { GoodGhostingInfo } from '../types' import { EthereumERC20TokenApprovedBoundary } from '../../../web3/UI/EthereumERC20TokenApprovedBoundary' import { useI18N } from '../../../utils' import { useGameToken } from '../hooks/usePoolData' -import BigNumber from 'bignumber.js' +import { isGreaterThanOrEqualTo } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ content: { @@ -57,9 +57,7 @@ export function GameActionDialog(props: GameActionDialogProps) { } = useERC20TokenBalance(gameToken.address) const hasSufficientBalance = - !loadingTokenBalance && - !errorTokenBalance && - new BigNumber(tokenBalance).isGreaterThanOrEqualTo(info.segmentPayment) + !loadingTokenBalance && !errorTokenBalance && isGreaterThanOrEqualTo(tokenBalance, info.segmentPayment) let action = (
diff --git a/packages/mask/src/plugins/GoodGhosting/utils.ts b/packages/mask/src/plugins/GoodGhosting/utils.ts index 07a4eb3faaba..c4f88e49a208 100644 --- a/packages/mask/src/plugins/GoodGhosting/utils.ts +++ b/packages/mask/src/plugins/GoodGhosting/utils.ts @@ -14,6 +14,7 @@ import formatDuration from 'date-fns/formatDuration' import isBefore from 'date-fns/isBefore' import { CurrencyType, TransactionStateType } from '@masknet/web3-shared-evm' import BigNumber from 'bignumber.js' +import { multipliedBy } from '@masknet/web3-shared-base' export enum PlayerStatus { Winning = 'winning', @@ -116,7 +117,7 @@ export function getGameFinancialData( const dateAfterDuration = addSeconds(baseDate, info.segmentLength * (info.lastSegment + 1)) const gameDuration = differenceInDays(dateAfterDuration, baseDate) - const expectedPayment = new BigNumber(info.segmentPayment).multipliedBy(info.lastSegment) + const expectedPayment = multipliedBy(info.segmentPayment, info.lastSegment) const dividend = winnerGains.multipliedBy(365) const divisor = expectedPayment .multipliedBy(gameDuration) @@ -128,7 +129,7 @@ export function getGameFinancialData( poolAPY, poolEarnings: info.gameHasEnded ? new BigNumber(info.totalGameInterest) : rawPoolInterest, extraRewards: info.gameHasEnded - ? new BigNumber(playerStandings.winning).multipliedBy(info.rewardsPerPlayer) + ? multipliedBy(playerStandings.winning, info.rewardsPerPlayer) : new BigNumber(poolData.reward).plus(poolData.incentives), } as GameFinancialData } diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ConfirmDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ConfirmDialog.tsx index b2d3bcceb42f..f1ad321f8b39 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/ConfirmDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ConfirmDialog.tsx @@ -5,12 +5,12 @@ import { formatEthereumAddress, FungibleTokenDetailed, isNative, - ONE, resolveAddressLinkOnExplorer, resolveTokenLinkOnExplorer, useChainId, useITOConstants, } from '@masknet/web3-shared-evm' +import { ONE } from '@masknet/web3-shared-base' import { Card, Grid, IconButton, Link, Paper, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import LaunchIcon from '@mui/icons-material/Launch' diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/CreateForm.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/CreateForm.tsx index 321f62d68bf8..dc54303e4888 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/CreateForm.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/CreateForm.tsx @@ -3,12 +3,11 @@ import { EthereumTokenType, formatAmount, formatBalance, - isGreaterThan, - isZero, useAccount, useITOConstants, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isGreaterThan, isZero } from '@masknet/web3-shared-base' import { Box, CircularProgress, Stack, TextField, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import CheckIcon from '@mui/icons-material/Check' diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ITO.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ITO.tsx index d1d7f5d2b03f..e6708aa5d31b 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/ITO.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ITO.tsx @@ -6,16 +6,14 @@ import { getChainDetailed, isSameAddress, currySameAddress, - isZero, resolveLinkOnExplorer, TransactionStateType, useAccount, useChainId, useChainIdValid, useTokenConstants, - ZERO, - isGreaterThan, } from '@masknet/web3-shared-evm' +import { isZero, ZERO, isGreaterThan } from '@masknet/web3-shared-base' import { Box, Card, Grid, Link, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import OpenInNewIcon from '@mui/icons-material/OpenInNew' diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/PoolInList.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/PoolInList.tsx index fdf8ee81e80d..2387abb7ca3f 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/PoolInList.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/PoolInList.tsx @@ -5,13 +5,13 @@ import { FungibleToken, getChainDetailed, isSameAddress, - isZero, TransactionStateType, useAccount, useFungibleTokenDetailed, useFungibleTokensDetailed, useTokenConstants, } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' import { Box, Card, diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ShareDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ShareDialog.tsx index e76500717b19..ec3c7ddf214e 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/ShareDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ShareDialog.tsx @@ -3,7 +3,8 @@ import { Box, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import { getAssetAsBlobURL, useI18N } from '../../../utils' import ActionButton from '../../../extension/options-page/DashboardComponents/ActionButton' -import { formatBalance, isZero, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { formatBalance, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' import type { BigNumber } from 'bignumber.js' const useStyles = makeStyles()((theme) => ({ diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx index 691244f3ccc2..102540d57404 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx @@ -17,11 +17,11 @@ import { TransactionStateType, useChainId, useFungibleTokenBalance, - ZERO, useFungibleTokenDetailed, isSameAddress, useTokenConstants, } from '@masknet/web3-shared-evm' +import { leftShift, rightShift, ZERO } from '@masknet/web3-shared-base' import { SelectTokenDialogEvent, WalletMessages, WalletRPC } from '../../Wallet/messages' import { TokenAmountPanel } from '../../../web3/UI/TokenAmountPanel' import { useSwapCallback } from './hooks/useSwapCallback' @@ -154,7 +154,7 @@ export function SwapDialog(props: SwapDialogProps) { setTokenAmount(initAmount) setSwapAmount(initAmount.multipliedBy(ratio)) setInputAmountForUI( - initAmount.isEqualTo(0) ? '' : formatBalance(initAmount.multipliedBy(ratio), ev.token.decimals), + initAmount.isZero() ? '' : formatBalance(initAmount.multipliedBy(ratio), ev.token.decimals), ) }, [ @@ -257,7 +257,7 @@ export function SwapDialog(props: SwapDialogProps) { //#endregion const validationMessage = useMemo(() => { - if (swapAmount.isEqualTo(0)) return t('plugin_ito_error_enter_amount') + if (swapAmount.isZero()) return t('plugin_ito_error_enter_amount') if (swapAmount.isGreaterThan(tokenBalance)) return t('plugin_ito_error_balance', { symbol: swapToken?.symbol }) if (tokenAmount.isGreaterThan(maxSwapAmount)) return t('plugin_ito_dialog_swap_exceed_wallet_limit') return '' @@ -295,13 +295,12 @@ export function SwapDialog(props: SwapDialogProps) { balance={tokenBalance} token={swapToken} onAmountChange={(value) => { - const val = - value === '' || value === '0' ? ZERO : new BigNumber(value).shiftedBy(swapToken.decimals) - const isMax = value === formatBalance(maxAmount, swapToken.decimals) && !val.isEqualTo(0) + const val = value === '' || value === '0' ? ZERO : leftShift(value, swapToken.decimals) + const isMax = value === formatBalance(maxAmount, swapToken.decimals) && !val.isZero() const tokenAmount = isMax ? maxSwapAmount : val.dividedBy(ratio) const swapAmount = isMax ? tokenAmount.multipliedBy(ratio) : val.dp(0) setInputAmountForUI( - isMax ? tokenAmount.multipliedBy(ratio).shiftedBy(-swapToken.decimals).toString() : value, + isMax ? rightShift(tokenAmount.multipliedBy(ratio), swapToken.decimals).toString() : value, ) setTokenAmount(tokenAmount.dp(0)) setSwapAmount(swapAmount) diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapGuide.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapGuide.tsx index bef3788e9e7e..d596b68bc84e 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapGuide.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapGuide.tsx @@ -1,11 +1,5 @@ -import { - ERC20TokenDetailed, - useAccount, - useChainId, - ZERO, - isSameAddress, - useTokenConstants, -} from '@masknet/web3-shared-evm' +import { ERC20TokenDetailed, useAccount, useChainId, isSameAddress, useTokenConstants } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import { DialogContent } from '@mui/material' import { makeStyles } from '@masknet/theme' import BigNumber from 'bignumber.js' diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx index 74b56dc5a4d8..2ee64a0c1c75 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx @@ -1,6 +1,5 @@ import { Link, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' -import BigNumber from 'bignumber.js' import { useCallback, useState } from 'react' import { v4 as uuid } from 'uuid' import { FormattedAddress, useRemoteControlledDialog } from '@masknet/shared' @@ -12,11 +11,11 @@ import { EthereumTokenType, formatBalance, formatEthereumAddress, - isGreaterThan, resolveAddressLinkOnExplorer, useChainId, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isGreaterThan, leftShift } from '@masknet/web3-shared-base' import { EthereumERC20TokenApprovedBoundary } from '../../../web3/UI/EthereumERC20TokenApprovedBoundary' import { EthereumWalletConnectedBoundary } from '../../../web3/UI/EthereumWalletConnectedBoundary' import { TokenAmountPanel } from '../../../web3/UI/TokenAmountPanel' @@ -79,7 +78,7 @@ export function UnlockDialog(props: UnlockDialogProps) { //#endregion //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = new BigNumber(rawAmount || '0').shiftedBy(token?.decimals ?? 0) + const amount = leftShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance } = useFungibleTokenBalance( token?.type ?? EthereumTokenType.Native, token?.address ?? '', diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useFill.ts b/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useFill.ts index dc374875b83e..5e7c8f3c901a 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useFill.ts +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useFill.ts @@ -6,8 +6,6 @@ import Web3Utils from 'web3-utils' import type { ITO2 } from '@masknet/web3-contracts/types/ITO2' import type { NonPayableTx } from '@masknet/web3-contracts/types/types' import { - isGreaterThan, - ONE, TransactionEventType, TransactionStateType, useAccount, @@ -19,6 +17,7 @@ import { TransactionState, FAKE_SIGN_PASSWORD, } from '@masknet/web3-shared-evm' +import { isGreaterThan, ONE } from '@masknet/web3-shared-base' import { useITO_Contract } from './useITO_Contract' import { gcd, sortTokens } from '../helpers' import { ITO_CONTRACT_BASE_TIMESTAMP, MSG_DELIMITER } from '../../constants' diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useSwapCallback.ts b/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useSwapCallback.ts index f8e0273b0ed0..62e2f571d1e9 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useSwapCallback.ts +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/hooks/useSwapCallback.ts @@ -7,7 +7,6 @@ import { currySameAddress, EthereumTokenType, FungibleTokenDetailed, - isZero, TransactionEventType, TransactionStateType, useAccount, @@ -16,6 +15,7 @@ import { isSameAddress, useITOConstants, } from '@masknet/web3-shared-evm' +import { isPositive, isZero } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { useCallback } from 'react' import type { TransactionReceipt } from 'web3-core' @@ -74,7 +74,7 @@ export function useSwapCallback( } // error: invalid swap amount - if (!new BigNumber(total).isPositive()) { + if (!isPositive(total)) { setSwapState({ type: TransactionStateType.FAILED, error: new Error('Invalid swap amount.'), diff --git a/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/DrawDialog.tsx b/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/DrawDialog.tsx index 8d338950a7be..5e7915a38c4d 100644 --- a/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/DrawDialog.tsx +++ b/packages/mask/src/plugins/MaskBox/SNSAdaptor/components/DrawDialog.tsx @@ -1,5 +1,4 @@ import { useCallback } from 'react' -import BigNumber from 'bignumber.js' import { useContainer } from 'unstated-next' import { makeStyles } from '@masknet/theme' import { Add, Remove } from '@mui/icons-material' @@ -23,6 +22,7 @@ import type { BoxInfo } from '../../type' import { GasSettingBar } from '../../../Wallet/SNSAdaptor/GasSettingDialog/GasSettingBar' import { TokenPrice } from '../../../../components/shared/TokenPrice' import { Context } from '../../hooks/useContext' +import { multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ main: { @@ -132,7 +132,7 @@ export function DrawDialog(props: DrawDialogProps) { now) return BoxState.NOT_READY if (boxInfo.endAt < now || maskBoxStatus?.expired) return BoxState.EXPIRED return BoxState.READY @@ -155,7 +155,7 @@ function useContext(initialState?: { boxId: string }) { const { value: holderTokenBalance = '0' } = useERC20TokenBalance(holderToken?.address) const holderMinTokenAmountBN = new BigNumber(boxInfo?.holderMinTokenAmount ?? 0) const isQualified = - (holderMinTokenAmountBN.eq(0) || holderMinTokenAmountBN.lte(holderTokenBalance)) && isQualifiedByContract + (isZero(holderMinTokenAmountBN) || holderMinTokenAmountBN.lte(holderTokenBalance)) && isQualifiedByContract //#endregion const boxStateMessage = useMemo(() => { @@ -223,7 +223,7 @@ function useContext(initialState?: { boxId: string }) { const paymentTokenIndex = boxInfo?.payments.findIndex((x) => isSameAddress(x.token.address ?? '', paymentTokenAddress)) ?? -1 const paymentTokenPrice = paymentTokenInfo?.price ?? '0' - const costAmount = new BigNumber(paymentTokenPrice).multipliedBy(paymentCount) + const costAmount = multipliedBy(paymentTokenPrice, paymentCount) const isNativeToken = isSameAddress(paymentTokenAddress, NATIVE_TOKEN_ADDRESS) const paymentTokenBalance = isNativeToken ? paymentNativeTokenBalance : paymentERC20TokenBalance const paymentTokenDetailed = paymentTokenInfo?.token ?? null diff --git a/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts b/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts index ec4460516f33..91f772589fe8 100644 --- a/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts +++ b/packages/mask/src/plugins/MaskBox/hooks/useOpenBoxTransaction.ts @@ -1,8 +1,8 @@ import { useMemo } from 'react' -import BigNumber from 'bignumber.js' import type { NonPayableTx } from '@masknet/web3-contracts/types/types' import { EthereumTokenType, FungibleTokenDetailed, useAccount } from '@masknet/web3-shared-evm' import { useMaskBoxContract } from './useMaskBoxContract' +import { multipliedBy } from '@masknet/web3-shared-base' export function useOpenBoxTransaction( boxId: string, @@ -22,7 +22,7 @@ export function useOpenBoxTransaction( from: account, value: paymentTokenDetailed?.type === EthereumTokenType.Native - ? new BigNumber(paymentTokenPrice).multipliedBy(amount).toFixed() + ? multipliedBy(paymentTokenPrice, amount).toFixed() : undefined, }, method: maskBoxContract.methods.openBox(boxId, amount, paymentTokenIndex, '0x0'), diff --git a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx index e99af80d32d4..c1350acab8cf 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx @@ -3,15 +3,14 @@ import { EthereumTokenType, formatBalance, FungibleTokenDetailed, - isZero, TransactionStateType, useAccount, ZERO_ADDRESS, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isZero, leftShift } from '@masknet/web3-shared-base' import { DialogContent, Grid, Typography } from '@mui/material' import { keyframes, makeStyles } from '@masknet/theme' -import BigNumber from 'bignumber.js' import { useCallback, useEffect, useMemo, useState } from 'react' import { v4 as uuid } from 'uuid' import { InjectedDialog } from '../../../components/shared/InjectedDialog' @@ -129,7 +128,7 @@ export function DepositDialog() { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = new BigNumber(rawAmount || '0').shiftedBy(token?.decimals ?? 0) + const amount = leftShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance, diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx index 9c3651f8f8bb..04cc3a9309ff 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx @@ -3,13 +3,12 @@ import { EthereumTokenType, formatBalance, FungibleTokenDetailed, - isGreaterThan, - isZero, useAccount, useNativeTokenDetailed, useRedPacketConstants, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isGreaterThan, isZero, leftShift, multipliedBy } from '@masknet/web3-shared-base' import { omit } from 'lodash-unified' import { FormControl, InputLabel, MenuItem, MenuProps, Select, TextField } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' @@ -145,11 +144,8 @@ export function RedPacketERC20Form(props: RedPacketFormProps) { ? formatBalance(origin?.total, origin.token?.decimals ?? 0) : formatBalance(new BigNumber(origin?.total ?? '0').div(origin?.shares ?? 1), origin?.token?.decimals ?? 0), ) - const amount = new BigNumber(rawAmount ?? '0').shiftedBy(token?.decimals ?? 0) - const totalAmount = useMemo( - () => (isRandom ? new BigNumber(amount) : new BigNumber(amount).multipliedBy(shares ?? '0')), - [amount, shares], - ) + const amount = leftShift(rawAmount ?? '0', token?.decimals) + const totalAmount = useMemo(() => multipliedBy(amount, isRandom ? 1 : shares ?? '0'), [amount, shares]) // balance const { value: tokenBalance = '0', loading: loadingTokenBalance } = useFungibleTokenBalance( diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useCreateCallback.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useCreateCallback.tsx index ff80ac36008c..1f517b100009 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useCreateCallback.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/hooks/useCreateCallback.tsx @@ -9,7 +9,6 @@ import type { PayableTx } from '@masknet/web3-contracts/types/types' import { EthereumTokenType, FungibleTokenDetailed, - isLessThan, TransactionEventType, TransactionState, TransactionStateType, @@ -18,6 +17,7 @@ import { useTokenConstants, useTransactionState, } from '@masknet/web3-shared-evm' +import { isLessThan } from '@masknet/web3-shared-base' import { useRedPacketContract } from './useRedPacketContract' export interface RedPacketSettings { diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/ConfirmDialog.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/ConfirmDialog.tsx index 2cee2ae37250..8fe85ba324f2 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/ConfirmDialog.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/ConfirmDialog.tsx @@ -20,6 +20,7 @@ import { TokenIcon } from '@masknet/shared' import { TargetChainIdContext } from '../../trader/useTargetChainIdContext' import { currentSlippageSettings } from '../../settings' import { useNativeTokenPrice } from '../../../Wallet/hooks/useTokenPrice' +import { multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ section: { @@ -118,7 +119,7 @@ export function ConfirmDialogUI(props: ConfirmDialogUIProps) { const tokenPrice = useNativeTokenPrice(chainId) const gasFee = useMemo(() => { - return gas && gasPrice ? new BigNumber(gasPrice).multipliedBy(gas).integerValue().toFixed() : '0' + return gas && gasPrice ? multipliedBy(gasPrice, gas).integerValue().toFixed() : '0' }, [gas, gasPrice]) const feeValueUSD = useMemo( diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Gas1559Settings.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Gas1559Settings.tsx index 197ba7b2d0ee..26554a813b3f 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Gas1559Settings.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Gas1559Settings.tsx @@ -14,6 +14,7 @@ import { ExpandMore } from '@mui/icons-material' import { fromWei, toHex } from 'web3-utils' import { isEmpty } from 'lodash-unified' import ActionButton from '../../../../extension/options-page/DashboardComponents/ActionButton' +import { isGreaterThan, isLessThan, isLessThanOrEqualTo, isPositive, multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ option: { @@ -120,13 +121,10 @@ function defineSchema(t: I18NFunction) { maxPriorityFeePerGas: zod .string() .min(1, t('wallet_transfer_error_max_priority_fee_absence')) - .refine( - (value) => new BigNumber(value).isPositive(), - t('wallet_transfer_error_max_priority_fee_absence'), - ), + .refine(isPositive, t('wallet_transfer_error_max_priority_fee_absence')), maxFeePerGas: zod.string().min(1, t('wallet_transfer_error_max_fee_absence')), }) - .refine((data) => new BigNumber(data.maxPriorityFeePerGas).isLessThanOrEqualTo(data.maxFeePerGas), { + .refine((data) => isLessThanOrEqualTo(data.maxPriorityFeePerGas, data.maxFeePerGas), { message: t('wallet_transfer_error_max_priority_gas_fee_imbalance'), path: ['maxFeePerGas'], }) @@ -193,13 +191,12 @@ export const Gas1559Settings = memo(({ onCancel, onSave: o //#region These are additional form rules that need to be prompted for but do not affect the validation of the form const maxPriorFeeHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxPriorityFeePerGas).isLessThan(gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) + if (isLessThan(maxPriorityFeePerGas, gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) return t('wallet_transfer_error_max_priority_gas_fee_too_low') if ( - new BigNumber(maxPriorityFeePerGas).isGreaterThan( - new BigNumber(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0).multipliedBy( - HIGH_FEE_WARNING_MULTIPLIER, - ), + isGreaterThan( + maxPriorityFeePerGas, + multipliedBy(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_priority_gas_fee_too_high') @@ -208,11 +205,12 @@ export const Gas1559Settings = memo(({ onCancel, onSave: o const maxFeeGasHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxFeePerGas).isLessThan(gasOptions?.estimatedBaseFee ?? 0)) + if (isLessThan(maxFeePerGas, gasOptions?.estimatedBaseFee ?? 0)) return t('wallet_transfer_error_max_fee_too_low') if ( - new BigNumber(maxFeePerGas).isGreaterThan( - new BigNumber(gasOptions?.high?.suggestedMaxFeePerGas ?? 0).multipliedBy(HIGH_FEE_WARNING_MULTIPLIER), + isGreaterThan( + maxFeePerGas, + multipliedBy(gasOptions?.high?.suggestedMaxFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_fee_too_high') diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx index 4e28523983fe..bd0bb59b24c5 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx @@ -4,7 +4,8 @@ import { makeStyles, MaskColorVar } from '@masknet/theme' import { InputTokenPanel } from './InputTokenPanel' import { Box, chipClasses, Collapse, IconButton, Tooltip, Typography } from '@mui/material' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { EthereumTokenType, formatBalance, formatPercentage, isLessThan } from '@masknet/web3-shared-evm' +import { EthereumTokenType, formatBalance, formatPercentage } from '@masknet/web3-shared-evm' +import { isLessThan, leftShift } from '@masknet/web3-shared-base' import { TokenPanelType, TradeInfo, WarningLevel } from '../../types' import BigNumber from 'bignumber.js' import { first, noop } from 'lodash-unified' @@ -234,7 +235,7 @@ export const TradeForm = memo( //#endregion //#region form controls - const inputTokenTradeAmount = new BigNumber(inputAmount || '0').shiftedBy(inputToken?.decimals ?? 0) + const inputTokenTradeAmount = leftShift(inputAmount || '0', inputToken?.decimals) //#endregion //#region UI logic diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx index eb7341d0c24e..b103dee8a9de 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx @@ -10,7 +10,6 @@ import { FungibleTokenDetailed, GasOptionConfig, getNetworkTypeFromChainId, - isGreaterThan, isSameAddress, TransactionStateType, useChainId, @@ -19,6 +18,7 @@ import { useTokenConstants, useWallet, } from '@masknet/web3-shared-evm' +import { isGreaterThan, isLessThan, multipliedBy } from '@masknet/web3-shared-base' import { useRemoteControlledDialog, useValueRef } from '@masknet/shared' import type { Coin } from '../../types' import { TokenPanelType, TradeInfo } from '../../types' @@ -403,7 +403,7 @@ export function Trader(props: TraderProps) { isGreaterThan(trade.value.outputAmount, MINIMUM_AMOUNT) && trade.gas.value ) { - const gasFee = new BigNumber(gasPrice).multipliedBy(trade.gas.value).integerValue().toFixed() + const gasFee = multipliedBy(gasPrice, trade.gas.value).integerValue().toFixed() const gasFeeUSD = new BigNumber(formatBalance(gasFee ?? 0, outputToken.decimals)).times( nativeTokenPrice, @@ -424,8 +424,8 @@ export function Trader(props: TraderProps) { }) .filter(({ finalPrice }) => !!finalPrice) .sort(({ finalPrice: a }, { finalPrice: b }) => { - if (a && b && new BigNumber(a).isGreaterThan(b)) return -1 - if (a && b && new BigNumber(a).isLessThan(b)) return 1 + if (a && b && isGreaterThan(a, b)) return -1 + if (a && b && isLessThan(a, b)) return 1 return 0 }) } diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderInfo.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderInfo.tsx index 461191c26cee..068a79266e5c 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderInfo.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderInfo.tsx @@ -14,6 +14,7 @@ import { TradeProvider } from '@masknet/public-api' import BigNumber from 'bignumber.js' import { useNativeTokenPrice } from '../../../Wallet/hooks/useTokenPrice' import { TargetChainIdContext } from '../../trader/useTargetChainIdContext' +import { multipliedBy } from '@masknet/web3-shared-base' const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ trade: { @@ -85,9 +86,7 @@ export const TraderInfo = memo(({ trade, gasPrice, isBest, onCl const tokenPrice = useNativeTokenPrice(targetChainId) const gasFee = useMemo(() => { - return trade.gas.value && gasPrice - ? new BigNumber(gasPrice).multipliedBy(trade.gas.value).integerValue().toFixed() - : 0 + return trade.gas.value && gasPrice ? multipliedBy(gasPrice, trade.gas.value).integerValue().toFixed() : 0 }, [trade.gas?.value, gasPrice]) const feeValueUSD = useMemo( diff --git a/packages/mask/src/plugins/Trader/apis/balancer/index.ts b/packages/mask/src/plugins/Trader/apis/balancer/index.ts index 8d4ff4e0178d..9befd4aed39a 100644 --- a/packages/mask/src/plugins/Trader/apis/balancer/index.ts +++ b/packages/mask/src/plugins/Trader/apis/balancer/index.ts @@ -1,6 +1,7 @@ import { SOR } from '@balancer-labs/sor' import { JsonRpcProvider } from '@ethersproject/providers' -import { ChainId, getRPCConstants, getTraderConstants, isSameAddress, ZERO } from '@masknet/web3-shared-evm' +import { ChainId, getRPCConstants, getTraderConstants, isSameAddress } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { first, memoize } from 'lodash-unified' import { currentChainIdSettings } from '../../../Wallet/settings' diff --git a/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts b/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts index 0bdf23ea6838..1216585703ed 100644 --- a/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts +++ b/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts @@ -1,4 +1,5 @@ -import { FungibleTokenDetailed, ONE } from '@masknet/web3-shared-evm' +import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { leftShift, ONE, rightShift } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { BIPS_BASE } from '../../constants' @@ -11,8 +12,8 @@ export const calculateMinimumReturn = ({ toAmount: string | undefined slippage: number }): string => { - const toWei = new BigNumber(toAmount || '0').shiftedBy(toToken.decimals ?? 0) + const toWei = leftShift(toAmount || '0', toToken.decimals) const slippageWei = new BigNumber(slippage).dividedBy(BIPS_BASE) const minReturnWei = toWei.times(ONE.minus(slippageWei)) - return minReturnWei.shiftedBy(-(toToken.decimals ?? 0)).toFixed() + return rightShift(minReturnWei, -(toToken.decimals ?? 0)).toFixed() } diff --git a/packages/mask/src/plugins/Trader/apis/coinmarketcap/index.ts b/packages/mask/src/plugins/Trader/apis/coinmarketcap/index.ts index 2bc917858420..271cc01cf663 100644 --- a/packages/mask/src/plugins/Trader/apis/coinmarketcap/index.ts +++ b/packages/mask/src/plugins/Trader/apis/coinmarketcap/index.ts @@ -1,5 +1,6 @@ import { CMC_V1_BASE_URL, THIRD_PARTY_V1_BASE_URL } from '../../constants' import { Flags } from '../../../../../shared' +import getUnixTime from 'date-fns/getUnixTime' export interface Status { credit_count: number @@ -195,13 +196,12 @@ export async function getHistorical( endDate: Date, interval: string = '1d', ) { - const toUnixTimestamp = (d: Date) => String(Math.floor(d.getTime() / 1000)) const params = new URLSearchParams('format=chart_crypto_details') params.append('convert', currency) params.append('id', id) params.append('interval', interval) - params.append('time_end', toUnixTimestamp(endDate)) - params.append('time_start', toUnixTimestamp(startDate)) + params.append('time_end', getUnixTime(endDate).toString()) + params.append('time_start', getUnixTime(startDate).toString()) const response = await fetch(`${CMC_V1_BASE_URL}/cryptocurrency/quotes/historical?${params.toString()}`, { cache: Flags.trader_all_api_cached_enabled ? 'force-cache' : 'default', diff --git a/packages/mask/src/plugins/Trader/apis/dodo/index.ts b/packages/mask/src/plugins/Trader/apis/dodo/index.ts index 92f6c9f7ff22..a54ab4bd74ba 100644 --- a/packages/mask/src/plugins/Trader/apis/dodo/index.ts +++ b/packages/mask/src/plugins/Trader/apis/dodo/index.ts @@ -6,8 +6,8 @@ import type { SwapRouteSuccessResponse, } from '../../types/dodo' import { DODO_BASE_URL } from '../../constants/dodo' -import BigNumber from 'bignumber.js' import urlcat from 'urlcat' +import { rightShift } from '@masknet/web3-shared-base' export async function swapRoute(request: SwapRouteRequest) { const response = await fetch( @@ -31,7 +31,7 @@ export async function swapRoute(request: SwapRouteRequest) { return { ...(payload as SwapRouteSuccessResponse).data, - fromAmount: new BigNumber(request.fromAmount).shiftedBy(-(request.fromToken.decimals ?? 0)).toNumber(), + fromAmount: rightShift(request.fromAmount, request.fromToken.decimals ?? 0).toNumber(), value: request.isNativeSellToken ? request.fromAmount : '0', slippage: request.slippage, fromTokenSymbol: request.fromToken.symbol, diff --git a/packages/mask/src/plugins/Trader/apis/uniswap/index.ts b/packages/mask/src/plugins/Trader/apis/uniswap/index.ts index d093c9550cb0..13ddf70472b6 100644 --- a/packages/mask/src/plugins/Trader/apis/uniswap/index.ts +++ b/packages/mask/src/plugins/Trader/apis/uniswap/index.ts @@ -17,7 +17,7 @@ import { fetchBlockNumbersObjectByTimestamps, } from '../blocks' import { fetchLatestBlocks } from '../uniswap-health' -import { isGreaterThan } from '@masknet/web3-shared-evm' +import { isGreaterThan, isLessThanOrEqualTo } from '@masknet/web3-shared-base' type Value = string | number | BigNumber | undefined @@ -378,9 +378,7 @@ export async function getPriceStats( } if (latestBlock) { - blocks = blocks.filter( - (block) => block.blockNumber && new BigNumber(block?.blockNumber).isLessThanOrEqualTo(latestBlock), - ) + blocks = blocks.filter((block) => block.blockNumber && isLessThanOrEqualTo(block?.blockNumber, latestBlock)) } const prices = await fetchPricesByBlocks(id, blocks) diff --git a/packages/mask/src/plugins/Trader/constants/trader.ts b/packages/mask/src/plugins/Trader/constants/trader.ts index 90933745a6c0..1c6f45eac93d 100644 --- a/packages/mask/src/plugins/Trader/constants/trader.ts +++ b/packages/mask/src/plugins/Trader/constants/trader.ts @@ -1,4 +1,5 @@ -import { ChainId, createERC20Tokens, getChainDetailed, ONE } from '@masknet/web3-shared-evm' +import { ChainId, createERC20Tokens, getChainDetailed } from '@masknet/web3-shared-evm' +import { ONE } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import type { ERC20AgainstToken } from './types' diff --git a/packages/mask/src/plugins/Trader/helpers/uniswap.ts b/packages/mask/src/plugins/Trader/helpers/uniswap.ts index 51e67481a274..9ac7fba44ce8 100644 --- a/packages/mask/src/plugins/Trader/helpers/uniswap.ts +++ b/packages/mask/src/plugins/Trader/helpers/uniswap.ts @@ -5,13 +5,12 @@ import { Currency, Token, CurrencyAmount, TradeType, Percent, Price, Ether } fro import type { Trade } from '@uniswap/v2-sdk' import { formatEthereumAddress, - pow10, ChainId, EthereumTokenType, FungibleTokenDetailed, isSameAddress, - isGreaterThan, } from '@masknet/web3-shared-evm' +import { pow10, isGreaterThan } from '@masknet/web3-shared-base' import { ONE_HUNDRED_PERCENT, WNATIVE, ZERO_PERCENT } from '../constants' export function swapErrorToUserReadableMessage(error: any): string { diff --git a/packages/mask/src/plugins/Trader/trader/0x/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/0x/useTradeComputed.ts index d237e02983a3..dfbff0a435c0 100644 --- a/packages/mask/src/plugins/Trader/trader/0x/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/0x/useTradeComputed.ts @@ -1,6 +1,7 @@ import { useMemo } from 'react' import BigNumber from 'bignumber.js' -import { ZERO, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import type { SwapQuoteResponse, TradeComputed, TradeStrategy } from '../../types' export function useTradeComputed( diff --git a/packages/mask/src/plugins/Trader/trader/balancer/useTradeAmount.ts b/packages/mask/src/plugins/Trader/trader/balancer/useTradeAmount.ts index 98d771916131..b42e7bb5239a 100644 --- a/packages/mask/src/plugins/Trader/trader/balancer/useTradeAmount.ts +++ b/packages/mask/src/plugins/Trader/trader/balancer/useTradeAmount.ts @@ -1,4 +1,4 @@ -import { ZERO } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { useMemo } from 'react' import { ONE_BIPS, SLIPPAGE_DEFAULT } from '../../constants' diff --git a/packages/mask/src/plugins/Trader/trader/balancer/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/balancer/useTradeComputed.ts index c62dab2a44e7..f804607e0ec8 100644 --- a/packages/mask/src/plugins/Trader/trader/balancer/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/balancer/useTradeComputed.ts @@ -1,6 +1,7 @@ import { useMemo } from 'react' import BigNumber from 'bignumber.js' -import { ZERO, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import { SwapResponse, TradeComputed, TradeStrategy } from '../../types' const MIN_VALUE = new BigNumber('1e-5') diff --git a/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts b/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts index 29ff66d16595..f10521eaeb16 100644 --- a/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts +++ b/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts @@ -11,8 +11,8 @@ import { useAsyncRetry } from 'react-use' import { PluginTraderRPC } from '../../messages' import { TradeStrategy } from '../../types' import { useSlippageTolerance } from './useSlippageTolerance' -import BigNumber from 'bignumber.js' import { TargetChainIdContext } from '../useTargetChainIdContext' +import { rightShift } from '@masknet/web3-shared-base' export function useTrade( strategy: TradeStrategy, @@ -28,8 +28,8 @@ export function useTrade( const { BANCOR_ETH_ADDRESS } = useTraderConstants(chainId) const user = useAccount() - const inputAmount = new BigNumber(inputAmountWei).shiftedBy(-(inputToken?.decimals ?? 0)).toFixed() - const outputAmount = new BigNumber(outputAmountWei).shiftedBy(-(outputToken?.decimals ?? 0)).toFixed() + const inputAmount = rightShift(inputAmountWei, inputToken?.decimals ?? 0).toFixed() + const outputAmount = rightShift(outputAmountWei, outputToken?.decimals ?? 0).toFixed() const isExactIn = strategy === TradeStrategy.ExactIn return useAsyncRetry(async () => { diff --git a/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts index 14b59d7a8c9f..24d283c87461 100644 --- a/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts @@ -1,7 +1,6 @@ -import BigNumber from 'bignumber.js' import { useMemo } from 'react' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { ZERO } from '@masknet/web3-shared-evm' +import { leftShift, ZERO } from '@masknet/web3-shared-base' import type { SwapBancorRequest, TradeComputed, TradeStrategy } from '../../types' export function useTradeComputed( @@ -14,9 +13,9 @@ export function useTradeComputed( if (!trade) return null if (!inputToken || !outputToken) return null - const inputAmountWei = new BigNumber(trade.fromAmount || '0').shiftedBy(inputToken.decimals ?? 0) - const outputAmountWei = new BigNumber(trade.toAmount || '0').shiftedBy(outputToken.decimals ?? 0) - const minimumReceivedWei = new BigNumber(trade.minimumReceived).shiftedBy(outputToken.decimals ?? 0) + const inputAmountWei = leftShift(trade.fromAmount || '0', inputToken.decimals) + const outputAmountWei = leftShift(trade.toAmount || '0', outputToken.decimals) + const minimumReceivedWei = leftShift(trade.minimumReceived, outputToken.decimals) const tradeComputed: TradeComputed = { strategy, diff --git a/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts index 4a3d7de06094..8aa0177645fd 100644 --- a/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js' import { useMemo } from 'react' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { ZERO } from '@masknet/web3-shared-evm' +import { leftShift, ZERO } from '@masknet/web3-shared-base' import { SwapRouteData, TradeComputed, TradeStrategy } from '../../types' export function useTradeComputed( @@ -15,9 +15,9 @@ export function useTradeComputed( if (!inputToken || !outputToken) return null const isExactIn = strategy === TradeStrategy.ExactIn if (!isExactIn) return null - const inputAmount = new BigNumber(trade.fromAmount).shiftedBy(inputToken.decimals).integerValue() + const inputAmount = leftShift(trade.fromAmount, inputToken.decimals).integerValue() const executionPrice = new BigNumber(trade.resPricePerToToken) - const outputAmount = new BigNumber(trade.resAmount).shiftedBy(outputToken.decimals).integerValue() + const outputAmount = leftShift(trade.resAmount, outputToken.decimals).integerValue() const priceImpact = new BigNumber(trade.priceImpact) return { strategy, diff --git a/packages/mask/src/plugins/Trader/trader/native/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/native/useTradeComputed.ts index 1fc2767c286c..cae847904236 100644 --- a/packages/mask/src/plugins/Trader/trader/native/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/native/useTradeComputed.ts @@ -1,6 +1,7 @@ import { useMemo } from 'react' import BigNumber from 'bignumber.js' -import { EthereumTokenType, FungibleTokenDetailed, ZERO } from '@masknet/web3-shared-evm' +import { EthereumTokenType, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import { TradeComputed, TradeStrategy } from '../../types' export interface NativeTokenWrapper { diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useTrade.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useTrade.ts index 14d1e4d0682c..e2c0d3a9628f 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useTrade.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useTrade.ts @@ -1,4 +1,5 @@ -import { isZero, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' import { TradeStrategy } from '../../types' import { toUniswapCurrencyAmount, toUniswapCurrency } from '../../helpers' import { useV2BestTradeExactIn, useV2BestTradeExactOut } from './useV2BestTrade' diff --git a/packages/mask/src/plugins/Trader/trader/uniswap/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/uniswap/useTradeComputed.ts index e7c5e4946e28..8d3685f24714 100644 --- a/packages/mask/src/plugins/Trader/trader/uniswap/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/uniswap/useTradeComputed.ts @@ -1,4 +1,5 @@ -import { ZERO, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import { Trade as V2Trade } from '@uniswap/v2-sdk' import { TradeType } from '@uniswap/sdk-core' import { uniswapCurrencyAmountTo, uniswapPercentTo, uniswapPriceTo, uniswapTokenTo } from '../../helpers' diff --git a/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts index f7fac2c18fd9..bb42bb019a60 100644 --- a/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts @@ -1,6 +1,5 @@ import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { pow10 } from '@masknet/web3-shared-evm' -import BigNumber from 'bignumber.js' +import { multipliedBy, pow10 } from '@masknet/web3-shared-base' import { useTrade as useNativeTokenTrade } from './native/useTrade' import { useTradeComputed as useNativeTokenTradeComputed } from './native/useTradeComputed' import { TagType, TradeInfo, TradeStrategy } from '../types' @@ -31,7 +30,9 @@ export function useAllTradeComputed( ): TradeInfo[] { const { targetChainId } = TargetChainIdContext.useContainer() const inputTokenProduct = pow10(inputToken?.decimals ?? 0) - const inputAmount_ = new BigNumber(inputAmount || '0').multipliedBy(inputTokenProduct).integerValue().toFixed() + const inputAmount_ = multipliedBy(inputAmount || '0', inputTokenProduct) + .integerValue() + .toFixed() const { value: tradeProviders = [] } = useAvailableTraderProviders(TagType.CASH, 'MASK', targetChainId) // NATIVE-WNATIVE pair diff --git a/packages/mask/src/plugins/Trader/trader/useTradeApproveComputed.ts b/packages/mask/src/plugins/Trader/trader/useTradeApproveComputed.ts index 6b6af542093f..3a64c6fb201f 100644 --- a/packages/mask/src/plugins/Trader/trader/useTradeApproveComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/useTradeApproveComputed.ts @@ -1,5 +1,6 @@ import { useMemo } from 'react' -import { createERC20Token, EthereumTokenType, FungibleTokenDetailed, ZERO } from '@masknet/web3-shared-evm' +import { createERC20Token, EthereumTokenType, FungibleTokenDetailed } from '@masknet/web3-shared-evm' +import { ZERO } from '@masknet/web3-shared-base' import { TradeProvider } from '@masknet/public-api' import type { SwapQuoteResponse, TradeComputed } from '../types' import { useGetTradeContext } from './useGetTradeContext' diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSetting1559.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSetting1559.tsx index cbbf8e9d0eee..cd269e4043da 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSetting1559.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSetting1559.tsx @@ -15,6 +15,14 @@ import { WalletRPC } from '../../messages' import { useNativeTokenPrice } from '../../hooks/useTokenPrice' import { useGasSettingStyles } from './useGasSettingStyles' import type { GasSettingProps } from './types' +import { + isGreaterThan, + isGreaterThanOrEqualTo, + isLessThan, + isLessThanOrEqualTo, + isPositive, + multipliedBy, +} from '@masknet/web3-shared-base' const HIGH_FEE_WARNING_MULTIPLIER = 1.5 @@ -65,19 +73,16 @@ export const GasSetting1559: FC = memo( .string() .min(1, t('wallet_transfer_error_gas_limit_absence')) .refine( - (gasLimit) => new BigNumber(gasLimit).isGreaterThanOrEqualTo(minGasLimit), + (gasLimit) => isGreaterThanOrEqualTo(gasLimit, minGasLimit), t('popups_wallet_gas_fee_settings_min_gas_limit_tips', { limit: minGasLimit }), ), maxPriorityFeePerGas: zod .string() .min(1, t('wallet_transfer_error_max_priority_fee_absence')) - .refine( - (value) => new BigNumber(value).isPositive(), - t('wallet_transfer_error_max_priority_gas_fee_positive'), - ), + .refine(isPositive, t('wallet_transfer_error_max_priority_gas_fee_positive')), maxFeePerGas: zod.string().min(1, t('wallet_transfer_error_max_fee_absence')), }) - .refine((data) => new BigNumber(data.maxPriorityFeePerGas).isLessThanOrEqualTo(data.maxFeePerGas), { + .refine((data) => isLessThanOrEqualTo(data.maxPriorityFeePerGas, data.maxFeePerGas), { message: t('wallet_transfer_error_max_priority_gas_fee_imbalance'), path: ['maxFeePerGas'], }) @@ -150,13 +155,12 @@ export const GasSetting1559: FC = memo( //#region These are additional form rules that need to be prompted for but do not affect the validation of the form const maxPriorFeeHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxPriorityFeePerGas).isLessThan(gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) + if (isLessThan(maxPriorityFeePerGas, gasOptions?.low?.suggestedMaxPriorityFeePerGas ?? 0)) return t('wallet_transfer_error_max_priority_gas_fee_too_low') if ( - new BigNumber(maxPriorityFeePerGas).isGreaterThan( - new BigNumber(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0).multipliedBy( - HIGH_FEE_WARNING_MULTIPLIER, - ), + isGreaterThan( + maxPriorityFeePerGas, + multipliedBy(gasOptions?.high?.suggestedMaxPriorityFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_priority_gas_fee_too_high') @@ -165,13 +169,12 @@ export const GasSetting1559: FC = memo( const maxFeeGasHelperText = useMemo(() => { if (getGasOptionsLoading) return undefined - if (new BigNumber(maxFeePerGas).isLessThan(gasOptions?.estimatedBaseFee ?? 0)) + if (isLessThan(maxFeePerGas, gasOptions?.estimatedBaseFee ?? 0)) return t('wallet_transfer_error_max_fee_too_low') if ( - new BigNumber(maxFeePerGas).isGreaterThan( - new BigNumber(gasOptions?.high?.suggestedMaxFeePerGas ?? 0).multipliedBy( - HIGH_FEE_WARNING_MULTIPLIER, - ), + isGreaterThan( + maxFeePerGas, + multipliedBy(gasOptions?.high?.suggestedMaxFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_fee_too_high') diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSettingBar.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSettingBar.tsx index f2cd7b176852..1ff59d16f09c 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSettingBar.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/GasSettingDialog/GasSettingBar.tsx @@ -14,6 +14,7 @@ import type { NonPayableTx } from '@masknet/web3-contracts/types/types' import { Box, IconButton, Typography } from '@mui/material' import { WalletMessages } from '../../messages' import { TokenPrice } from '../../../../components/shared/TokenPrice' +import { multipliedBy } from '@masknet/web3-shared-base' export interface GasSettingBarProps { gasLimit: number @@ -72,7 +73,8 @@ export function GasSettingBar(props: GasSettingBarProps) { }, []) const gasFee = useMemo(() => { - return new BigNumber(gasLimit).multipliedBy( + return multipliedBy( + gasLimit, isEIP1559Supported(chainId) && maxFee ? new BigNumber(maxFee) : gasPrice ?? gasPriceDefault, ) }, [chainId, gasLimit, gasPrice, maxFee, gasPriceDefault]) diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/TransactionDescription.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/TransactionDescription.tsx index f79255f4f06c..a1b1dbfb00bd 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/TransactionDescription.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/TransactionDescription.tsx @@ -6,18 +6,19 @@ import { NativeTokenDetailed, ERC20TokenDetailed, FungibleTokenDetailed, - pow10, useERC20TokenDetailed, } from '@masknet/web3-shared-evm' +import { pow10 } from '@masknet/web3-shared-base' import type Services from '../../../../extension/service' import { first, last } from 'lodash-unified' function getTokenAmountDescription(amount = '0', tokenDetailed?: FungibleTokenDetailed, negative?: boolean) { - return `${negative ? '- ' : ''}${ - pow10(9 + (tokenDetailed?.decimals ?? 18)).isGreaterThanOrEqualTo(amount) - ? formatBalance(amount, tokenDetailed?.decimals ?? 0, 4) - : 'infinite' - } ${tokenDetailed?.symbol}`.trim() + const symbol = negative ? '- ' : '' + const value = pow10(9 + (tokenDetailed?.decimals ?? 18)).isGreaterThanOrEqualTo(amount) + ? formatBalance(amount, tokenDetailed?.decimals ?? 0, 4) + : 'infinite' + const token = tokenDetailed?.symbol?.trim() + return `${symbol}${value} ${token}` } function getTransactionDescription( diff --git a/packages/mask/src/plugins/Wallet/services/assets.ts b/packages/mask/src/plugins/Wallet/services/assets.ts index bf92b5ea5a3a..f1f4c6e62e0d 100644 --- a/packages/mask/src/plugins/Wallet/services/assets.ts +++ b/packages/mask/src/plugins/Wallet/services/assets.ts @@ -1,4 +1,5 @@ import { unreachable } from '@dimensiondev/kit' +import { leftShift, multipliedBy, rightShift } from '@masknet/web3-shared-base' import { Asset, ChainId, @@ -172,12 +173,12 @@ function formatAssetsFromDebank(data: WalletTokenRecord[], network?: NetworkType y.symbol, y.logo_url ? [y.logo_url] : undefined, ), - balance: new BigNumber(y.amount).shiftedBy(y.decimals).toFixed(), + balance: leftShift(y.amount, y.decimals).toFixed(), price: { [CurrencyType.USD]: new BigNumber(y.price ?? 0).toFixed(), }, value: { - [CurrencyType.USD]: new BigNumber(y.price ?? 0).multipliedBy(new BigNumber(y.amount)).toFixed(), + [CurrencyType.USD]: multipliedBy(y.price ?? 0, y.amount).toFixed(), }, logoURI: y.logo_url, } @@ -191,7 +192,7 @@ function formatAssetsFromZerion( scope: SocketRequestAssetScope, ) { return data.map(({ asset, quantity }) => { - const balance = new BigNumber(quantity).shiftedBy(-asset.decimals).toNumber() + const balance = rightShift(quantity, asset.decimals).toNumber() const value = (asset as ZerionAsset).price?.value ?? (asset as ZerionCovalentAsset).value ?? 0 const isNativeToken = (symbol: string) => ['ETH', 'BNB', 'MATIC', 'ARETH'].includes(symbol) @@ -211,7 +212,7 @@ function formatAssetsFromZerion( usd: new BigNumber(value).toString(), }, value: { - usd: new BigNumber(balance).multipliedBy(value).toString(), + usd: multipliedBy(balance, value).toString(), }, logoURI: asset.icon_url, } diff --git a/packages/mask/src/plugins/Wallet/services/transactions.ts b/packages/mask/src/plugins/Wallet/services/transactions.ts index 777f26480cfe..205a0cdc791e 100644 --- a/packages/mask/src/plugins/Wallet/services/transactions.ts +++ b/packages/mask/src/plugins/Wallet/services/transactions.ts @@ -1,5 +1,5 @@ +import { multipliedBy, rightShift } from '@masknet/web3-shared-base' import { NetworkType, FungibleAssetProvider } from '@masknet/web3-shared-evm' -import BigNumber from 'bignumber.js' import { isNil } from 'lodash-unified' import * as DeBankAPI from '../apis/debank' import * as ZerionApi from '../apis/zerion' @@ -103,8 +103,8 @@ function fromZerion(data: ZerionTransactionItem[]) { return data .filter(({ type }) => type !== ZerionRBDTransactionType.AUTHORIZE) .map((transaction) => { - const ethGasFee = new BigNumber(transaction.fee?.value ?? 0).shiftedBy(-18).toString() - const usdGasFee = new BigNumber(ethGasFee).multipliedBy(transaction.fee?.price ?? 0).toString() + const ethGasFee = rightShift(transaction.fee?.value ?? 0, -18).toString() + const usdGasFee = multipliedBy(ethGasFee, transaction.fee?.price ?? 0).toString() return { type: transaction.type, @@ -119,7 +119,7 @@ function fromZerion(data: ZerionTransactionItem[]) { symbol: asset.symbol, address: asset.asset_code, direction, - amount: new BigNumber(value).shiftedBy(-asset.decimals).toNumber(), + amount: rightShift(value, asset.decimals).toNumber(), logoURI: asset.icon_url, } }) ?? [], diff --git a/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx b/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx index 603d41300ecf..0fa7c1252bc3 100644 --- a/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx +++ b/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx @@ -2,14 +2,13 @@ import { EthereumTokenType, formatBalance, FungibleTokenDetailed, - isZero, TransactionStateType, useAccount, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' +import { isZero, leftShift } from '@masknet/web3-shared-base' import { DialogContent } from '@mui/material' import { makeStyles } from '@masknet/theme' -import BigNumber from 'bignumber.js' import { useCallback, useEffect, useMemo, useState } from 'react' import { v4 as uuid } from 'uuid' import { InjectedDialog } from '../../../components/shared/InjectedDialog' @@ -103,7 +102,7 @@ export function InvestDialog() { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = new BigNumber(rawAmount || '0').shiftedBy(token?.decimals ?? 0) + const amount = leftShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance, diff --git a/packages/mask/src/plugins/dHEDGE/utils.ts b/packages/mask/src/plugins/dHEDGE/utils.ts index 3ebbcbbf334f..7a94520127ee 100644 --- a/packages/mask/src/plugins/dHEDGE/utils.ts +++ b/packages/mask/src/plugins/dHEDGE/utils.ts @@ -24,7 +24,7 @@ const ONE_TRILLION = ONE_BILLION * 1000 * formatAmountPostfix(20000.123); * // returns 20.1K **/ -export function formatAmountPostfix(input: BigNumber.Value) { +export function formatAmountPostfix(input: BigNumber.Value): string { let postfix = '' let amount = new BigNumber(input) diff --git a/packages/mask/src/web3/UI/EthereumWalletConnectedBoundary.tsx b/packages/mask/src/web3/UI/EthereumWalletConnectedBoundary.tsx index df48d54a9377..8e2c36ac154e 100644 --- a/packages/mask/src/web3/UI/EthereumWalletConnectedBoundary.tsx +++ b/packages/mask/src/web3/UI/EthereumWalletConnectedBoundary.tsx @@ -5,7 +5,8 @@ import { useRemoteControlledDialog } from '@masknet/shared' import ActionButton, { ActionButtonProps } from '../../extension/options-page/DashboardComponents/ActionButton' import { WalletMessages } from '../../plugins/Wallet/messages' import { useI18N } from '../../utils' -import { isZero, useAccount, useChainIdValid, useNativeTokenBalance } from '@masknet/web3-shared-evm' +import { useAccount, useChainIdValid, useNativeTokenBalance } from '@masknet/web3-shared-evm' +import { isZero } from '@masknet/web3-shared-base' import { useWalletRiskWarningDialog } from '../../plugins/Wallet/hooks/useWalletRiskWarningDialog' const useStyles = makeStyles()((theme) => ({ diff --git a/packages/plugins/Flow/src/apis/getFungibleAssets.ts b/packages/plugins/Flow/src/apis/getFungibleAssets.ts index e304e0d13f38..169880bcb313 100644 --- a/packages/plugins/Flow/src/apis/getFungibleAssets.ts +++ b/packages/plugins/Flow/src/apis/getFungibleAssets.ts @@ -1,8 +1,8 @@ -import BigNumber from 'bignumber.js' import { Pagination, Web3Plugin, CurrencyType } from '@masknet/plugin-infra' import { ChainId, createClient, getTokenConstants } from '@masknet/web3-shared-flow' import { getTokenPrice } from '@masknet/web3-providers' import { createFungibleAsset, createFungibleToken } from '../helpers' +import { leftShift } from '@masknet/web3-shared-base' async function getTokenBalance( chainId: ChainId, @@ -39,10 +39,7 @@ async function getTokenBalance( `, args: (arg, t) => [arg(account, t.Address)], }) - return new BigNumber(balance) - .multipliedBy(10 ** decimals) - .integerValue() - .toFixed() + return leftShift(balance, decimals).integerValue().toFixed() } catch { return '0' } diff --git a/packages/plugins/Flow/src/helpers/token.ts b/packages/plugins/Flow/src/helpers/token.ts index fdc88e7dd204..7376855cb2d6 100644 --- a/packages/plugins/Flow/src/helpers/token.ts +++ b/packages/plugins/Flow/src/helpers/token.ts @@ -1,6 +1,6 @@ import { CurrencyType, TokenType, Web3Plugin } from '@masknet/plugin-infra' +import { multipliedBy, rightShift } from '@masknet/web3-shared-base' import type { ChainId } from '@masknet/web3-shared-flow' -import BigNumber from 'bignumber.js' export function createFungibleToken( chainId: ChainId, @@ -29,13 +29,11 @@ export function createFungibleAsset( return { id: token.address, chainId: token.chainId, - balance: new BigNumber(balance).shiftedBy(-8).toFixed(), + balance: rightShift(balance, -8).toFixed(), token, logoURI, value: { - [CurrencyType.USD]: new BigNumber(price?.usd ?? 0) - .multipliedBy(new BigNumber(balance).shiftedBy(-8)) - .toFixed(), + [CurrencyType.USD]: multipliedBy(price?.usd ?? 0, rightShift(balance, -8)).toFixed(), }, price, } diff --git a/packages/web3-shared/base/utils/number.ts b/packages/web3-shared/base/utils/number.ts index 95b1e7ec55af..6f634c05a5f9 100644 --- a/packages/web3-shared/base/utils/number.ts +++ b/packages/web3-shared/base/utils/number.ts @@ -1,6 +1,52 @@ import BigNumber from 'bignumber.js' +export const ZERO = new BigNumber('0') +export const ONE = new BigNumber('1') + +/** n === 0 */ +export function isZero(n: BigNumber.Value) { + return n === 0 || n === '0' || new BigNumber(n).isZero() +} + +/** a > b */ +export function isGreaterThan(a: BigNumber.Value, b: BigNumber.Value) { + return new BigNumber(a).isGreaterThan(b) +} + +/** a >= b */ +export function isGreaterThanOrEqualTo(a: BigNumber.Value, b: BigNumber.Value) { + return new BigNumber(a).isGreaterThanOrEqualTo(b) +} + +/** a < b */ +export function isLessThan(a: BigNumber.Value, b: BigNumber.Value) { + return new BigNumber(a).isLessThan(b) +} + +/** a <= b */ +export function isLessThanOrEqualTo(a: BigNumber.Value, b: BigNumber.Value) { + return new BigNumber(a).isLessThanOrEqualTo(b) +} + +export function isPositive(n: BigNumber.Value) { + return new BigNumber(n).isPositive() +} + +export function multipliedBy(a: BigNumber.Value, b: BigNumber.Value) { + return new BigNumber(a).multipliedBy(b) +} + /** 10 ** n */ -export function pow10(n: BigNumber.Value, m?: BigNumber.Value) { - return new BigNumber(10).pow(n, m) +export function pow10(n: BigNumber.Value) { + return new BigNumber(10).pow(n) +} + +/** n << m */ +export function leftShift(n: BigNumber.Value, m: number | undefined | null) { + return new BigNumber(n).shiftedBy(+(m ?? 0)) +} + +/** n >> m */ +export function rightShift(n: BigNumber.Value, m: number | undefined | null) { + return new BigNumber(n).shiftedBy(-(m ?? 0)) } diff --git a/packages/web3-shared/evm/hooks/useERC20TokenApproveCallback.ts b/packages/web3-shared/evm/hooks/useERC20TokenApproveCallback.ts index eff268f4aa88..4b3b953a692a 100644 --- a/packages/web3-shared/evm/hooks/useERC20TokenApproveCallback.ts +++ b/packages/web3-shared/evm/hooks/useERC20TokenApproveCallback.ts @@ -8,7 +8,7 @@ import { useAccount } from './useAccount' import { useERC20TokenAllowance } from './useERC20TokenAllowance' import { useERC20TokenBalance } from './useERC20TokenBalance' import { useTransactionState } from './useTransactionState' -import { isLessThan } from '../utils' +import { isLessThan } from '@masknet/web3-shared-base' const MaxUint256 = new BigNumber('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff').toFixed() diff --git a/packages/web3-shared/evm/hooks/useERC20TokenTransferCallback.ts b/packages/web3-shared/evm/hooks/useERC20TokenTransferCallback.ts index c5b40e51e030..c58062b44612 100644 --- a/packages/web3-shared/evm/hooks/useERC20TokenTransferCallback.ts +++ b/packages/web3-shared/evm/hooks/useERC20TokenTransferCallback.ts @@ -5,7 +5,7 @@ import { useAccount } from './useAccount' import { useERC20TokenContract } from '../contracts/useERC20TokenContract' import { useTransactionState } from './useTransactionState' import { TransactionStateType, GasConfig, TransactionEventType } from '../types' -import { isGreaterThan, isZero } from '../utils' +import { isGreaterThan, isZero } from '@masknet/web3-shared-base' export function useERC20TokenTransferCallback(address?: string, amount?: string, recipient?: string) { const account = useAccount() diff --git a/packages/web3-shared/evm/hooks/useNativeTokenTransferCallback.ts b/packages/web3-shared/evm/hooks/useNativeTokenTransferCallback.ts index 6ef32f24183b..c2e6e3c6ece7 100644 --- a/packages/web3-shared/evm/hooks/useNativeTokenTransferCallback.ts +++ b/packages/web3-shared/evm/hooks/useNativeTokenTransferCallback.ts @@ -5,7 +5,7 @@ import { useAccount } from './useAccount' import { useChainId } from './useChainId' import { useTransactionState } from './useTransactionState' import { useWeb3 } from './useWeb3' -import { isGreaterThan, isZero } from '../utils' +import { isGreaterThan, isZero } from '@masknet/web3-shared-base' import { TransactionStateType, GasConfig } from '../types' export function useNativeTransferCallback() { diff --git a/packages/web3-shared/evm/hooks/useNativeTokenWrapperCallback.ts b/packages/web3-shared/evm/hooks/useNativeTokenWrapperCallback.ts index 7ae60781360b..522cc4319931 100644 --- a/packages/web3-shared/evm/hooks/useNativeTokenWrapperCallback.ts +++ b/packages/web3-shared/evm/hooks/useNativeTokenWrapperCallback.ts @@ -4,7 +4,7 @@ import { useNativeTokenWrapperContract } from '../contracts/useWrappedEtherContr import { useAccount } from './useAccount' import { useTransactionState } from './useTransactionState' import { ChainId, GasOptionConfig, TransactionStateType, TransactionEventType } from '../types' -import { isLessThan, isZero } from '../utils' +import { isLessThan, isZero } from '@masknet/web3-shared-base' export function useNativeTokenWrapperCallback(chainId?: ChainId) { const account = useAccount() diff --git a/packages/web3-shared/evm/package.json b/packages/web3-shared/evm/package.json index 9de24510dccf..766d1738ad2b 100644 --- a/packages/web3-shared/evm/package.json +++ b/packages/web3-shared/evm/package.json @@ -7,6 +7,7 @@ "@ensdomains/address-encoder": "^0.2.6", "@masknet/web3-constants": "workspace:*", "@masknet/web3-contracts": "workspace:*", + "@masknet/web3-shared-base": "workspace:*", "@types/ethereum-blockies": "^0.1.0", "@types/punycode": "^2.1.0", "@unstoppabledomains/resolution": "^5.0.1", diff --git a/packages/web3-shared/evm/utils/formatter.ts b/packages/web3-shared/evm/utils/formatter.ts index ea69dc66a003..93bdd2d21b4c 100644 --- a/packages/web3-shared/evm/utils/formatter.ts +++ b/packages/web3-shared/evm/utils/formatter.ts @@ -1,11 +1,10 @@ import { BigNumber } from 'bignumber.js' import { EthereumAddress } from 'wallet.ts' -import { pow10 } from './number' +import { multipliedBy, pow10 } from '@masknet/web3-shared-base' import { isValidDomain } from './domain' export function formatPercentage(value: BigNumber.Value) { - const percentage = new BigNumber(value) - .multipliedBy(100) + const percentage = multipliedBy(value, 100) .toFixed(2) .replace(/\.?0+$/, '') return `${percentage}%` @@ -108,17 +107,17 @@ export function formatAmountPrecision( } export function formatWeiToGwei(value: BigNumber.Value) { - return new BigNumber(value).idiv(10 ** 9) + return new BigNumber(value).shiftedBy(-9).integerValue() } export function formatWeiToEther(value: BigNumber.Value) { - return new BigNumber(value).div(new BigNumber(10 ** 18)) + return new BigNumber(value).shiftedBy(-18) } export function formatGweiToWei(value: BigNumber.Value) { - return new BigNumber(value).multipliedBy(10 ** 9) + return new BigNumber(value).shiftedBy(9) } export function formatGweiToEther(value: BigNumber.Value) { - return new BigNumber(value).div(10 ** 9) + return new BigNumber(value).shiftedBy(-9) } diff --git a/packages/web3-shared/evm/utils/index.ts b/packages/web3-shared/evm/utils/index.ts index adee12f8b27c..fd9ec01001b0 100644 --- a/packages/web3-shared/evm/utils/index.ts +++ b/packages/web3-shared/evm/utils/index.ts @@ -3,7 +3,6 @@ export * from './call' export * from './token' export * from './enum' export * from './formatter' -export * from './number' export * from './chainDetailed' export * from './transaction' export * from './domain' diff --git a/packages/web3-shared/evm/utils/number.ts b/packages/web3-shared/evm/utils/number.ts deleted file mode 100644 index afa1a3846679..000000000000 --- a/packages/web3-shared/evm/utils/number.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { BigNumber } from 'bignumber.js' - -export const ZERO = new BigNumber('0') -export const ONE = new BigNumber('1') - -/** value == 0 */ -export function isZero(value: BigNumber.Value) { - return value === 0 || value === '0' || new BigNumber(value).isZero() -} - -/** a > b */ -export function isGreaterThan(a: BigNumber.Value, b: BigNumber.Value) { - return new BigNumber(a).isGreaterThan(b) -} - -/** a < b */ -export function isLessThan(a: BigNumber.Value, b: BigNumber.Value) { - return new BigNumber(a).isLessThan(b) -} - -/** 10 ** n */ -export function pow10(n: BigNumber.Value, m?: BigNumber.Value) { - return new BigNumber(10).pow(n, m) -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 220f073565ea..d8ba547dbce0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -139,6 +139,7 @@ importers: '@masknet/shared-base': workspace:* '@masknet/storybook-shared': workspace:* '@masknet/theme': workspace:* + '@masknet/web3-shared-base': workspace:* '@masknet/web3-shared-evm': workspace:* '@msgpack/msgpack': ^2.7.1 '@servie/events': ^3.0.0 @@ -190,6 +191,7 @@ importers: '@masknet/shared-base': link:../shared-base '@masknet/storybook-shared': link:../storybook-shared '@masknet/theme': link:../theme + '@masknet/web3-shared-base': link:../web3-shared/base '@masknet/web3-shared-evm': link:../web3-shared/evm '@msgpack/msgpack': 2.7.1 '@servie/events': 3.0.0 @@ -302,6 +304,7 @@ importers: '@masknet/shared-base': workspace:* '@masknet/theme': workspace:* '@masknet/web3-contracts': workspace:* + '@masknet/web3-shared-base': workspace:* '@masknet/web3-shared-evm': workspace:* '@msgpack/msgpack': ^2.7.1 '@nice-labs/emit-file-webpack-plugin': ^1.1.2 @@ -439,6 +442,7 @@ importers: '@masknet/shared-base': link:../shared-base '@masknet/theme': link:../theme '@masknet/web3-contracts': link:../web3-contracts + '@masknet/web3-shared-base': link:../web3-shared/base '@masknet/web3-shared-evm': link:../web3-shared/evm '@msgpack/msgpack': 2.7.1 '@servie/events': 3.0.0 @@ -880,6 +884,7 @@ importers: '@ensdomains/address-encoder': ^0.2.6 '@masknet/web3-constants': workspace:* '@masknet/web3-contracts': workspace:* + '@masknet/web3-shared-base': workspace:* '@types/ethereum-blockies': ^0.1.0 '@types/punycode': ^2.1.0 '@types/use-subscription': ^1.0.0 @@ -902,6 +907,7 @@ importers: '@ensdomains/address-encoder': 0.2.6 '@masknet/web3-constants': link:../../web3-constants '@masknet/web3-contracts': link:../../web3-contracts + '@masknet/web3-shared-base': link:../base '@types/ethereum-blockies': 0.1.0 '@types/punycode': 2.1.0 '@unstoppabledomains/resolution': 5.0.1 From fc5ef6e780d0dfa381192574783d9ea4e878808b Mon Sep 17 00:00:00 2001 From: Septs Date: Thu, 9 Dec 2021 13:15:15 +0800 Subject: [PATCH 2/6] fix: typo error --- .../extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx b/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx index e51be1378d31..c4519cd720a4 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/GasSetting/GasSetting1559.tsx @@ -324,7 +324,7 @@ export const GasSetting1559 = memo(() => { if ( isGreaterThan( maxFeePerGas, - new BigNumber(gasOptions?.high?.suggestedMaxFeePerGas ?? 0).multipliedBy(HIGH_FEE_WARNING_MULTIPLIER), + multipliedBy(gasOptions?.high?.suggestedMaxFeePerGas ?? 0, HIGH_FEE_WARNING_MULTIPLIER), ) ) return t('wallet_transfer_error_max_fee_too_high') From e3a77eb0a81d15759d8655e76b0f6d3940d08026 Mon Sep 17 00:00:00 2001 From: Septs Date: Thu, 9 Dec 2021 13:28:06 +0800 Subject: [PATCH 3/6] fix: typo --- .../Wallets/components/Transfer/TransferERC20.tsx | 6 +++--- .../popups/pages/Wallet/ContractInteraction/index.tsx | 4 ++-- .../popups/pages/Wallet/Transfer/Prior1559Transfer.tsx | 10 +++++----- .../popups/pages/Wallet/Transfer/Transfer1559.tsx | 10 +++++----- packages/mask/src/plugins/Collectible/helpers.ts | 3 +-- .../src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx | 4 ++-- .../mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx | 4 ++-- .../mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx | 4 ++-- .../mask/src/plugins/PoolTogether/UI/DepositDialog.tsx | 4 ++-- .../RedPacket/SNSAdaptor/RedPacketERC20Form.tsx | 4 ++-- .../src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx | 4 ++-- .../Trader/apis/bancor/calculateMinimumReturn.ts | 4 ++-- packages/mask/src/plugins/Trader/apis/dodo/index.ts | 4 ++-- .../mask/src/plugins/Trader/trader/bancor/useTrade.ts | 6 +++--- .../plugins/Trader/trader/bancor/useTradeComputed.ts | 8 ++++---- .../src/plugins/Trader/trader/dodo/useTradeComputed.ts | 6 +++--- packages/mask/src/plugins/Wallet/services/assets.ts | 4 ++-- .../mask/src/plugins/Wallet/services/transactions.ts | 6 +++--- packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx | 4 ++-- packages/plugins/Flow/src/apis/getFungibleAssets.ts | 4 ++-- packages/plugins/Flow/src/helpers/token.ts | 6 +++--- packages/web3-shared/base/utils/number.ts | 4 ++-- 22 files changed, 56 insertions(+), 57 deletions(-) diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx index c6f43901004e..0cfb264e6e6c 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx @@ -14,7 +14,7 @@ import { useNativeTokenDetailed, useTokenTransferCallback, } from '@masknet/web3-shared-evm' -import { isGreaterThan, isZero, leftShift, multipliedBy } from '@masknet/web3-shared-base' +import { isGreaterThan, isZero, multipliedBy } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { NetworkPluginID, useLookupAddress, useNetworkDescriptor, useWeb3State } from '@masknet/plugin-infra' import { FormattedAddress, TokenAmountPanel } from '@masknet/shared' @@ -74,7 +74,7 @@ export const TransferERC20 = memo(({ token }) => { //#endregion // transfer amount - const transferAmount = leftShift(amount || '0', selectedToken.decimals).toFixed() + const transferAmount = rightShift(amount || '0', selectedToken.decimals).toFixed() const erc20GasLimit = useGasLimit( selectedToken.type, selectedToken.address, @@ -119,7 +119,7 @@ export const TransferERC20 = memo(({ token }) => { //#region validation const validationMessage = useMemo(() => { if (!transferAmount || isZero(transferAmount)) return t.wallets_transfer_error_amount_absence() - if (isGreaterThan(leftShift(amount, selectedToken.decimals).toFixed(), maxAmount)) + if (isGreaterThan(rightShift(amount, selectedToken.decimals).toFixed(), maxAmount)) return t.wallets_transfer_error_insufficient_balance({ symbol: selectedToken.symbol ?? '' }) if (!address) return t.wallets_transfer_error_address_absence() if (!EthereumAddress.isValid(address)) return t.wallets_transfer_error_invalid_address() diff --git a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx index d5534aadf222..63b74b8cd24e 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx @@ -30,7 +30,7 @@ import { useNativeTokenPrice, useTokenPrice } from '../../../../../plugins/Walle import { LoadingPlaceholder } from '../../../components/LoadingPlaceholder' import { toHex } from 'web3-utils' import { NetworkPluginID, useReverseAddress, useWeb3State } from '@masknet/plugin-infra' -import { isGreaterThan, pow10, rightShift } from '@masknet/web3-shared-base' +import { isGreaterThan, leftShift, pow10 } from '@masknet/web3-shared-base' const useStyles = makeStyles()(() => ({ container: { @@ -282,7 +282,7 @@ const ContractInteraction = memo(() => { // token estimated value const tokenPrice = useTokenPrice(chainId, !isNativeTokenInteraction ? token?.address : undefined) const nativeTokenPrice = useNativeTokenPrice(nativeToken?.chainId) - const tokenValueUSD = rightShift(tokenAmount, tokenDecimals ?? 0) + const tokenValueUSD = leftShift(tokenAmount, tokenDecimals) .times((!isNativeTokenInteraction ? tokenPrice : nativeTokenPrice) ?? 0) .toString() diff --git a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx index 180b9d175adb..4e9a022d4fec 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Prior1559Transfer.tsx @@ -16,7 +16,7 @@ import { useWallet, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isZero, isGreaterThan, isGreaterThanOrEqualTo, leftShift, multipliedBy } from '@masknet/web3-shared-base' +import { isZero, isGreaterThan, isGreaterThanOrEqualTo, multipliedBy, rightShift } from '@masknet/web3-shared-base' import { Controller, FormProvider, useForm, useFormContext } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { useAsync, useAsyncFn, useUpdateEffect } from 'react-use' @@ -154,11 +154,11 @@ export const Prior1559Transfer = memo(({ selectedAsset, amount: zod .string() .refine((amount) => { - const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) + const transferAmount = rightShift(amount || '0', selectedAsset?.token.decimals) return !!transferAmount || !isZero(transferAmount) }, t('wallet_transfer_error_amount_absence')) .refine((amount) => { - const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) + const transferAmount = rightShift(amount || '0', selectedAsset?.token.decimals) return !isGreaterThan(transferAmount, selectedAsset?.balance ?? 0) }, t('wallet_transfer_error_insufficient_balance', { token: selectedAsset?.token.symbol })), gasLimit: zod @@ -205,7 +205,7 @@ export const Prior1559Transfer = memo(({ selectedAsset, const { value: minGasLimit, error } = useGasLimit( selectedAsset?.token.type, selectedAsset?.token.address, - leftShift(!!amount ? amount : 0, selectedAsset?.token.decimals).toFixed(), + rightShift(!!amount ? amount : 0, selectedAsset?.token.decimals).toFixed(), EthereumAddress.isValid(address) ? address : '', ) //#endregion @@ -245,7 +245,7 @@ export const Prior1559Transfer = memo(({ selectedAsset, const [{ loading }, onSubmit] = useAsyncFn( async (data: zod.infer) => { - const transferAmount = leftShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() + const transferAmount = rightShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() await transferCallback(transferAmount, data.address, { gasPrice: toHex(formatGweiToWei(data.gasPrice).toString()), gas: new BigNumber(data.gasLimit).toNumber(), diff --git a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx index aa2385bf18f4..096daa403890 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/Transfer/Transfer1559.tsx @@ -21,8 +21,8 @@ import { isPositive, isLessThan, isLessThanOrEqualTo, - leftShift, multipliedBy, + rightShift, } from '@masknet/web3-shared-base' import { z as zod } from 'zod' import { EthereumAddress } from 'wallet.ts' @@ -197,11 +197,11 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM amount: zod .string() .refine((amount) => { - const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) + const transferAmount = rightShift(amount || '0', selectedAsset?.token.decimals) return !!transferAmount || !isZero(transferAmount) }, t('wallet_transfer_error_amount_absence')) .refine((amount) => { - const transferAmount = leftShift(amount || '0', selectedAsset?.token.decimals) + const transferAmount = rightShift(amount || '0', selectedAsset?.token.decimals) return !isGreaterThan(transferAmount, selectedAsset?.balance ?? 0) }, t('wallet_transfer_error_insufficient_balance', { token: selectedAsset?.token.symbol })), gasLimit: zod @@ -295,7 +295,7 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM const { value: minGasLimit } = useGasLimit( selectedAsset?.token.type, selectedAsset?.token.address, - leftShift(amount ?? 0, selectedAsset?.token.decimals).toFixed(), + rightShift(amount ?? 0, selectedAsset?.token.decimals).toFixed(), EthereumAddress.isValid(address) ? address : registeredAddress, ) //#endregion @@ -344,7 +344,7 @@ export const Transfer1559 = memo(({ selectedAsset, openAssetM const [{ loading }, onSubmit] = useAsyncFn( async (data: zod.infer) => { - const transferAmount = leftShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() + const transferAmount = rightShift(data.amount || '0', selectedAsset?.token.decimals).toFixed() //If input address is ens domain, use registeredAddress to transfer if (Utils?.isValidDomain?.(data.address)) { diff --git a/packages/mask/src/plugins/Collectible/helpers.ts b/packages/mask/src/plugins/Collectible/helpers.ts index 3757077379a2..708d8875e987 100644 --- a/packages/mask/src/plugins/Collectible/helpers.ts +++ b/packages/mask/src/plugins/Collectible/helpers.ts @@ -4,7 +4,6 @@ import { createRenderWithMetadata, createTypedMessageMetadataReader } from '../. import { PLUGIN_META_KEY, RaribleIPFSURL } from './constants' import type { CollectibleJSON_Payload, CollectibleToken } from './types' import schema from './schema.json' -import { rightShift } from '@masknet/web3-shared-base' import type BigNumber from 'bignumber.js' export const CollectibleMetadataReader = createTypedMessageMetadataReader( @@ -32,7 +31,7 @@ export function toTokenIdentifier(token?: CollectibleToken) { } export function toDecimalAmount(weiAmount: BigNumber.Value, decimals: number) { - return rightShift(weiAmount, decimals).toNumber() + return leftShift(weiAmount, decimals).toNumber() } export function toRaribleImage(url?: string) { diff --git a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx index 038211a9134b..6015284bc04e 100644 --- a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx +++ b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/DonateDialog.tsx @@ -27,7 +27,7 @@ import { TokenAmountPanel } from '../../../web3/UI/TokenAmountPanel' import { SelectTokenDialogEvent, WalletMessages } from '../../Wallet/messages' import { useDonateCallback } from '../hooks/useDonateCallback' import { PluginGitcoinMessages } from '../messages' -import { leftShift } from '@masknet/web3-shared-base' +import { rightShift } from '@masknet/web3-shared-base' const useStyles = makeStyles()((theme) => ({ paper: { @@ -112,7 +112,7 @@ export function DonateDialog(props: DonateDialogProps) { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = leftShift(rawAmount || '0', token?.decimals) + const amount = rightShift(rawAmount || '0', token?.decimals) //#endregion //#region blocking diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx index 102540d57404..6da58c08fe9f 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/SwapDialog.tsx @@ -295,12 +295,12 @@ export function SwapDialog(props: SwapDialogProps) { balance={tokenBalance} token={swapToken} onAmountChange={(value) => { - const val = value === '' || value === '0' ? ZERO : leftShift(value, swapToken.decimals) + const val = value === '' || value === '0' ? ZERO : rightShift(value, swapToken.decimals) const isMax = value === formatBalance(maxAmount, swapToken.decimals) && !val.isZero() const tokenAmount = isMax ? maxSwapAmount : val.dividedBy(ratio) const swapAmount = isMax ? tokenAmount.multipliedBy(ratio) : val.dp(0) setInputAmountForUI( - isMax ? rightShift(tokenAmount.multipliedBy(ratio), swapToken.decimals).toString() : value, + isMax ? leftShift(tokenAmount.multipliedBy(ratio), swapToken.decimals).toString() : value, ) setTokenAmount(tokenAmount.dp(0)) setSwapAmount(swapAmount) diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx index 2ee64a0c1c75..7b4dfde4d4ff 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/UnlockDialog.tsx @@ -15,7 +15,7 @@ import { useChainId, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isGreaterThan, leftShift } from '@masknet/web3-shared-base' +import { isGreaterThan, rightShift } from '@masknet/web3-shared-base' import { EthereumERC20TokenApprovedBoundary } from '../../../web3/UI/EthereumERC20TokenApprovedBoundary' import { EthereumWalletConnectedBoundary } from '../../../web3/UI/EthereumWalletConnectedBoundary' import { TokenAmountPanel } from '../../../web3/UI/TokenAmountPanel' @@ -78,7 +78,7 @@ export function UnlockDialog(props: UnlockDialogProps) { //#endregion //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = leftShift(rawAmount || '0', token?.decimals) + const amount = rightShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance } = useFungibleTokenBalance( token?.type ?? EthereumTokenType.Native, token?.address ?? '', diff --git a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx index c1350acab8cf..8dc17c4827b1 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/DepositDialog.tsx @@ -8,7 +8,7 @@ import { ZERO_ADDRESS, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isZero, leftShift } from '@masknet/web3-shared-base' +import { isZero, rightShift } from '@masknet/web3-shared-base' import { DialogContent, Grid, Typography } from '@mui/material' import { keyframes, makeStyles } from '@masknet/theme' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -128,7 +128,7 @@ export function DepositDialog() { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = leftShift(rawAmount || '0', token?.decimals) + const amount = rightShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance, diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx index 04cc3a9309ff..d469009b0a76 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx @@ -8,7 +8,7 @@ import { useRedPacketConstants, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isGreaterThan, isZero, leftShift, multipliedBy } from '@masknet/web3-shared-base' +import { isGreaterThan, isZero, multipliedBy } from '@masknet/web3-shared-base' import { omit } from 'lodash-unified' import { FormControl, InputLabel, MenuItem, MenuProps, Select, TextField } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' @@ -144,7 +144,7 @@ export function RedPacketERC20Form(props: RedPacketFormProps) { ? formatBalance(origin?.total, origin.token?.decimals ?? 0) : formatBalance(new BigNumber(origin?.total ?? '0').div(origin?.shares ?? 1), origin?.token?.decimals ?? 0), ) - const amount = leftShift(rawAmount ?? '0', token?.decimals) + const amount = rightShift(rawAmount ?? '0', token?.decimals) const totalAmount = useMemo(() => multipliedBy(amount, isRandom ? 1 : shares ?? '0'), [amount, shares]) // balance diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx index bd0bb59b24c5..4b594c467eaa 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx @@ -5,7 +5,7 @@ import { InputTokenPanel } from './InputTokenPanel' import { Box, chipClasses, Collapse, IconButton, Tooltip, Typography } from '@mui/material' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' import { EthereumTokenType, formatBalance, formatPercentage } from '@masknet/web3-shared-evm' -import { isLessThan, leftShift } from '@masknet/web3-shared-base' +import { isLessThan, rightShift } from '@masknet/web3-shared-base' import { TokenPanelType, TradeInfo, WarningLevel } from '../../types' import BigNumber from 'bignumber.js' import { first, noop } from 'lodash-unified' @@ -235,7 +235,7 @@ export const TradeForm = memo( //#endregion //#region form controls - const inputTokenTradeAmount = leftShift(inputAmount || '0', inputToken?.decimals) + const inputTokenTradeAmount = rightShift(inputAmount || '0', inputToken?.decimals) //#endregion //#region UI logic diff --git a/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts b/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts index 1216585703ed..7674144e4f0c 100644 --- a/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts +++ b/packages/mask/src/plugins/Trader/apis/bancor/calculateMinimumReturn.ts @@ -12,8 +12,8 @@ export const calculateMinimumReturn = ({ toAmount: string | undefined slippage: number }): string => { - const toWei = leftShift(toAmount || '0', toToken.decimals) + const toWei = rightShift(toAmount || '0', toToken.decimals) const slippageWei = new BigNumber(slippage).dividedBy(BIPS_BASE) const minReturnWei = toWei.times(ONE.minus(slippageWei)) - return rightShift(minReturnWei, -(toToken.decimals ?? 0)).toFixed() + return leftShift(minReturnWei, toToken.decimals).toFixed() } diff --git a/packages/mask/src/plugins/Trader/apis/dodo/index.ts b/packages/mask/src/plugins/Trader/apis/dodo/index.ts index a54ab4bd74ba..caf5b7a8fcd8 100644 --- a/packages/mask/src/plugins/Trader/apis/dodo/index.ts +++ b/packages/mask/src/plugins/Trader/apis/dodo/index.ts @@ -7,7 +7,7 @@ import type { } from '../../types/dodo' import { DODO_BASE_URL } from '../../constants/dodo' import urlcat from 'urlcat' -import { rightShift } from '@masknet/web3-shared-base' +import { leftShift } from '@masknet/web3-shared-base' export async function swapRoute(request: SwapRouteRequest) { const response = await fetch( @@ -31,7 +31,7 @@ export async function swapRoute(request: SwapRouteRequest) { return { ...(payload as SwapRouteSuccessResponse).data, - fromAmount: rightShift(request.fromAmount, request.fromToken.decimals ?? 0).toNumber(), + fromAmount: leftShift(request.fromAmount, request.fromToken.decimals).toNumber(), value: request.isNativeSellToken ? request.fromAmount : '0', slippage: request.slippage, fromTokenSymbol: request.fromToken.symbol, diff --git a/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts b/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts index f10521eaeb16..86d0b9fb8d49 100644 --- a/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts +++ b/packages/mask/src/plugins/Trader/trader/bancor/useTrade.ts @@ -12,7 +12,7 @@ import { PluginTraderRPC } from '../../messages' import { TradeStrategy } from '../../types' import { useSlippageTolerance } from './useSlippageTolerance' import { TargetChainIdContext } from '../useTargetChainIdContext' -import { rightShift } from '@masknet/web3-shared-base' +import { leftShift } from '@masknet/web3-shared-base' export function useTrade( strategy: TradeStrategy, @@ -28,8 +28,8 @@ export function useTrade( const { BANCOR_ETH_ADDRESS } = useTraderConstants(chainId) const user = useAccount() - const inputAmount = rightShift(inputAmountWei, inputToken?.decimals ?? 0).toFixed() - const outputAmount = rightShift(outputAmountWei, outputToken?.decimals ?? 0).toFixed() + const inputAmount = leftShift(inputAmountWei, inputToken?.decimals).toFixed() + const outputAmount = leftShift(outputAmountWei, outputToken?.decimals).toFixed() const isExactIn = strategy === TradeStrategy.ExactIn return useAsyncRetry(async () => { diff --git a/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts index 24d283c87461..1364e5ec4fd7 100644 --- a/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/bancor/useTradeComputed.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { leftShift, ZERO } from '@masknet/web3-shared-base' +import { rightShift, ZERO } from '@masknet/web3-shared-base' import type { SwapBancorRequest, TradeComputed, TradeStrategy } from '../../types' export function useTradeComputed( @@ -13,9 +13,9 @@ export function useTradeComputed( if (!trade) return null if (!inputToken || !outputToken) return null - const inputAmountWei = leftShift(trade.fromAmount || '0', inputToken.decimals) - const outputAmountWei = leftShift(trade.toAmount || '0', outputToken.decimals) - const minimumReceivedWei = leftShift(trade.minimumReceived, outputToken.decimals) + const inputAmountWei = rightShift(trade.fromAmount || '0', inputToken.decimals) + const outputAmountWei = rightShift(trade.toAmount || '0', outputToken.decimals) + const minimumReceivedWei = rightShift(trade.minimumReceived, outputToken.decimals) const tradeComputed: TradeComputed = { strategy, diff --git a/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts index 8aa0177645fd..28cceab06655 100644 --- a/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/dodo/useTradeComputed.ts @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js' import { useMemo } from 'react' import type { FungibleTokenDetailed } from '@masknet/web3-shared-evm' -import { leftShift, ZERO } from '@masknet/web3-shared-base' +import { rightShift, ZERO } from '@masknet/web3-shared-base' import { SwapRouteData, TradeComputed, TradeStrategy } from '../../types' export function useTradeComputed( @@ -15,9 +15,9 @@ export function useTradeComputed( if (!inputToken || !outputToken) return null const isExactIn = strategy === TradeStrategy.ExactIn if (!isExactIn) return null - const inputAmount = leftShift(trade.fromAmount, inputToken.decimals).integerValue() + const inputAmount = rightShift(trade.fromAmount, inputToken.decimals).integerValue() const executionPrice = new BigNumber(trade.resPricePerToToken) - const outputAmount = leftShift(trade.resAmount, outputToken.decimals).integerValue() + const outputAmount = rightShift(trade.resAmount, outputToken.decimals).integerValue() const priceImpact = new BigNumber(trade.priceImpact) return { strategy, diff --git a/packages/mask/src/plugins/Wallet/services/assets.ts b/packages/mask/src/plugins/Wallet/services/assets.ts index f1f4c6e62e0d..40787f8e1163 100644 --- a/packages/mask/src/plugins/Wallet/services/assets.ts +++ b/packages/mask/src/plugins/Wallet/services/assets.ts @@ -173,7 +173,7 @@ function formatAssetsFromDebank(data: WalletTokenRecord[], network?: NetworkType y.symbol, y.logo_url ? [y.logo_url] : undefined, ), - balance: leftShift(y.amount, y.decimals).toFixed(), + balance: rightShift(y.amount, y.decimals).toFixed(), price: { [CurrencyType.USD]: new BigNumber(y.price ?? 0).toFixed(), }, @@ -192,7 +192,7 @@ function formatAssetsFromZerion( scope: SocketRequestAssetScope, ) { return data.map(({ asset, quantity }) => { - const balance = rightShift(quantity, asset.decimals).toNumber() + const balance = leftShift(quantity, asset.decimals).toNumber() const value = (asset as ZerionAsset).price?.value ?? (asset as ZerionCovalentAsset).value ?? 0 const isNativeToken = (symbol: string) => ['ETH', 'BNB', 'MATIC', 'ARETH'].includes(symbol) diff --git a/packages/mask/src/plugins/Wallet/services/transactions.ts b/packages/mask/src/plugins/Wallet/services/transactions.ts index 205a0cdc791e..1f5ded904a8e 100644 --- a/packages/mask/src/plugins/Wallet/services/transactions.ts +++ b/packages/mask/src/plugins/Wallet/services/transactions.ts @@ -1,4 +1,4 @@ -import { multipliedBy, rightShift } from '@masknet/web3-shared-base' +import { leftShift, multipliedBy } from '@masknet/web3-shared-base' import { NetworkType, FungibleAssetProvider } from '@masknet/web3-shared-evm' import { isNil } from 'lodash-unified' import * as DeBankAPI from '../apis/debank' @@ -103,7 +103,7 @@ function fromZerion(data: ZerionTransactionItem[]) { return data .filter(({ type }) => type !== ZerionRBDTransactionType.AUTHORIZE) .map((transaction) => { - const ethGasFee = rightShift(transaction.fee?.value ?? 0, -18).toString() + const ethGasFee = leftShift(transaction.fee?.value ?? 0, 18).toString() const usdGasFee = multipliedBy(ethGasFee, transaction.fee?.price ?? 0).toString() return { @@ -119,7 +119,7 @@ function fromZerion(data: ZerionTransactionItem[]) { symbol: asset.symbol, address: asset.asset_code, direction, - amount: rightShift(value, asset.decimals).toNumber(), + amount: leftShift(value, asset.decimals).toNumber(), logoURI: asset.icon_url, } }) ?? [], diff --git a/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx b/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx index 0fa7c1252bc3..06317ba0afbb 100644 --- a/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx +++ b/packages/mask/src/plugins/dHEDGE/UI/InvestDialog.tsx @@ -6,7 +6,7 @@ import { useAccount, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isZero, leftShift } from '@masknet/web3-shared-base' +import { isZero, rightShift } from '@masknet/web3-shared-base' import { DialogContent } from '@mui/material' import { makeStyles } from '@masknet/theme' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -102,7 +102,7 @@ export function InvestDialog() { //#region amount const [rawAmount, setRawAmount] = useState('') - const amount = leftShift(rawAmount || '0', token?.decimals) + const amount = rightShift(rawAmount || '0', token?.decimals) const { value: tokenBalance = '0', loading: loadingTokenBalance, diff --git a/packages/plugins/Flow/src/apis/getFungibleAssets.ts b/packages/plugins/Flow/src/apis/getFungibleAssets.ts index 169880bcb313..d9f58c984f9b 100644 --- a/packages/plugins/Flow/src/apis/getFungibleAssets.ts +++ b/packages/plugins/Flow/src/apis/getFungibleAssets.ts @@ -2,7 +2,7 @@ import { Pagination, Web3Plugin, CurrencyType } from '@masknet/plugin-infra' import { ChainId, createClient, getTokenConstants } from '@masknet/web3-shared-flow' import { getTokenPrice } from '@masknet/web3-providers' import { createFungibleAsset, createFungibleToken } from '../helpers' -import { leftShift } from '@masknet/web3-shared-base' +import { rightShift } from '@masknet/web3-shared-base' async function getTokenBalance( chainId: ChainId, @@ -39,7 +39,7 @@ async function getTokenBalance( `, args: (arg, t) => [arg(account, t.Address)], }) - return leftShift(balance, decimals).integerValue().toFixed() + return rightShift(balance, decimals).integerValue().toFixed() } catch { return '0' } diff --git a/packages/plugins/Flow/src/helpers/token.ts b/packages/plugins/Flow/src/helpers/token.ts index 7376855cb2d6..a3c843d0ac83 100644 --- a/packages/plugins/Flow/src/helpers/token.ts +++ b/packages/plugins/Flow/src/helpers/token.ts @@ -1,5 +1,5 @@ import { CurrencyType, TokenType, Web3Plugin } from '@masknet/plugin-infra' -import { multipliedBy, rightShift } from '@masknet/web3-shared-base' +import { leftShift, multipliedBy } from '@masknet/web3-shared-base' import type { ChainId } from '@masknet/web3-shared-flow' export function createFungibleToken( @@ -29,11 +29,11 @@ export function createFungibleAsset( return { id: token.address, chainId: token.chainId, - balance: rightShift(balance, -8).toFixed(), + balance: leftShift(balance, 8).toFixed(), token, logoURI, value: { - [CurrencyType.USD]: multipliedBy(price?.usd ?? 0, rightShift(balance, -8)).toFixed(), + [CurrencyType.USD]: multipliedBy(price?.usd ?? 0, leftShift(balance, 8)).toFixed(), }, price, } diff --git a/packages/web3-shared/base/utils/number.ts b/packages/web3-shared/base/utils/number.ts index 6f634c05a5f9..a3e49cd37f49 100644 --- a/packages/web3-shared/base/utils/number.ts +++ b/packages/web3-shared/base/utils/number.ts @@ -42,11 +42,11 @@ export function pow10(n: BigNumber.Value) { } /** n << m */ -export function leftShift(n: BigNumber.Value, m: number | undefined | null) { +export function rightShift(n: BigNumber.Value, m: number | undefined | null) { return new BigNumber(n).shiftedBy(+(m ?? 0)) } /** n >> m */ -export function rightShift(n: BigNumber.Value, m: number | undefined | null) { +export function leftShift(n: BigNumber.Value, m: number | undefined | null) { return new BigNumber(n).shiftedBy(-(m ?? 0)) } From d6b71d09d182bdafd801042118d87bd296adb271 Mon Sep 17 00:00:00 2001 From: Septs Date: Thu, 9 Dec 2021 13:51:48 +0800 Subject: [PATCH 4/6] fix: typo --- packages/mask/src/plugins/Collectible/helpers.ts | 1 + .../src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/mask/src/plugins/Collectible/helpers.ts b/packages/mask/src/plugins/Collectible/helpers.ts index 708d8875e987..defb4254c2f2 100644 --- a/packages/mask/src/plugins/Collectible/helpers.ts +++ b/packages/mask/src/plugins/Collectible/helpers.ts @@ -5,6 +5,7 @@ import { PLUGIN_META_KEY, RaribleIPFSURL } from './constants' import type { CollectibleJSON_Payload, CollectibleToken } from './types' import schema from './schema.json' import type BigNumber from 'bignumber.js' +import { leftShift } from '@masknet/web3-shared-base' export const CollectibleMetadataReader = createTypedMessageMetadataReader( PLUGIN_META_KEY, diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx index d469009b0a76..8192bb833c0c 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC20Form.tsx @@ -8,7 +8,7 @@ import { useRedPacketConstants, useFungibleTokenBalance, } from '@masknet/web3-shared-evm' -import { isGreaterThan, isZero, multipliedBy } from '@masknet/web3-shared-base' +import { isGreaterThan, isZero, multipliedBy, rightShift } from '@masknet/web3-shared-base' import { omit } from 'lodash-unified' import { FormControl, InputLabel, MenuItem, MenuProps, Select, TextField } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' From 00fb717dc1042772c3f8bcf34be52ee8fd937eb2 Mon Sep 17 00:00:00 2001 From: Septs Date: Fri, 10 Dec 2021 09:41:04 +0800 Subject: [PATCH 5/6] fix: build failed --- .../src/pages/Wallets/components/Transfer/TransferERC20.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx index 0cfb264e6e6c..e75bf749d057 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/TransferERC20.tsx @@ -14,7 +14,7 @@ import { useNativeTokenDetailed, useTokenTransferCallback, } from '@masknet/web3-shared-evm' -import { isGreaterThan, isZero, multipliedBy } from '@masknet/web3-shared-base' +import { isGreaterThan, isZero, multipliedBy, rightShift } from '@masknet/web3-shared-base' import BigNumber from 'bignumber.js' import { NetworkPluginID, useLookupAddress, useNetworkDescriptor, useWeb3State } from '@masknet/plugin-infra' import { FormattedAddress, TokenAmountPanel } from '@masknet/shared' @@ -119,7 +119,7 @@ export const TransferERC20 = memo(({ token }) => { //#region validation const validationMessage = useMemo(() => { if (!transferAmount || isZero(transferAmount)) return t.wallets_transfer_error_amount_absence() - if (isGreaterThan(rightShift(amount, selectedToken.decimals).toFixed(), maxAmount)) + if (isGreaterThan(rightShift(amount, selectedToken.decimals), maxAmount)) return t.wallets_transfer_error_insufficient_balance({ symbol: selectedToken.symbol ?? '' }) if (!address) return t.wallets_transfer_error_address_absence() if (!EthereumAddress.isValid(address)) return t.wallets_transfer_error_invalid_address() From 38e1f8fd9f9b09bf5aa9c4b63a3ec90ad4ca83d6 Mon Sep 17 00:00:00 2001 From: Septs Date: Fri, 10 Dec 2021 14:13:51 +0800 Subject: [PATCH 6/6] chore: update comments --- packages/web3-shared/base/utils/number.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/web3-shared/base/utils/number.ts b/packages/web3-shared/base/utils/number.ts index a3e49cd37f49..acd76a62fdf1 100644 --- a/packages/web3-shared/base/utils/number.ts +++ b/packages/web3-shared/base/utils/number.ts @@ -28,10 +28,12 @@ export function isLessThanOrEqualTo(a: BigNumber.Value, b: BigNumber.Value) { return new BigNumber(a).isLessThanOrEqualTo(b) } +/** a > 0 */ export function isPositive(n: BigNumber.Value) { return new BigNumber(n).isPositive() } +/** a * b */ export function multipliedBy(a: BigNumber.Value, b: BigNumber.Value) { return new BigNumber(a).multipliedBy(b) } @@ -41,12 +43,12 @@ export function pow10(n: BigNumber.Value) { return new BigNumber(10).pow(n) } -/** n << m */ +/** n * (10 ** m) */ export function rightShift(n: BigNumber.Value, m: number | undefined | null) { return new BigNumber(n).shiftedBy(+(m ?? 0)) } -/** n >> m */ +/** n / (10 ** m) */ export function leftShift(n: BigNumber.Value, m: number | undefined | null) { return new BigNumber(n).shiftedBy(-(m ?? 0)) }