@ape.swap/bonds-sdk 6.2.1 → 6.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/MenuSelect/MenuSelect.d.ts +1 -1
- package/dist/components/MenuSelect/MenuSelect.js.map +1 -1
- package/dist/components/ProgressBar/ProgressBarWrapper.d.ts +1 -1
- package/dist/components/ProgressBar/ProgressBarWrapper.js.map +1 -1
- package/dist/components/TokenInfoAndName/index.d.ts +0 -1
- package/dist/components/TokenInfoAndName/index.js +1 -1
- package/dist/components/TokenInfoAndName/index.js.map +1 -1
- package/dist/components/TokenSelectorModal/TokenRow.js +2 -2
- package/dist/components/TokenSelectorModal/TokenRow.js.map +1 -1
- package/dist/components/TokenSelectorPanel/index.js +3 -3
- package/dist/components/TokenSelectorPanel/index.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/uikit-sdk/Button/Button.js +0 -36
- package/dist/components/uikit-sdk/Button/Button.js.map +1 -1
- package/dist/components/uikit-sdk/Button/types.d.ts +6 -10
- package/dist/components/uikit-sdk/Button/types.js +0 -5
- package/dist/components/uikit-sdk/Button/types.js.map +1 -1
- package/dist/components/uikit-sdk/Checkbox/types.d.ts +2 -1
- package/dist/components/uikit-sdk/Checkbox/types.js.map +1 -1
- package/dist/components/uikit-sdk/Skeleton/styles.d.ts +0 -12
- package/dist/components/uikit-sdk/Skeleton/styles.js +1 -1
- package/dist/components/uikit-sdk/Skeleton/styles.js.map +1 -1
- package/dist/components/uikit-sdk/Svg/Icons/ZapIcon.d.ts +2 -2
- package/dist/components/uikit-sdk/Svg/styles.d.ts +0 -2
- package/dist/components/uikit-sdk/Svg/styles.js.map +1 -1
- package/dist/components/uikit-sdk/Text/types.d.ts +1 -1
- package/dist/components/uikit-sdk/Text/types.js +1 -1
- package/dist/components/uikit-sdk/Text/types.js.map +1 -1
- package/dist/components/uikit-sdk/TooltipBubble/types.d.ts +2 -1
- package/dist/components/uikit-sdk/TooltipBubble/types.js.map +1 -1
- package/dist/config/constants/aptosZapTokens.d.ts +0 -9
- package/dist/config/constants/aptosZapTokens.js +1 -2
- package/dist/config/constants/aptosZapTokens.js.map +1 -1
- package/dist/config/constants/networks.d.ts +0 -2
- package/dist/config/constants/networks.js +1 -1
- package/dist/config/constants/networks.js.map +1 -1
- package/dist/config/constants/tokens.d.ts +1 -2
- package/dist/constants/aptosConstants.d.ts +0 -6
- package/dist/constants/aptosConstants.js +15 -1
- package/dist/constants/aptosConstants.js.map +1 -1
- package/dist/constants/solanaConstants.d.ts +0 -6
- package/dist/constants/solanaConstants.js +0 -21
- package/dist/constants/solanaConstants.js.map +1 -1
- package/dist/constants/suiConstants.d.ts +0 -5
- package/dist/constants/suiConstants.js +11 -0
- package/dist/constants/suiConstants.js.map +1 -1
- package/dist/hooks/useSortedZapList.d.ts +1 -1
- package/dist/hooks/useSortedZapList.js +1 -2
- package/dist/hooks/useSortedZapList.js.map +1 -1
- package/dist/hooks/useTokenFromZapList.js +0 -1
- package/dist/hooks/useTokenFromZapList.js.map +1 -1
- package/dist/providers/index.d.ts +11 -0
- package/dist/providers/index.js +0 -6
- package/dist/providers/index.js.map +1 -1
- package/dist/state/allowance/useAllowance.js +2 -3
- package/dist/state/allowance/useAllowance.js.map +1 -1
- package/dist/state/balance/useCurrencyBalance.js +2 -3
- package/dist/state/balance/useCurrencyBalance.js.map +1 -1
- package/dist/state/balance/useCurrencyBalanceAptos.js +5 -5
- package/dist/state/balance/useCurrencyBalanceAptos.js.map +1 -1
- package/dist/state/balance/useCurrencyBalanceSolana.d.ts +0 -2
- package/dist/state/balance/useCurrencyBalanceSolana.js +3 -6
- package/dist/state/balance/useCurrencyBalanceSolana.js.map +1 -1
- package/dist/state/balance/useCurrencyBalanceSui.js +2 -2
- package/dist/state/balance/useCurrencyBalanceSui.js.map +1 -1
- package/dist/state/balance/useUserTokensBalance.js +3 -5
- package/dist/state/balance/useUserTokensBalance.js.map +1 -1
- package/dist/state/bondApiStats/useGetBondApiStats.d.ts +0 -1
- package/dist/state/bondApiStats/useGetBondApiStats.js +1 -1
- package/dist/state/bondApiStats/useGetBondApiStats.js.map +1 -1
- package/dist/state/bonds/fetchBondsData/cleanBillsData.js +16 -13
- package/dist/state/bonds/fetchBondsData/cleanBillsData.js.map +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.d.ts +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.js +4 -6
- package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.js.map +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.d.ts +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.js +4 -3
- package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.js.map +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.d.ts +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.js +2 -3
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.js.map +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.d.ts +1 -1
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.js +5 -7
- package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.js.map +1 -1
- package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.d.ts +1 -2
- package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.js +2 -5
- package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.js.map +1 -1
- package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsSOL.js +2 -5
- package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsSOL.js.map +1 -1
- package/dist/state/bonds/useBondsList.d.ts +1 -2
- package/dist/state/bonds/useBondsList.js +1 -1
- package/dist/state/bonds/useBondsList.js.map +1 -1
- package/dist/state/bonds/useBondsListPreTGE.d.ts +1 -2
- package/dist/state/bonds/useBondsListPreTGE.js +1 -1
- package/dist/state/bonds/useBondsListPreTGE.js.map +1 -1
- package/dist/state/bonds/useTierProofSignature.d.ts +0 -1
- package/dist/state/bonds/useTierProofSignature.js +1 -1
- package/dist/state/bonds/useTierProofSignature.js.map +1 -1
- package/dist/state/bonds/useUserBondsPreTGE.d.ts +3 -4
- package/dist/state/bonds/useUserBondsPreTGE.js +4 -7
- package/dist/state/bonds/useUserBondsPreTGE.js.map +1 -1
- package/dist/state/historicalPrice/useHistoricalPrice.d.ts +1 -2
- package/dist/state/historicalPrice/useHistoricalPrice.js +1 -1
- package/dist/state/historicalPrice/useHistoricalPrice.js.map +1 -1
- package/dist/state/hotBonds/useHotBonds.d.ts +0 -2
- package/dist/state/hotBonds/useHotBonds.js +1 -1
- package/dist/state/hotBonds/useHotBonds.js.map +1 -1
- package/dist/state/price/useCurrencyPrice.js +1 -2
- package/dist/state/price/useCurrencyPrice.js.map +1 -1
- package/dist/state/recommendations/useGetBondRecommendations.d.ts +0 -1
- package/dist/state/recommendations/useGetBondRecommendations.js +1 -1
- package/dist/state/recommendations/useGetBondRecommendations.js.map +1 -1
- package/dist/state/tiers/useTierPoints.d.ts +0 -6
- package/dist/state/tiers/useTierPoints.js +16 -17
- package/dist/state/tiers/useTierPoints.js.map +1 -1
- package/dist/state/zap/useAptosZapQuote.d.ts +1 -16
- package/dist/state/zap/useAptosZapQuote.js +4 -4
- package/dist/state/zap/useAptosZapQuote.js.map +1 -1
- package/dist/state/zap/useJupiterSolanaQuote.js +4 -11
- package/dist/state/zap/useJupiterSolanaQuote.js.map +1 -1
- package/dist/state/zap/useSoulZapBondQuote.js +12 -21
- package/dist/state/zap/useSoulZapBondQuote.js.map +1 -1
- package/dist/state/zap/useSuiZapQuote.d.ts +1 -1
- package/dist/state/zap/useSuiZapQuote.js +9 -14
- package/dist/state/zap/useSuiZapQuote.js.map +1 -1
- package/dist/theme/base.d.ts +1 -4
- package/dist/theme/base.js +1 -1
- package/dist/theme/base.js.map +1 -1
- package/dist/theme/components.d.ts +0 -20
- package/dist/theme/components.js +1 -1
- package/dist/theme/components.js.map +1 -1
- package/dist/types/aptosBonds.d.ts +0 -60
- package/dist/types/bondIssuanceCodec.d.ts +0 -1
- package/dist/types/bondIssuanceCodec.js.map +1 -1
- package/dist/types/bondTermCodec.d.ts +0 -1
- package/dist/types/bondTermCodec.js.map +1 -1
- package/dist/types/solanaBonds.d.ts +4 -3
- package/dist/utils/aptosHelpers.d.ts +1 -14
- package/dist/utils/aptosHelpers.js +30 -2
- package/dist/utils/aptosHelpers.js.map +1 -1
- package/dist/utils/bondPriceHelpers.d.ts +1 -1
- package/dist/utils/bondPriceHelpers.js +5 -11
- package/dist/utils/bondPriceHelpers.js.map +1 -1
- package/dist/utils/calculateSolanaTrueBillPrice.d.ts +0 -4
- package/dist/utils/calculateSolanaTrueBillPrice.js +33 -32
- package/dist/utils/calculateSolanaTrueBillPrice.js.map +1 -1
- package/dist/utils/convertToBigish.d.ts +0 -1
- package/dist/utils/convertToBigish.js +3 -18
- package/dist/utils/convertToBigish.js.map +1 -1
- package/dist/utils/displayHelpers.d.ts +3 -9
- package/dist/utils/displayHelpers.js +63 -47
- package/dist/utils/displayHelpers.js.map +1 -1
- package/dist/utils/fixedPoint.d.ts +28 -0
- package/dist/utils/fixedPoint.js +239 -0
- package/dist/utils/fixedPoint.js.map +1 -0
- package/dist/utils/formatNumber.d.ts +0 -7
- package/dist/utils/formatNumber.js +6 -12
- package/dist/utils/formatNumber.js.map +1 -1
- package/dist/utils/getBalanceNumber.d.ts +1 -2
- package/dist/utils/getBalanceNumber.js +5 -3
- package/dist/utils/getBalanceNumber.js.map +1 -1
- package/dist/utils/getNativeTicker.js +0 -1
- package/dist/utils/getNativeTicker.js.map +1 -1
- package/dist/utils/suiHelpers.d.ts +0 -2
- package/dist/utils/suiHelpers.js +13 -15
- package/dist/utils/suiHelpers.js.map +1 -1
- package/dist/views/Bonds/Bonds.d.ts +0 -4
- package/dist/views/Bonds/Bonds.js.map +1 -1
- package/dist/views/Bonds/components/BondRows/ActiveBondRows.d.ts +1 -1
- package/dist/views/Bonds/components/BondRows/ActiveBondRows.js +2 -3
- package/dist/views/Bonds/components/BondRows/ActiveBondRows.js.map +1 -1
- package/dist/views/Bonds/components/BonusComponents/BonusComponent.js +1 -2
- package/dist/views/Bonds/components/BonusComponents/BonusComponent.js.map +1 -1
- package/dist/views/Bonds/components/BonusComponents/BonusTable.js +1 -2
- package/dist/views/Bonds/components/BonusComponents/BonusTable.js.map +1 -1
- package/dist/views/Bonds/components/BuyAgainRow/index.js +2 -4
- package/dist/views/Bonds/components/BuyAgainRow/index.js.map +1 -1
- package/dist/views/Bonds/components/RecommendationCards/SmallRecommendationCard.d.ts +1 -1
- package/dist/views/Bonds/components/RecommendationCards/SmallRecommendationCard.js.map +1 -1
- package/dist/views/Bonds/utils.d.ts +0 -2
- package/dist/views/Bonds/utils.js +2 -3
- package/dist/views/Bonds/utils.js.map +1 -1
- package/dist/views/BuyBond/BuyBondModal.d.ts +1 -1
- package/dist/views/BuyBond/BuyBondModal.js.map +1 -1
- package/dist/views/BuyBond/BuyComponent.js +16 -17
- package/dist/views/BuyBond/BuyComponent.js.map +1 -1
- package/dist/views/BuyBond/BuyComponentAptos.d.ts +1 -1
- package/dist/views/BuyBond/BuyComponentAptos.js +20 -33
- package/dist/views/BuyBond/BuyComponentAptos.js.map +1 -1
- package/dist/views/BuyBond/BuyComponentPreTGE.js +6 -8
- package/dist/views/BuyBond/BuyComponentPreTGE.js.map +1 -1
- package/dist/views/BuyBond/BuyComponentSolana.d.ts +1 -1
- package/dist/views/BuyBond/BuyComponentSolana.js +20 -27
- package/dist/views/BuyBond/BuyComponentSolana.js.map +1 -1
- package/dist/views/BuyBond/BuyComponentSui.d.ts +1 -1
- package/dist/views/BuyBond/BuyComponentSui.js +15 -28
- package/dist/views/BuyBond/BuyComponentSui.js.map +1 -1
- package/dist/views/BuyBond/components/NewRateModal/NewRateModal.js +2 -2
- package/dist/views/BuyBond/components/NewRateModal/NewRateModal.js.map +1 -1
- package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js +6 -9
- package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js.map +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/SalesTable.d.ts +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/SalesTable.js.map +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/TopSaleCard.d.ts +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/TopSaleCard.js.map +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/TopThreeSalesCards.d.ts +1 -1
- package/dist/views/ProjectView/components/BondLeaderboard/components/TopThreeSalesCards.js.map +1 -1
- package/dist/views/ProjectView/components/BondStats/index.js +2 -4
- package/dist/views/ProjectView/components/BondStats/index.js.map +1 -1
- package/dist/views/ProjectView/components/BondStats/types.d.ts +2 -1
- package/dist/views/ProjectView/components/BondStats/types.js.map +1 -1
- package/dist/views/SingleBond/SoldOutBuyBondPlaceholder.d.ts +1 -1
- package/dist/views/SingleBond/SoldOutBuyBondPlaceholder.js.map +1 -1
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowPreTGE.js +4 -5
- package/dist/views/YourBonds/components/UserBondRow/UserBondRowPreTGE.js.map +1 -1
- package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.d.ts +8 -0
- package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.js +43 -0
- package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.js.map +1 -0
- package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.d.ts +8 -1
- package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.js +172 -15
- package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.js.map +1 -1
- package/dist/views/YourBondsModal/components/LinkShare/utils.js +19 -10
- package/dist/views/YourBondsModal/components/LinkShare/utils.js.map +1 -1
- package/dist/views/YourBondsModal/components/TransferBondModal/index.js +1 -2
- package/dist/views/YourBondsModal/components/TransferBondModal/index.js.map +1 -1
- package/package.json +6 -8
- package/dist/components/AccordionText/index.d.ts +0 -6
- package/dist/components/RestrictedRegionModal/index.d.ts +0 -5
- package/dist/components/TabNavigation/index.d.ts +0 -8
- package/dist/components/uikit-sdk/Input/NumericInput.d.ts +0 -9
- package/dist/components/uikit-sdk/Modal/ModalFooter.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Audit.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Fire.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/FullLogo.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Instagram.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Language.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Medium.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Pool.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Reddit.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Telegram.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/Icons/Website.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/BSC.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/CELO.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/CRONOS.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/FANTOM.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/GNOSIS.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/OKX.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/OPTIMISM.d.ts +0 -4
- package/dist/components/uikit-sdk/Svg/tokens/POLYGONZK.d.ts +0 -4
- package/dist/config/constants/tokens.js +0 -36
- package/dist/config/constants/tokens.js.map +0 -1
- package/dist/contexts/RefreshContext.d.ts +0 -10
- package/dist/hooks/useRefresh.d.ts +0 -6
- package/dist/hooks/useTimer.d.ts +0 -2
- package/dist/state/bondApiStats/useUserApiStats.d.ts +0 -22
- package/dist/state/bonds/aptosBondsConfig.d.ts +0 -4
- package/dist/state/bonds/fetchUsersBonds/getBillNftData.d.ts +0 -9
- package/dist/state/geoFencing/useGeoFencing.d.ts +0 -5
- package/dist/state/zap/useSoulZapTokenQuote.d.ts +0 -3
- package/dist/state/zap/useTierOptimizationPreview.d.ts +0 -27
- package/dist/views/ZapModal/index.d.ts +0 -13
- package/dist/views/ZapModal/styles.d.ts +0 -2
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BigNumber } from 'bignumber.js';
|
|
2
1
|
import { getBalanceNumber } from './getBalanceNumber.js';
|
|
3
2
|
import { getFirstNonZeroDigits } from './roundNumber.js';
|
|
4
3
|
import { getTimePeriods } from './getTimePeriods.js';
|
|
@@ -6,9 +5,15 @@ import { formatNumberSI } from './formatNumber.js';
|
|
|
6
5
|
import { LaunchBondTiers } from '@ape.swap/apeswap-lists';
|
|
7
6
|
import { TIERS_WEIGHT } from '../state/tiers/useTierPoints.js';
|
|
8
7
|
import { findHighestTrueBondPrice } from './bondPriceHelpers.js';
|
|
8
|
+
import { toFixedString, parseUnits, mulDivRound } from './fixedPoint.js';
|
|
9
9
|
|
|
10
|
+
const PRECISION_18 = 10n ** 18n;
|
|
11
|
+
// Scale used to carry percentage ratios (tier boost, fee) into integer math alongside
|
|
12
|
+
// wei-scale trueBondPrice values, so the huge integer never round-trips through a float.
|
|
13
|
+
const RATIO_SCALE = 1000000000000n; // 1e12
|
|
14
|
+
const scaleRatio = (ratio) => parseUnits(ratio.toString(), 12);
|
|
10
15
|
const claimable = (userBill) => {
|
|
11
|
-
return getBalanceNumber(
|
|
16
|
+
return getBalanceNumber(userBill?.pendingRewards ?? '0', userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
|
|
12
17
|
};
|
|
13
18
|
const claimableUSD = (userBill) => {
|
|
14
19
|
const claimableTokens = claimable(userBill);
|
|
@@ -19,14 +24,15 @@ const earnTokenPrice = (bond) => {
|
|
|
19
24
|
};
|
|
20
25
|
// Amount of unvested (locked) tokens
|
|
21
26
|
const pending = (userBill) => {
|
|
22
|
-
return (getBalanceNumber(
|
|
27
|
+
return (getBalanceNumber(userBill?.payout ?? 0, userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18) -
|
|
28
|
+
claimable(userBill));
|
|
23
29
|
};
|
|
24
30
|
const pendingUSD = (userBill) => {
|
|
25
31
|
const pendingTokens = pending(userBill);
|
|
26
32
|
return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0');
|
|
27
33
|
};
|
|
28
34
|
const claimed = (userBill) => {
|
|
29
|
-
return getBalanceNumber(
|
|
35
|
+
return getBalanceNumber(userBill?.payoutClaimed ?? '0', userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
|
|
30
36
|
};
|
|
31
37
|
const claimedUSD = (userBill) => {
|
|
32
38
|
const claimedTokens = claimed(userBill);
|
|
@@ -80,12 +86,20 @@ const getVestingTermsTooltipString = (bond) => {
|
|
|
80
86
|
}
|
|
81
87
|
return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`;
|
|
82
88
|
};
|
|
89
|
+
// Applies tier-boost and fee percentage multipliers to a wei-scale (1e18) trueBondPrice,
|
|
90
|
+
// keeping the huge integer exact until the final getBalanceNumber() conversion.
|
|
91
|
+
const trueBondPriceWithFeeNumber = (trueBondPrice, tierBoostRate, feeInPayout) => {
|
|
92
|
+
const priceBig = BigInt(trueBondPrice ?? '0');
|
|
93
|
+
const tierAdjusted = mulDivRound(priceBig, scaleRatio((100 + tierBoostRate) / 100), RATIO_SCALE);
|
|
94
|
+
const feeAdjusted = mulDivRound(tierAdjusted, scaleRatio((100 + feeInPayout) / 100), RATIO_SCALE);
|
|
95
|
+
return getBalanceNumber(feeAdjusted);
|
|
96
|
+
};
|
|
83
97
|
const discountEarnTokenPrice = (bond, useTiers) => {
|
|
84
98
|
const feeInPayout = bond?.feeInPayout ?? 0;
|
|
85
99
|
const tierBoostRate = bond?.tierBoostRate ?? 0;
|
|
86
100
|
const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0');
|
|
87
101
|
const trueBondPrice = findHighestTrueBondPrice(useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0', bond?.trueBondPrices)?.trueBondPrice;
|
|
88
|
-
const trueBondPriceWithFee =
|
|
102
|
+
const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout);
|
|
89
103
|
return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3);
|
|
90
104
|
};
|
|
91
105
|
const discountEarnTokenPriceForUser = (bond, useTiers, userTier) => {
|
|
@@ -93,50 +107,49 @@ const discountEarnTokenPriceForUser = (bond, useTiers, userTier) => {
|
|
|
93
107
|
const tierBoostRate = bond?.tierBoostRate ?? 0;
|
|
94
108
|
const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0');
|
|
95
109
|
const trueBondPrice = findHighestTrueBondPrice(useTiers && userTier ? TIERS_WEIGHT[userTier] : '0', bond?.trueBondPrices)?.trueBondPrice;
|
|
96
|
-
const trueBondPriceWithFee =
|
|
110
|
+
const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout);
|
|
97
111
|
return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee);
|
|
98
112
|
};
|
|
99
113
|
const SAFETY_THRESHOLD = 5; // in USD
|
|
114
|
+
// bond?.tokensRemaining is already a human-decimal string (divided by decimals upstream);
|
|
115
|
+
// bond?.maxPayout is a raw wei-scale integer.
|
|
100
116
|
const getSafetyAvailable = (bond, allowLowValueBonds) => {
|
|
101
|
-
const available =
|
|
102
|
-
const payoutTokenPrice =
|
|
117
|
+
const available = Number(bond?.tokensRemaining ?? '0');
|
|
118
|
+
const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0);
|
|
103
119
|
const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD;
|
|
104
|
-
const thresholdToShow = payoutTokenPrice
|
|
120
|
+
const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0;
|
|
105
121
|
const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100;
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return new BigNumber(0);
|
|
111
|
-
return safeAvailable;
|
|
122
|
+
const safeAvailable = available * feeInPayoutAdjuster - thresholdToShow;
|
|
123
|
+
if (available === 0)
|
|
124
|
+
return 0;
|
|
125
|
+
return safeAvailable < 0 ? 0 : safeAvailable;
|
|
112
126
|
};
|
|
113
127
|
const getSafetyPurchaseLimit = (bond, allowLowValueBonds) => {
|
|
114
128
|
const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD;
|
|
115
|
-
const payoutTokenPrice =
|
|
116
|
-
const thresholdToShow = payoutTokenPrice
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.minus(thresholdToShow);
|
|
129
|
+
const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0);
|
|
130
|
+
const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0;
|
|
131
|
+
const maxPayout = getBalanceNumber(bond?.maxPayout ?? 0, bond?.earnToken?.decimals?.[bond?.chainId] ?? 18);
|
|
132
|
+
return maxPayout - thresholdToShow;
|
|
120
133
|
};
|
|
121
134
|
const getMaxBuy = (bond, allowLowValueBonds) => {
|
|
122
135
|
const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds);
|
|
123
136
|
const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds);
|
|
124
|
-
return safePurchaseLimit
|
|
137
|
+
return safePurchaseLimit < safeAvailable ? safePurchaseLimit : safeAvailable;
|
|
125
138
|
};
|
|
126
139
|
function formatUSDNumber(input) {
|
|
127
|
-
const number =
|
|
128
|
-
if (
|
|
140
|
+
const number = Number(input);
|
|
141
|
+
if (Number.isNaN(number))
|
|
129
142
|
return '0';
|
|
130
143
|
// If the number is greater than 0 but less than 0.01
|
|
131
|
-
if (number
|
|
144
|
+
if (number > 0 && number < 0.01) {
|
|
132
145
|
return '< 0.01';
|
|
133
146
|
}
|
|
134
147
|
// If the number is greater than 1k, round to no decimals.
|
|
135
|
-
if (number
|
|
136
|
-
return number.
|
|
148
|
+
if (number > 1000) {
|
|
149
|
+
return number.toLocaleString('en-US', { maximumFractionDigits: 0 });
|
|
137
150
|
}
|
|
138
151
|
// Note: Between 1k and 0.01 show 2 decimals
|
|
139
|
-
return parseFloat(number
|
|
152
|
+
return parseFloat(toFixedString(number, 2)).toLocaleString('en-US');
|
|
140
153
|
}
|
|
141
154
|
const youSpendUSD = (bond, inputValue) => {
|
|
142
155
|
return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString();
|
|
@@ -145,13 +158,16 @@ const youSpendUSD = (bond, inputValue) => {
|
|
|
145
158
|
const getPayoutAmount = (bond, inputValue, userPoints) => {
|
|
146
159
|
if (!inputValue || !bond || !userPoints || !bond.trueBondPrices)
|
|
147
160
|
return 0;
|
|
148
|
-
const bigValue =
|
|
161
|
+
const bigValue = parseUnits(inputValue, 18);
|
|
149
162
|
const fee = bond?.feeInPayout ?? 0;
|
|
150
163
|
const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices);
|
|
151
|
-
const trueBondPrice =
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
164
|
+
const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0');
|
|
165
|
+
const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18);
|
|
166
|
+
const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18);
|
|
167
|
+
if (trueBondPriceWithFee === 0n)
|
|
168
|
+
return 0;
|
|
169
|
+
const billValueScaled = mulDivRound(bigValue, PRECISION_18, trueBondPriceWithFee);
|
|
170
|
+
return getBalanceNumber(billValueScaled, 18);
|
|
155
171
|
};
|
|
156
172
|
const youGetUSD = (bond, inputValue, userPoints) => {
|
|
157
173
|
if (!inputValue || !bond || !userPoints || !bond.trueBondPrices)
|
|
@@ -175,35 +191,35 @@ const getBonusColor = (premiumString) => {
|
|
|
175
191
|
* @param bond - The bond data
|
|
176
192
|
* @param targetPayoutAmount - The desired payout amount in payout tokens
|
|
177
193
|
* @param userPoints - User's tier points
|
|
178
|
-
* @returns The principal token amount needed, or
|
|
194
|
+
* @returns The principal token amount needed, or 0 if calculation cannot be performed
|
|
179
195
|
*/
|
|
180
196
|
const getPrincipalAmount = (bond, targetPayoutAmount, userPoints) => {
|
|
181
197
|
if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices)
|
|
182
|
-
return
|
|
183
|
-
const billValue =
|
|
198
|
+
return 0;
|
|
199
|
+
const billValue = parseUnits(targetPayoutAmount.toString(), 18);
|
|
184
200
|
const fee = bond?.feeInPayout ?? 0;
|
|
185
201
|
const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices);
|
|
186
|
-
const trueBondPrice =
|
|
187
|
-
if (trueBondPrice
|
|
188
|
-
return
|
|
189
|
-
const
|
|
190
|
-
const trueBondPriceWithFee = trueBondPrice
|
|
202
|
+
const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0');
|
|
203
|
+
if (trueBondPrice === 0n)
|
|
204
|
+
return 0;
|
|
205
|
+
const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18);
|
|
206
|
+
const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18);
|
|
191
207
|
// Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)
|
|
192
|
-
const
|
|
208
|
+
const bigValueScaled = mulDivRound(billValue, trueBondPriceWithFee, PRECISION_18);
|
|
193
209
|
// Convert from 18 decimals back to regular amount
|
|
194
|
-
return
|
|
210
|
+
return getBalanceNumber(bigValueScaled, 18);
|
|
195
211
|
};
|
|
196
212
|
const getRemainingTokensString = (bond, allowLowValueBonds) => {
|
|
197
|
-
const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds)
|
|
213
|
+
const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds);
|
|
198
214
|
// const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')
|
|
199
215
|
const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0');
|
|
200
216
|
return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`;
|
|
201
217
|
};
|
|
202
218
|
const remainingPercentage = (bond) => {
|
|
203
|
-
const totalMaxPayout =
|
|
204
|
-
const remainingTokens =
|
|
205
|
-
return remainingTokens
|
|
219
|
+
const totalMaxPayout = getBalanceNumber(bond.maxTotalPayout ?? '0', bond.earnToken.decimals?.[bond.chainId] ?? 18);
|
|
220
|
+
const remainingTokens = Number(bond.tokensRemaining ?? '0');
|
|
221
|
+
return (remainingTokens / totalMaxPayout) * 100;
|
|
206
222
|
};
|
|
207
223
|
|
|
208
|
-
export {
|
|
224
|
+
export { claimable, claimableUSD, claimed, claimedUSD, discountEarnTokenPrice, discountEarnTokenPriceForUser, earnTokenPrice, formatUSDNumber, getBonusColor, getMaxBuy, getPayoutAmount, getPendingVestingString, getPercentageVested, getPrincipalAmount, getRawBonus, getRemainingTokensString, getTimeLeftForFullyVested, getVestingTermsString, getVestingTermsTooltipString, pending, pendingUSD, remainingPercentage };
|
|
209
225
|
//# sourceMappingURL=displayHelpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displayHelpers.js","sources":["../../src/utils/displayHelpers.ts"],"sourcesContent":["import { BigNumber } from 'bignumber.js'\nimport { UserBill } from '../types/yourbonds'\nimport { getBalanceNumber } from './getBalanceNumber'\nimport { BondsData } from '../types/bonds'\nimport { getFirstNonZeroDigits } from './roundNumber'\nimport { getTimePeriods } from './getTimePeriods'\nimport { formatNumberSI } from './formatNumber'\nimport { BillsConfig, LaunchBondTiers } from '@ape.swap/apeswap-lists'\nimport { TIERS_WEIGHT } from '../state/tiers/useTierPoints'\nimport { findHighestTrueBondPrice } from './bondPriceHelpers'\n\nexport const claimable = (userBill?: UserBill) => {\n return getBalanceNumber(\n new BigNumber(userBill?.pendingRewards ?? '0'),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimableUSD = (userBill?: UserBill) => {\n const claimableTokens = claimable(userBill)\n return claimableTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const earnTokenPrice = (bond: BondsData) => {\n return formatNumberSI(bond?.payoutTokenPrice ?? '0')\n}\n\n// Amount of unvested (locked) tokens\nexport const pending = (userBill?: UserBill) => {\n return (\n getBalanceNumber(\n new BigNumber(userBill?.payout ?? 0),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n ) - claimable(userBill)\n )\n}\n\nexport const pendingUSD = (userBill?: UserBill) => {\n const pendingTokens = pending(userBill)\n return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const claimed = (userBill?: UserBill) => {\n return getBalanceNumber(\n new BigNumber(userBill?.payoutClaimed ?? '0'),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimedUSD = (userBill?: UserBill) => {\n const claimedTokens = claimed(userBill)\n return claimedTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getPercentageVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n if (timeLeftForFullyVested <= 0) return 100\n return ((vestingTerm - timeLeftForFullyVested) / vestingTerm) * 100\n}\n\nexport const getTimeLeftForFullyVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const purchaseTimestamp = parseInt(bond?.vestingStartTimestamp ?? '0')\n const now = Math.round(Date.now() / 1000)\n return purchaseTimestamp + vestingTerm - now\n}\n\nexport const getPendingVestingString = (bond?: UserBill) => {\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n const vestingTime = getTimePeriods(timeLeftForFullyVested, true)\n return `${vestingTime.days}d, ${vestingTime.hours}h, ${vestingTime.minutes}m`\n}\n\nexport const getVestingTermsString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff ?? 0\n if (!vestingCliff) {\n const vestingTime = getTimePeriods(vestingTerm, true)\n return `${vestingTime.days} D`\n } else if (vestingCliff) {\n // TODO: remove this hardcoded shit\n if (bond?.earnToken.symbol === 'AIX') {\n return `${getTimePeriods(vestingCliff, true).days} D`\n }\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n return `${vestingCliffString.days + vestingTime.days} D`\n }\n return '-'\n}\n\nexport const getVestingTermsTooltipString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff\n if (!vestingCliff) return undefined\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n if (vestingTerm - vestingCliff === 0) {\n return `${vestingCliffString.days}-day cliff, then instant release of all tokens.`\n }\n return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`\n}\n\nexport const discountEarnTokenPrice = (bond: BondsData, useTiers?: boolean) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = getBalanceNumber(\n new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100),\n )\n return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3)\n}\n\nexport const discountEarnTokenPriceForUser = (bond: BondsData, useTiers?: boolean, userTier?: LaunchBondTiers) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers && userTier ? TIERS_WEIGHT[userTier] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = getBalanceNumber(\n new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100),\n )\n return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee)\n}\n\nexport const SAFETY_THRESHOLD = 5 // in USD\n\nexport const getSafetyAvailable = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const available = new BigNumber(bond?.tokensRemaining ?? '0')\n const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0)\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0)\n const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100\n let safeAvailable = available.times(feeInPayoutAdjuster).minus(thresholdToShow)\n if (safeAvailable.lt(0)) safeAvailable = new BigNumber(0)\n if (available.isZero()) return new BigNumber(0)\n return safeAvailable\n}\n\nexport const getSafetyPurchaseLimit = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0)\n const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0)\n return new BigNumber(bond?.maxPayout ?? 0)\n .div(new BigNumber(10).pow(bond?.earnToken?.decimals?.[bond?.chainId] ?? 18))\n .minus(thresholdToShow)\n}\n\nexport const getMaxBuy = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds)\n const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds)\n\n return safePurchaseLimit.lt(safeAvailable) ? safePurchaseLimit : safeAvailable\n}\n\nexport function formatUSDNumber(input: string): string {\n const number = new BigNumber(input)\n if (number.isNaN()) return '0'\n\n // If the number is greater than 0 but less than 0.01\n if (number.gt(0) && number.lt(0.01)) {\n return '< 0.01'\n }\n // If the number is greater than 1k, round to no decimals.\n if (number.gt(1000)) {\n return number.toNumber().toLocaleString('en-US', { maximumFractionDigits: 0 })\n }\n // Note: Between 1k and 0.01 show 2 decimals\n return parseFloat(number.toFixed(2)).toLocaleString('en-US')\n}\n\nexport const youSpendUSD = (bond: BondsData, inputValue: string) => {\n return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString()\n}\n\n// receives depositAmount and returns the payoutTokens the user will receive. IT DOES SUBTRACT FEE IN PAYOUT\nexport const getPayoutAmount = (bond?: BondsData, inputValue?: string, userPoints?: string | null) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const bigValue = new BigNumber(inputValue).times(new BigNumber(10).pow(18))\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0')\n const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100))\n const billValue = bigValue.div(trueBondPrice.plus(trueBondPrice.times(reverseFee)))\n return billValue.toNumber()\n}\n\nexport const youGetUSD = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n const payoutAmount = getPayoutAmount(bond, inputValue, userPoints)\n return payoutAmount * parseFloat(bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getRawBonus = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!bond || !inputValue || !userPoints) return '0'\n const premiumUSD = youGetUSD(bond, inputValue, userPoints) - parseFloat(youSpendUSD(bond, inputValue))\n return premiumUSD.toString()\n}\n\nexport const getFeeAmount = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n const fee = bond?.feeInPayout\n if (!bond || !inputValue || !fee || !userPoints) return 0\n const billValue = new BigNumber(inputValue).times(new BigNumber(10).pow(18))\n const trueBondPrice = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const feeAmount = billValue.div(new BigNumber(trueBondPrice?.trueBondPrice ?? 0).div(fee / 100))\n return feeAmount.toNumber()\n}\n\nexport const getBonusColor = (premiumString: string): string => {\n return parseFloat(premiumString) < 0 ? 'premium-negative' : 'premium-positive'\n}\n\n/**\n * Calculates the principal token amount needed to receive a target payout amount.\n * This is the reverse of getRawPayoutAmount function (does NOT include fees).\n *\n * @param bond - The bond data\n * @param targetPayoutAmount - The desired payout amount in payout tokens\n * @param userPoints - User's tier points\n * @returns The principal token amount needed, or '0' if calculation cannot be performed\n */\nexport const getPrincipalAmount = (\n bond?: BondsData,\n targetPayoutAmount?: number | string,\n userPoints?: string | null,\n): BigNumber => {\n if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices) return new BigNumber(0)\n\n const billValue = new BigNumber(targetPayoutAmount)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0')\n\n if (trueBondPrice.isZero()) return new BigNumber(0)\n\n const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100))\n const trueBondPriceWithFee = trueBondPrice.plus(trueBondPrice.times(reverseFee))\n\n // Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)\n const bigValue = billValue.times(trueBondPriceWithFee)\n\n // Convert from 18 decimals back to regular amount\n return bigValue.div(new BigNumber(10).pow(18))\n}\n\nexport const getRemainingTokensString = (bond: BondsData, allowLowValueBonds?: boolean) => {\n const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds).toNumber()\n // const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')\n const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0')\n\n return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`\n}\n\nexport const remainingPercentage = (bond: BondsData): number => {\n const totalMaxPayout = new BigNumber(bond.maxTotalPayout ?? '0').div(\n new BigNumber(10).pow(bond.earnToken.decimals?.[bond.chainId] ?? 18),\n )\n const remainingTokens = new BigNumber(bond.tokensRemaining ?? '0')\n\n return remainingTokens.div(totalMaxPayout).times(100).toNumber()\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"displayHelpers.js","sources":["../../src/utils/displayHelpers.ts"],"sourcesContent":["import { UserBill } from '../types/yourbonds'\nimport { getBalanceNumber } from './getBalanceNumber'\nimport { BondsData } from '../types/bonds'\nimport { getFirstNonZeroDigits } from './roundNumber'\nimport { getTimePeriods } from './getTimePeriods'\nimport { formatNumberSI } from './formatNumber'\nimport { BillsConfig, LaunchBondTiers } from '@ape.swap/apeswap-lists'\nimport { TIERS_WEIGHT } from '../state/tiers/useTierPoints'\nimport { findHighestTrueBondPrice } from './bondPriceHelpers'\nimport { mulDivRound, parseUnits, toFixedString } from './fixedPoint'\n\nconst PRECISION_18 = 10n ** 18n\n// Scale used to carry percentage ratios (tier boost, fee) into integer math alongside\n// wei-scale trueBondPrice values, so the huge integer never round-trips through a float.\nconst RATIO_SCALE = 1_000_000_000_000n // 1e12\nconst scaleRatio = (ratio: number): bigint => parseUnits(ratio.toString(), 12)\n\nexport const claimable = (userBill?: UserBill) => {\n return getBalanceNumber(\n userBill?.pendingRewards ?? '0',\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimableUSD = (userBill?: UserBill) => {\n const claimableTokens = claimable(userBill)\n return claimableTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const earnTokenPrice = (bond: BondsData) => {\n return formatNumberSI(bond?.payoutTokenPrice ?? '0')\n}\n\n// Amount of unvested (locked) tokens\nexport const pending = (userBill?: UserBill) => {\n return (\n getBalanceNumber(userBill?.payout ?? 0, userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18) -\n claimable(userBill)\n )\n}\n\nexport const pendingUSD = (userBill?: UserBill) => {\n const pendingTokens = pending(userBill)\n return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const claimed = (userBill?: UserBill) => {\n return getBalanceNumber(\n userBill?.payoutClaimed ?? '0',\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimedUSD = (userBill?: UserBill) => {\n const claimedTokens = claimed(userBill)\n return claimedTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getPercentageVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n if (timeLeftForFullyVested <= 0) return 100\n return ((vestingTerm - timeLeftForFullyVested) / vestingTerm) * 100\n}\n\nexport const getTimeLeftForFullyVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const purchaseTimestamp = parseInt(bond?.vestingStartTimestamp ?? '0')\n const now = Math.round(Date.now() / 1000)\n return purchaseTimestamp + vestingTerm - now\n}\n\nexport const getPendingVestingString = (bond?: UserBill) => {\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n const vestingTime = getTimePeriods(timeLeftForFullyVested, true)\n return `${vestingTime.days}d, ${vestingTime.hours}h, ${vestingTime.minutes}m`\n}\n\nexport const getVestingTermsString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff ?? 0\n if (!vestingCliff) {\n const vestingTime = getTimePeriods(vestingTerm, true)\n return `${vestingTime.days} D`\n } else if (vestingCliff) {\n // TODO: remove this hardcoded shit\n if (bond?.earnToken.symbol === 'AIX') {\n return `${getTimePeriods(vestingCliff, true).days} D`\n }\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n return `${vestingCliffString.days + vestingTime.days} D`\n }\n return '-'\n}\n\nexport const getVestingTermsTooltipString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff\n if (!vestingCliff) return undefined\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n if (vestingTerm - vestingCliff === 0) {\n return `${vestingCliffString.days}-day cliff, then instant release of all tokens.`\n }\n return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`\n}\n\n// Applies tier-boost and fee percentage multipliers to a wei-scale (1e18) trueBondPrice,\n// keeping the huge integer exact until the final getBalanceNumber() conversion.\nconst trueBondPriceWithFeeNumber = (\n trueBondPrice: string | undefined,\n tierBoostRate: number,\n feeInPayout: number,\n): number => {\n const priceBig = BigInt(trueBondPrice ?? '0')\n const tierAdjusted = mulDivRound(priceBig, scaleRatio((100 + tierBoostRate) / 100), RATIO_SCALE)\n const feeAdjusted = mulDivRound(tierAdjusted, scaleRatio((100 + feeInPayout) / 100), RATIO_SCALE)\n return getBalanceNumber(feeAdjusted)\n}\n\nexport const discountEarnTokenPrice = (bond: BondsData, useTiers?: boolean) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout)\n return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3)\n}\n\nexport const discountEarnTokenPriceForUser = (bond: BondsData, useTiers?: boolean, userTier?: LaunchBondTiers) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers && userTier ? TIERS_WEIGHT[userTier] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout)\n return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee)\n}\n\nconst SAFETY_THRESHOLD = 5 // in USD\n\n// bond?.tokensRemaining is already a human-decimal string (divided by decimals upstream);\n// bond?.maxPayout is a raw wei-scale integer.\nconst getSafetyAvailable = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const available = Number(bond?.tokensRemaining ?? '0')\n const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0)\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0\n const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100\n const safeAvailable = available * feeInPayoutAdjuster - thresholdToShow\n if (available === 0) return 0\n return safeAvailable < 0 ? 0 : safeAvailable\n}\n\nconst getSafetyPurchaseLimit = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0)\n const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0\n const maxPayout = getBalanceNumber(bond?.maxPayout ?? 0, bond?.earnToken?.decimals?.[bond?.chainId] ?? 18)\n return maxPayout - thresholdToShow\n}\n\nexport const getMaxBuy = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds)\n const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds)\n\n return safePurchaseLimit < safeAvailable ? safePurchaseLimit : safeAvailable\n}\n\nexport function formatUSDNumber(input: string): string {\n const number = Number(input)\n if (Number.isNaN(number)) return '0'\n\n // If the number is greater than 0 but less than 0.01\n if (number > 0 && number < 0.01) {\n return '< 0.01'\n }\n // If the number is greater than 1k, round to no decimals.\n if (number > 1000) {\n return number.toLocaleString('en-US', { maximumFractionDigits: 0 })\n }\n // Note: Between 1k and 0.01 show 2 decimals\n return parseFloat(toFixedString(number, 2)).toLocaleString('en-US')\n}\n\nconst youSpendUSD = (bond: BondsData, inputValue: string) => {\n return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString()\n}\n\n// receives depositAmount and returns the payoutTokens the user will receive. IT DOES SUBTRACT FEE IN PAYOUT\nexport const getPayoutAmount = (bond?: BondsData, inputValue?: string, userPoints?: string | null) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const bigValue = parseUnits(inputValue, 18)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0')\n\n const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18)\n const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18)\n if (trueBondPriceWithFee === 0n) return 0\n\n const billValueScaled = mulDivRound(bigValue, PRECISION_18, trueBondPriceWithFee)\n return getBalanceNumber(billValueScaled, 18)\n}\n\nconst youGetUSD = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n const payoutAmount = getPayoutAmount(bond, inputValue, userPoints)\n return payoutAmount * parseFloat(bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getRawBonus = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!bond || !inputValue || !userPoints) return '0'\n const premiumUSD = youGetUSD(bond, inputValue, userPoints) - parseFloat(youSpendUSD(bond, inputValue))\n return premiumUSD.toString()\n}\n\nexport const getBonusColor = (premiumString: string): string => {\n return parseFloat(premiumString) < 0 ? 'premium-negative' : 'premium-positive'\n}\n\n/**\n * Calculates the principal token amount needed to receive a target payout amount.\n * This is the reverse of getRawPayoutAmount function (does NOT include fees).\n *\n * @param bond - The bond data\n * @param targetPayoutAmount - The desired payout amount in payout tokens\n * @param userPoints - User's tier points\n * @returns The principal token amount needed, or 0 if calculation cannot be performed\n */\nexport const getPrincipalAmount = (\n bond?: BondsData,\n targetPayoutAmount?: number | string,\n userPoints?: string | null,\n): number => {\n if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const billValue = parseUnits(targetPayoutAmount.toString(), 18)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0')\n\n if (trueBondPrice === 0n) return 0\n\n const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18)\n const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18)\n\n // Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)\n const bigValueScaled = mulDivRound(billValue, trueBondPriceWithFee, PRECISION_18)\n\n // Convert from 18 decimals back to regular amount\n return getBalanceNumber(bigValueScaled, 18)\n}\n\nexport const getRemainingTokensString = (bond: BondsData, allowLowValueBonds?: boolean) => {\n const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds)\n // const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')\n const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0')\n\n return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`\n}\n\nexport const remainingPercentage = (bond: BondsData): number => {\n const totalMaxPayout = getBalanceNumber(bond.maxTotalPayout ?? '0', bond.earnToken.decimals?.[bond.chainId] ?? 18)\n const remainingTokens = Number(bond.tokensRemaining ?? '0')\n\n return (remainingTokens / totalMaxPayout) * 100\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type Rounding = 'floor' | 'ceil' | 'trunc';
|
|
2
|
+
export type DecimalRounding = Rounding | 'halfUp';
|
|
3
|
+
/**
|
|
4
|
+
* Parses a human decimal string/number into a raw integer scaled by 10^decimals.
|
|
5
|
+
* `rounding` controls what happens when the input has more fractional digits than
|
|
6
|
+
* `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass
|
|
7
|
+
* 'floor'/'ceil' where overspending or underspending the user's typed amount matters
|
|
8
|
+
* (e.g. converting a typed amount to atomic units for a transaction).
|
|
9
|
+
*/
|
|
10
|
+
export declare const parseUnits: (value: string | number | undefined | null, decimals: number, rounding?: DecimalRounding) => bigint;
|
|
11
|
+
/** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */
|
|
12
|
+
export declare const formatUnits: (value: bigint | string | number | undefined | null, decimals: number) => string;
|
|
13
|
+
/** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */
|
|
14
|
+
export declare const mulDivRound: (value: bigint, numerator: bigint, denominator: bigint, rounding?: DecimalRounding) => bigint;
|
|
15
|
+
/**
|
|
16
|
+
* Rounds a human-scale decimal value to `dp` decimal places, returned as a string.
|
|
17
|
+
* Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt
|
|
18
|
+
* based, so it doesn't inherit float rounding artifacts.
|
|
19
|
+
*/
|
|
20
|
+
export declare const toFixedString: (value: string | number, dp: number, rounding?: DecimalRounding) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.
|
|
23
|
+
* Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics
|
|
24
|
+
* (does not strip trailing zeros, and never switches to exponential notation — callers that
|
|
25
|
+
* want trimmed output should trim the result themselves, matching prior call sites that did
|
|
26
|
+
* `.toFixed().replace(/\.?0+$/, '')` after `.sd()`).
|
|
27
|
+
*/
|
|
28
|
+
export declare const toSignificantDigitsString: (value: string | number, sigDigits: number) => string;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// Fixed-point / decimal-string math built on native BigInt.
|
|
2
|
+
//
|
|
3
|
+
// Two distinct jobs, kept separate:
|
|
4
|
+
// - parseUnits/formatUnits/mulDivRound operate on raw on-chain integer amounts
|
|
5
|
+
// (wei-style, scaled by 10^decimals) — exact BigInt arithmetic.
|
|
6
|
+
// - toFixedString/toSignificantDigitsString operate on already-human-scale
|
|
7
|
+
// decimal numbers (prices, percentages) for display formatting/rounding.
|
|
8
|
+
// BigInt has no notion of decimals, so these round via string/BigInt digit
|
|
9
|
+
// manipulation instead of float scaling, to avoid classic float rounding
|
|
10
|
+
// artifacts (e.g. naive `Math.round(x * 100) / 100`).
|
|
11
|
+
const DIGITS_RE = /^\d*\.?\d*$/;
|
|
12
|
+
const hasNonZeroDigit = (digits) => /[1-9]/.test(digits);
|
|
13
|
+
const shouldRoundUp = (discarded, rounding, negative) => {
|
|
14
|
+
if (rounding === 'trunc')
|
|
15
|
+
return false;
|
|
16
|
+
if (rounding === 'floor')
|
|
17
|
+
return negative && hasNonZeroDigit(discarded);
|
|
18
|
+
if (rounding === 'ceil')
|
|
19
|
+
return !negative && hasNonZeroDigit(discarded);
|
|
20
|
+
// halfUp (round half away from zero): only the first discarded digit matters.
|
|
21
|
+
const firstDiscarded = discarded.charCodeAt(0) - 48;
|
|
22
|
+
return firstDiscarded >= 5;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Parses a human decimal string/number into a raw integer scaled by 10^decimals.
|
|
26
|
+
* `rounding` controls what happens when the input has more fractional digits than
|
|
27
|
+
* `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass
|
|
28
|
+
* 'floor'/'ceil' where overspending or underspending the user's typed amount matters
|
|
29
|
+
* (e.g. converting a typed amount to atomic units for a transaction).
|
|
30
|
+
*/
|
|
31
|
+
const parseUnits = (value, decimals, rounding = 'halfUp') => {
|
|
32
|
+
if (value === undefined || value === null || value === '')
|
|
33
|
+
return 0n;
|
|
34
|
+
const raw = typeof value === 'number' ? value.toString() : value.trim();
|
|
35
|
+
if (!raw)
|
|
36
|
+
return 0n;
|
|
37
|
+
let negative = false;
|
|
38
|
+
let str = raw;
|
|
39
|
+
if (str.startsWith('-')) {
|
|
40
|
+
negative = true;
|
|
41
|
+
str = str.slice(1);
|
|
42
|
+
}
|
|
43
|
+
else if (str.startsWith('+')) {
|
|
44
|
+
str = str.slice(1);
|
|
45
|
+
}
|
|
46
|
+
if (!DIGITS_RE.test(str) || str === '' || str === '.')
|
|
47
|
+
return 0n;
|
|
48
|
+
const [intPartRaw, fracPartRaw = ''] = str.split('.');
|
|
49
|
+
const intPart = intPartRaw || '0';
|
|
50
|
+
let combined;
|
|
51
|
+
if (fracPartRaw.length > decimals) {
|
|
52
|
+
const keep = fracPartRaw.slice(0, decimals);
|
|
53
|
+
const discarded = fracPartRaw.slice(decimals);
|
|
54
|
+
combined = BigInt(intPart + keep || '0');
|
|
55
|
+
if (shouldRoundUp(discarded, rounding, negative))
|
|
56
|
+
combined += 1n;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const fracPart = fracPartRaw.padEnd(decimals, '0');
|
|
60
|
+
combined = BigInt(intPart + fracPart || '0');
|
|
61
|
+
}
|
|
62
|
+
return negative && combined !== 0n ? -combined : combined;
|
|
63
|
+
};
|
|
64
|
+
/** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */
|
|
65
|
+
const formatUnits = (value, decimals) => {
|
|
66
|
+
let big;
|
|
67
|
+
try {
|
|
68
|
+
if (typeof value === 'bigint')
|
|
69
|
+
big = value;
|
|
70
|
+
else if (value === undefined || value === null || value === '')
|
|
71
|
+
big = 0n;
|
|
72
|
+
else if (typeof value === 'number')
|
|
73
|
+
big = BigInt(Math.trunc(value));
|
|
74
|
+
else
|
|
75
|
+
big = BigInt(value.trim());
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
big = 0n;
|
|
79
|
+
}
|
|
80
|
+
const negative = big < 0n;
|
|
81
|
+
const abs = negative ? -big : big;
|
|
82
|
+
const base = 10n ** BigInt(decimals);
|
|
83
|
+
const intPart = abs / base;
|
|
84
|
+
const fracPart = abs % base;
|
|
85
|
+
let fracStr = decimals > 0 ? fracPart.toString().padStart(decimals, '0') : '';
|
|
86
|
+
fracStr = fracStr.replace(/0+$/, '');
|
|
87
|
+
const result = fracStr.length > 0 ? `${intPart}.${fracStr}` : `${intPart}`;
|
|
88
|
+
return negative && big !== 0n ? `-${result}` : result;
|
|
89
|
+
};
|
|
90
|
+
/** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */
|
|
91
|
+
const mulDivRound = (value, numerator, denominator, rounding = 'trunc') => {
|
|
92
|
+
if (denominator === 0n)
|
|
93
|
+
throw new Error('mulDivRound: division by zero');
|
|
94
|
+
const product = value * numerator;
|
|
95
|
+
const quotient = product / denominator;
|
|
96
|
+
const remainder = product % denominator;
|
|
97
|
+
if (remainder === 0n || rounding === 'trunc')
|
|
98
|
+
return quotient;
|
|
99
|
+
// Sign of the true (unrounded) mathematical quotient.
|
|
100
|
+
const isNegative = product < 0n !== denominator < 0n;
|
|
101
|
+
if (rounding === 'floor')
|
|
102
|
+
return isNegative ? quotient - 1n : quotient;
|
|
103
|
+
if (rounding === 'ceil')
|
|
104
|
+
return isNegative ? quotient : quotient + 1n;
|
|
105
|
+
// halfUp (round half away from zero)
|
|
106
|
+
const absRemainder = remainder < 0n ? -remainder : remainder;
|
|
107
|
+
const absDenominator = denominator < 0n ? -denominator : denominator;
|
|
108
|
+
const roundsUp = absRemainder * 2n >= absDenominator;
|
|
109
|
+
if (!roundsUp)
|
|
110
|
+
return quotient;
|
|
111
|
+
return isNegative ? quotient - 1n : quotient + 1n;
|
|
112
|
+
};
|
|
113
|
+
// Expands JS exponential notation ("4.56e-8") into a plain decimal string, via pure
|
|
114
|
+
// string manipulation (shifting the decimal point) — never re-derives digits from the
|
|
115
|
+
// underlying binary float, so no float-representation noise is introduced.
|
|
116
|
+
const expandExponential = (str) => {
|
|
117
|
+
const match = str.match(/^(-?)(\d+)(?:\.(\d+))?e([+-]\d+)$/i);
|
|
118
|
+
if (!match)
|
|
119
|
+
return str;
|
|
120
|
+
const [, sign, intDigits, fracDigits = '', expStr] = match;
|
|
121
|
+
const exp = parseInt(expStr, 10);
|
|
122
|
+
const digits = intDigits + fracDigits;
|
|
123
|
+
const pointPos = intDigits.length + exp;
|
|
124
|
+
let result;
|
|
125
|
+
if (pointPos <= 0) {
|
|
126
|
+
result = `0.${'0'.repeat(-pointPos)}${digits}`;
|
|
127
|
+
}
|
|
128
|
+
else if (pointPos >= digits.length) {
|
|
129
|
+
result = digits + '0'.repeat(pointPos - digits.length);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
result = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`;
|
|
133
|
+
}
|
|
134
|
+
return sign + result;
|
|
135
|
+
};
|
|
136
|
+
const toPlainDecimalString = (value) => {
|
|
137
|
+
if (typeof value === 'string')
|
|
138
|
+
return value.trim() || '0';
|
|
139
|
+
if (!Number.isFinite(value))
|
|
140
|
+
return '0';
|
|
141
|
+
if (value === 0)
|
|
142
|
+
return '0';
|
|
143
|
+
// .toString() gives the shortest decimal that round-trips to this float (what a user
|
|
144
|
+
// typing "1.005" would expect), as opposed to .toFixed(n) which re-derives the true
|
|
145
|
+
// (noisy) binary expansion.
|
|
146
|
+
const str = value.toString();
|
|
147
|
+
return /e/i.test(str) ? expandExponential(str) : str;
|
|
148
|
+
};
|
|
149
|
+
const splitSigned = (value) => {
|
|
150
|
+
const str = toPlainDecimalString(value);
|
|
151
|
+
const negative = str.startsWith('-');
|
|
152
|
+
const unsigned = negative ? str.slice(1) : str;
|
|
153
|
+
const [intPartRaw, fracPartRaw = ''] = unsigned.split('.');
|
|
154
|
+
return { negative, intPart: intPartRaw || '0', fracPart: fracPartRaw };
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Rounds the unsigned "intPart.fracPart" digit string to `dp` decimal places.
|
|
158
|
+
* `dp` may be negative to round within the integer part (e.g. dp=-3 rounds to the nearest 1000).
|
|
159
|
+
*/
|
|
160
|
+
const roundDigits = (intPart, fracPart, dp, roundUp) => {
|
|
161
|
+
if (dp >= 0) {
|
|
162
|
+
if (fracPart.length <= dp) {
|
|
163
|
+
const paddedFrac = fracPart.padEnd(dp, '0');
|
|
164
|
+
return dp > 0 ? `${intPart}.${paddedFrac}` : intPart;
|
|
165
|
+
}
|
|
166
|
+
const keep = fracPart.slice(0, dp);
|
|
167
|
+
let combined = BigInt(intPart + keep || '0');
|
|
168
|
+
if (roundUp)
|
|
169
|
+
combined += 1n;
|
|
170
|
+
const combinedStr = combined.toString().padStart(dp + 1, '0');
|
|
171
|
+
const newInt = combinedStr.slice(0, combinedStr.length - dp) || '0';
|
|
172
|
+
const newFrac = dp > 0 ? combinedStr.slice(combinedStr.length - dp) : '';
|
|
173
|
+
return dp > 0 ? `${newInt}.${newFrac}` : newInt;
|
|
174
|
+
}
|
|
175
|
+
// dp < 0: round within the integer part, discarding the fractional part entirely.
|
|
176
|
+
const shift = -dp;
|
|
177
|
+
if (intPart.length <= shift) {
|
|
178
|
+
const combined = roundUp ? 10n ** BigInt(shift) : 0n;
|
|
179
|
+
return combined.toString();
|
|
180
|
+
}
|
|
181
|
+
const keepLen = intPart.length - shift;
|
|
182
|
+
const keep = intPart.slice(0, keepLen);
|
|
183
|
+
let combined = BigInt(keep || '0');
|
|
184
|
+
if (roundUp)
|
|
185
|
+
combined += 1n;
|
|
186
|
+
return combined.toString() + '0'.repeat(shift);
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Rounds a human-scale decimal value to `dp` decimal places, returned as a string.
|
|
190
|
+
* Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt
|
|
191
|
+
* based, so it doesn't inherit float rounding artifacts.
|
|
192
|
+
*/
|
|
193
|
+
const toFixedString = (value, dp, rounding = 'halfUp') => {
|
|
194
|
+
const { negative, intPart, fracPart } = splitSigned(value);
|
|
195
|
+
const discarded = dp >= 0 ? fracPart.slice(dp) : intPart.slice(Math.max(intPart.length + dp, 0)) + fracPart;
|
|
196
|
+
const roundUp = shouldRoundUp(discarded, rounding, negative);
|
|
197
|
+
const result = roundDigits(intPart, fracPart, dp, roundUp);
|
|
198
|
+
const isZero = !hasNonZeroDigit(result);
|
|
199
|
+
return negative && !isZero ? `-${result}` : result;
|
|
200
|
+
};
|
|
201
|
+
const significantExponent = (intPart, fracPart) => {
|
|
202
|
+
const intDigits = intPart.replace(/^0+/, '');
|
|
203
|
+
if (intDigits.length > 0)
|
|
204
|
+
return intDigits.length - 1;
|
|
205
|
+
const leadingZeros = fracPart.match(/^0*/)?.[0].length ?? 0;
|
|
206
|
+
if (leadingZeros >= fracPart.length)
|
|
207
|
+
return 0; // value is zero
|
|
208
|
+
return -(leadingZeros + 1);
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.
|
|
212
|
+
* Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics
|
|
213
|
+
* (does not strip trailing zeros, and never switches to exponential notation — callers that
|
|
214
|
+
* want trimmed output should trim the result themselves, matching prior call sites that did
|
|
215
|
+
* `.toFixed().replace(/\.?0+$/, '')` after `.sd()`).
|
|
216
|
+
*/
|
|
217
|
+
const toSignificantDigitsString = (value, sigDigits) => {
|
|
218
|
+
const { negative, intPart, fracPart } = splitSigned(value);
|
|
219
|
+
if (!hasNonZeroDigit(intPart) && !hasNonZeroDigit(fracPart))
|
|
220
|
+
return '0';
|
|
221
|
+
const signedStr = `${negative ? '-' : ''}${intPart}.${fracPart}`;
|
|
222
|
+
let dp = sigDigits - 1 - significantExponent(intPart, fracPart);
|
|
223
|
+
// Rounding can carry into an extra digit (e.g. 9.999 -> 10.0 at what was meant to be 3 sig
|
|
224
|
+
// figs), which yields one more significant digit than requested; detect it and re-round
|
|
225
|
+
// one decimal place tighter. Bounded loop: each iteration can only shift the exponent up by
|
|
226
|
+
// one, so this converges immediately in all but pathological all-nines inputs.
|
|
227
|
+
for (let i = 0; i < 4; i++) {
|
|
228
|
+
const rounded = toFixedString(signedStr, dp, 'halfUp');
|
|
229
|
+
const { intPart: rInt, fracPart: rFrac } = splitSigned(rounded);
|
|
230
|
+
const expectedExponent = sigDigits - 1 - dp;
|
|
231
|
+
if (significantExponent(rInt, rFrac) <= expectedExponent)
|
|
232
|
+
return rounded;
|
|
233
|
+
dp -= 1;
|
|
234
|
+
}
|
|
235
|
+
return toFixedString(signedStr, dp, 'halfUp');
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export { formatUnits, mulDivRound, parseUnits, toFixedString, toSignificantDigitsString };
|
|
239
|
+
//# sourceMappingURL=fixedPoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixedPoint.js","sources":["../../src/utils/fixedPoint.ts"],"sourcesContent":["// Fixed-point / decimal-string math built on native BigInt.\n//\n// Two distinct jobs, kept separate:\n// - parseUnits/formatUnits/mulDivRound operate on raw on-chain integer amounts\n// (wei-style, scaled by 10^decimals) — exact BigInt arithmetic.\n// - toFixedString/toSignificantDigitsString operate on already-human-scale\n// decimal numbers (prices, percentages) for display formatting/rounding.\n// BigInt has no notion of decimals, so these round via string/BigInt digit\n// manipulation instead of float scaling, to avoid classic float rounding\n// artifacts (e.g. naive `Math.round(x * 100) / 100`).\n\nexport type Rounding = 'floor' | 'ceil' | 'trunc'\nexport type DecimalRounding = Rounding | 'halfUp'\n\nconst DIGITS_RE = /^\\d*\\.?\\d*$/\n\nconst hasNonZeroDigit = (digits: string): boolean => /[1-9]/.test(digits)\n\nconst shouldRoundUp = (discarded: string, rounding: DecimalRounding, negative: boolean): boolean => {\n if (rounding === 'trunc') return false\n if (rounding === 'floor') return negative && hasNonZeroDigit(discarded)\n if (rounding === 'ceil') return !negative && hasNonZeroDigit(discarded)\n // halfUp (round half away from zero): only the first discarded digit matters.\n const firstDiscarded = discarded.charCodeAt(0) - 48\n return firstDiscarded >= 5\n}\n\n/**\n * Parses a human decimal string/number into a raw integer scaled by 10^decimals.\n * `rounding` controls what happens when the input has more fractional digits than\n * `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass\n * 'floor'/'ceil' where overspending or underspending the user's typed amount matters\n * (e.g. converting a typed amount to atomic units for a transaction).\n */\nexport const parseUnits = (\n value: string | number | undefined | null,\n decimals: number,\n rounding: DecimalRounding = 'halfUp',\n): bigint => {\n if (value === undefined || value === null || value === '') return 0n\n const raw = typeof value === 'number' ? value.toString() : value.trim()\n if (!raw) return 0n\n\n let negative = false\n let str = raw\n if (str.startsWith('-')) {\n negative = true\n str = str.slice(1)\n } else if (str.startsWith('+')) {\n str = str.slice(1)\n }\n\n if (!DIGITS_RE.test(str) || str === '' || str === '.') return 0n\n\n const [intPartRaw, fracPartRaw = ''] = str.split('.')\n const intPart = intPartRaw || '0'\n\n let combined: bigint\n if (fracPartRaw.length > decimals) {\n const keep = fracPartRaw.slice(0, decimals)\n const discarded = fracPartRaw.slice(decimals)\n combined = BigInt(intPart + keep || '0')\n if (shouldRoundUp(discarded, rounding, negative)) combined += 1n\n } else {\n const fracPart = fracPartRaw.padEnd(decimals, '0')\n combined = BigInt(intPart + fracPart || '0')\n }\n\n return negative && combined !== 0n ? -combined : combined\n}\n\n/** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */\nexport const formatUnits = (value: bigint | string | number | undefined | null, decimals: number): string => {\n let big: bigint\n try {\n if (typeof value === 'bigint') big = value\n else if (value === undefined || value === null || value === '') big = 0n\n else if (typeof value === 'number') big = BigInt(Math.trunc(value))\n else big = BigInt(value.trim())\n } catch {\n big = 0n\n }\n\n const negative = big < 0n\n const abs = negative ? -big : big\n const base = 10n ** BigInt(decimals)\n const intPart = abs / base\n const fracPart = abs % base\n\n let fracStr = decimals > 0 ? fracPart.toString().padStart(decimals, '0') : ''\n fracStr = fracStr.replace(/0+$/, '')\n\n const result = fracStr.length > 0 ? `${intPart}.${fracStr}` : `${intPart}`\n return negative && big !== 0n ? `-${result}` : result\n}\n\n/** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */\nexport const mulDivRound = (\n value: bigint,\n numerator: bigint,\n denominator: bigint,\n rounding: DecimalRounding = 'trunc',\n): bigint => {\n if (denominator === 0n) throw new Error('mulDivRound: division by zero')\n\n const product = value * numerator\n const quotient = product / denominator\n const remainder = product % denominator\n\n if (remainder === 0n || rounding === 'trunc') return quotient\n\n // Sign of the true (unrounded) mathematical quotient.\n const isNegative = product < 0n !== denominator < 0n\n\n if (rounding === 'floor') return isNegative ? quotient - 1n : quotient\n if (rounding === 'ceil') return isNegative ? quotient : quotient + 1n\n\n // halfUp (round half away from zero)\n const absRemainder = remainder < 0n ? -remainder : remainder\n const absDenominator = denominator < 0n ? -denominator : denominator\n const roundsUp = absRemainder * 2n >= absDenominator\n if (!roundsUp) return quotient\n return isNegative ? quotient - 1n : quotient + 1n\n}\n\n// Expands JS exponential notation (\"4.56e-8\") into a plain decimal string, via pure\n// string manipulation (shifting the decimal point) — never re-derives digits from the\n// underlying binary float, so no float-representation noise is introduced.\nconst expandExponential = (str: string): string => {\n const match = str.match(/^(-?)(\\d+)(?:\\.(\\d+))?e([+-]\\d+)$/i)\n if (!match) return str\n const [, sign, intDigits, fracDigits = '', expStr] = match\n const exp = parseInt(expStr, 10)\n const digits = intDigits + fracDigits\n const pointPos = intDigits.length + exp\n\n let result: string\n if (pointPos <= 0) {\n result = `0.${'0'.repeat(-pointPos)}${digits}`\n } else if (pointPos >= digits.length) {\n result = digits + '0'.repeat(pointPos - digits.length)\n } else {\n result = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`\n }\n return sign + result\n}\n\nconst toPlainDecimalString = (value: string | number): string => {\n if (typeof value === 'string') return value.trim() || '0'\n if (!Number.isFinite(value)) return '0'\n if (value === 0) return '0'\n // .toString() gives the shortest decimal that round-trips to this float (what a user\n // typing \"1.005\" would expect), as opposed to .toFixed(n) which re-derives the true\n // (noisy) binary expansion.\n const str = value.toString()\n return /e/i.test(str) ? expandExponential(str) : str\n}\n\nconst splitSigned = (value: string | number): { negative: boolean; intPart: string; fracPart: string } => {\n const str = toPlainDecimalString(value)\n const negative = str.startsWith('-')\n const unsigned = negative ? str.slice(1) : str\n const [intPartRaw, fracPartRaw = ''] = unsigned.split('.')\n return { negative, intPart: intPartRaw || '0', fracPart: fracPartRaw }\n}\n\n/**\n * Rounds the unsigned \"intPart.fracPart\" digit string to `dp` decimal places.\n * `dp` may be negative to round within the integer part (e.g. dp=-3 rounds to the nearest 1000).\n */\nconst roundDigits = (intPart: string, fracPart: string, dp: number, roundUp: boolean): string => {\n if (dp >= 0) {\n if (fracPart.length <= dp) {\n const paddedFrac = fracPart.padEnd(dp, '0')\n return dp > 0 ? `${intPart}.${paddedFrac}` : intPart\n }\n const keep = fracPart.slice(0, dp)\n let combined = BigInt(intPart + keep || '0')\n if (roundUp) combined += 1n\n const combinedStr = combined.toString().padStart(dp + 1, '0')\n const newInt = combinedStr.slice(0, combinedStr.length - dp) || '0'\n const newFrac = dp > 0 ? combinedStr.slice(combinedStr.length - dp) : ''\n return dp > 0 ? `${newInt}.${newFrac}` : newInt\n }\n\n // dp < 0: round within the integer part, discarding the fractional part entirely.\n const shift = -dp\n if (intPart.length <= shift) {\n const combined = roundUp ? 10n ** BigInt(shift) : 0n\n return combined.toString()\n }\n const keepLen = intPart.length - shift\n const keep = intPart.slice(0, keepLen)\n let combined = BigInt(keep || '0')\n if (roundUp) combined += 1n\n return combined.toString() + '0'.repeat(shift)\n}\n\n/**\n * Rounds a human-scale decimal value to `dp` decimal places, returned as a string.\n * Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt\n * based, so it doesn't inherit float rounding artifacts.\n */\nexport const toFixedString = (value: string | number, dp: number, rounding: DecimalRounding = 'halfUp'): string => {\n const { negative, intPart, fracPart } = splitSigned(value)\n const discarded = dp >= 0 ? fracPart.slice(dp) : intPart.slice(Math.max(intPart.length + dp, 0)) + fracPart\n const roundUp = shouldRoundUp(discarded, rounding, negative)\n const result = roundDigits(intPart, fracPart, dp, roundUp)\n const isZero = !hasNonZeroDigit(result)\n return negative && !isZero ? `-${result}` : result\n}\n\nconst significantExponent = (intPart: string, fracPart: string): number => {\n const intDigits = intPart.replace(/^0+/, '')\n if (intDigits.length > 0) return intDigits.length - 1\n const leadingZeros = fracPart.match(/^0*/)?.[0].length ?? 0\n if (leadingZeros >= fracPart.length) return 0 // value is zero\n return -(leadingZeros + 1)\n}\n\n/**\n * Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.\n * Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics\n * (does not strip trailing zeros, and never switches to exponential notation — callers that\n * want trimmed output should trim the result themselves, matching prior call sites that did\n * `.toFixed().replace(/\\.?0+$/, '')` after `.sd()`).\n */\nexport const toSignificantDigitsString = (value: string | number, sigDigits: number): string => {\n const { negative, intPart, fracPart } = splitSigned(value)\n if (!hasNonZeroDigit(intPart) && !hasNonZeroDigit(fracPart)) return '0'\n\n const signedStr = `${negative ? '-' : ''}${intPart}.${fracPart}`\n let dp = sigDigits - 1 - significantExponent(intPart, fracPart)\n\n // Rounding can carry into an extra digit (e.g. 9.999 -> 10.0 at what was meant to be 3 sig\n // figs), which yields one more significant digit than requested; detect it and re-round\n // one decimal place tighter. Bounded loop: each iteration can only shift the exponent up by\n // one, so this converges immediately in all but pathological all-nines inputs.\n for (let i = 0; i < 4; i++) {\n const rounded = toFixedString(signedStr, dp, 'halfUp')\n const { intPart: rInt, fracPart: rFrac } = splitSigned(rounded)\n const expectedExponent = sigDigits - 1 - dp\n if (significantExponent(rInt, rFrac) <= expectedExponent) return rounded\n dp -= 1\n }\n return toFixedString(signedStr, dp, 'halfUp')\n}\n"],"names":[],"mappings":"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"}
|