fix: estimate order margin query asset decimal places fix (#2029)
* fix: estimate margin and fees update fix - use asset dp and normalize * fix: update styling in fees breakdown component * fix: fix cypress tests * fix: format with asset dp only in react components * fix: fix number formattingcd * fix: remove comment * fix: rename getMaximumDigitsNumberFormat * fix: fix console-lite cypress tests
This commit is contained in:
parent
d3cb3896f4
commit
011ea97d23
@ -266,10 +266,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
.find('dt')
|
.find('dt')
|
||||||
.eq(3)
|
.eq(3)
|
||||||
.should('have.text', 'Est. Fees (tDAI)');
|
.should('have.text', 'Est. Fees (tDAI)');
|
||||||
cy.get('#step-2-panel')
|
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
|
||||||
.find('dd')
|
|
||||||
.eq(3)
|
|
||||||
.should('have.text', '3.00000 (3.03%)');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -291,10 +288,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006');
|
||||||
|
|
||||||
cy.get('#step-3-panel')
|
cy.get('#step-3-panel').find('dd').eq(3).should('have.text', '3 (3.03%)');
|
||||||
.find('dd')
|
|
||||||
.eq(3)
|
|
||||||
.should('have.text', '3.00000 (3.03%)');
|
|
||||||
|
|
||||||
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - ');
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ import {
|
|||||||
toDecimal,
|
toDecimal,
|
||||||
removeDecimal,
|
removeDecimal,
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
|
addDecimalsNormalizeNumber,
|
||||||
|
addDecimal,
|
||||||
|
formatNumber,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
useOrderSubmit,
|
useOrderSubmit,
|
||||||
@ -142,6 +145,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|||||||
return null;
|
return null;
|
||||||
}, [market.decimalPlaces, order.size, price]);
|
}, [market.decimalPlaces, order.size, price]);
|
||||||
|
|
||||||
|
const assetDecimals =
|
||||||
|
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
||||||
|
|
||||||
const fees = useMemo(() => {
|
const fees = useMemo(() => {
|
||||||
if (estMargin?.totalFees && notionalSize) {
|
if (estMargin?.totalFees && notionalSize) {
|
||||||
const percentage = new BigNumber(estMargin?.totalFees)
|
const percentage = new BigNumber(estMargin?.totalFees)
|
||||||
@ -150,11 +156,14 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|||||||
.decimalPlaces(2)
|
.decimalPlaces(2)
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
return `${estMargin.totalFees} (${percentage}%)`;
|
return `${addDecimalsNormalizeNumber(
|
||||||
|
estMargin.totalFees,
|
||||||
|
assetDecimals
|
||||||
|
)} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, [estMargin?.totalFees, notionalSize]);
|
}, [assetDecimals, estMargin?.totalFees, notionalSize]);
|
||||||
|
|
||||||
const max = useMemo(() => {
|
const max = useMemo(() => {
|
||||||
return new BigNumber(maxTrade)
|
return new BigNumber(maxTrade)
|
||||||
|
@ -25,13 +25,15 @@ export const useOrderMarginValidation = ({ market, estMargin }: Props) => {
|
|||||||
partyBalance?.party?.accounts || [],
|
partyBalance?.party?.accounts || [],
|
||||||
AccountType.ACCOUNT_TYPE_GENERAL
|
AccountType.ACCOUNT_TYPE_GENERAL
|
||||||
);
|
);
|
||||||
|
const assetDecimals =
|
||||||
|
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
||||||
const balance = settlementAccount
|
const balance = settlementAccount
|
||||||
? toBigNum(
|
? toBigNum(
|
||||||
settlementAccount.balance || 0,
|
settlementAccount.balance || 0,
|
||||||
settlementAccount.asset.decimals || 0
|
settlementAccount.asset.decimals || 0
|
||||||
)
|
)
|
||||||
: toBigNum('0', 0);
|
: toBigNum('0', assetDecimals);
|
||||||
const margin = toBigNum(estMargin?.margin || 0, 0);
|
const margin = toBigNum(estMargin?.margin || 0, assetDecimals);
|
||||||
const { id, symbol, decimals } =
|
const { id, symbol, decimals } =
|
||||||
market.tradableInstrument.instrument.product.settlementAsset;
|
market.tradableInstrument.instrument.product.settlementAsset;
|
||||||
const balanceString = balance.toString();
|
const balanceString = balance.toString();
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { FeesBreakdown } from '@vegaprotocol/market-info';
|
import { FeesBreakdown } from '@vegaprotocol/market-info';
|
||||||
import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers';
|
import {
|
||||||
|
addDecimalsNormalizeNumber,
|
||||||
|
normalizeFormatNumber,
|
||||||
|
t,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
@ -96,6 +100,8 @@ export const getFeeDetailsValues = ({
|
|||||||
estCloseOut,
|
estCloseOut,
|
||||||
market,
|
market,
|
||||||
}: FeeDetails) => {
|
}: FeeDetails) => {
|
||||||
|
const assetDecimals =
|
||||||
|
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
||||||
const formatValueWithMarketDp = (
|
const formatValueWithMarketDp = (
|
||||||
value: string | number | null | undefined
|
value: string | number | null | undefined
|
||||||
): string => {
|
): string => {
|
||||||
@ -107,10 +113,7 @@ export const getFeeDetailsValues = ({
|
|||||||
value: string | number | null | undefined
|
value: string | number | null | undefined
|
||||||
): string => {
|
): string => {
|
||||||
return value && !isNaN(Number(value))
|
return value && !isNaN(Number(value))
|
||||||
? normalizeFormatNumber(
|
? addDecimalsNormalizeNumber(value, assetDecimals)
|
||||||
value,
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.decimals
|
|
||||||
)
|
|
||||||
: '-';
|
: '-';
|
||||||
};
|
};
|
||||||
return [
|
return [
|
||||||
@ -136,6 +139,7 @@ export const getFeeDetailsValues = ({
|
|||||||
fees={estMargin?.fees}
|
fees={estMargin?.fees}
|
||||||
feeFactors={market.fees.factors}
|
feeFactors={market.fees.factors}
|
||||||
quoteName={quoteName}
|
quoteName={quoteName}
|
||||||
|
decimals={assetDecimals}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
@ -52,6 +52,15 @@ describe('useOrderMargin', () => {
|
|||||||
price: '1000000',
|
price: '1000000',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
product: {
|
||||||
|
settlementAsset: {
|
||||||
|
decimals: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const partyId = 'partyId';
|
const partyId = 'partyId';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
import { addDecimal, removeDecimal } from '@vegaprotocol/react-helpers';
|
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { useMarketPositions } from './use-market-positions';
|
import { useMarketPositions } from './use-market-positions';
|
||||||
import { useMarketDataMarkPrice } from './use-market-data-mark-price';
|
import { useMarketDataMarkPrice } from './use-market-data-mark-price';
|
||||||
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
import type { EstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||||
@ -37,6 +37,7 @@ export const useOrderMargin = ({
|
|||||||
}: Props): OrderMargin | null => {
|
}: Props): OrderMargin | null => {
|
||||||
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
const marketPositions = useMarketPositions({ marketId: market.id, partyId });
|
||||||
const markPriceData = useMarketDataMarkPrice(market.id);
|
const markPriceData = useMarketDataMarkPrice(market.id);
|
||||||
|
|
||||||
const { data } = useEstimateOrderQuery({
|
const { data } = useEstimateOrderQuery({
|
||||||
variables: {
|
variables: {
|
||||||
marketId: market.id,
|
marketId: market.id,
|
||||||
@ -79,12 +80,12 @@ export const useOrderMargin = ({
|
|||||||
const { makerFee, liquidityFee, infrastructureFee } =
|
const { makerFee, liquidityFee, infrastructureFee } =
|
||||||
data.estimateOrder.fee;
|
data.estimateOrder.fee;
|
||||||
return {
|
return {
|
||||||
margin: addDecimal(margin, market.decimalPlaces),
|
margin,
|
||||||
totalFees: addDecimal(fees, market.decimalPlaces),
|
totalFees: fees,
|
||||||
fees: {
|
fees: {
|
||||||
makerFee: addDecimal(makerFee, market.decimalPlaces),
|
makerFee,
|
||||||
liquidityFee: addDecimal(liquidityFee, market.decimalPlaces),
|
liquidityFee,
|
||||||
infrastructureFee: addDecimal(infrastructureFee, market.decimalPlaces),
|
infrastructureFee,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { totalFeesPercentage } from '@vegaprotocol/market-list';
|
import { totalFeesPercentage } from '@vegaprotocol/market-list';
|
||||||
import { formatNumberPercentage, t } from '@vegaprotocol/react-helpers';
|
import {
|
||||||
|
addDecimalsNormalizeNumber,
|
||||||
|
formatNumberPercentage,
|
||||||
|
t,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
@ -48,6 +52,7 @@ export const FeesBreakdown = ({
|
|||||||
fees,
|
fees,
|
||||||
feeFactors,
|
feeFactors,
|
||||||
quoteName,
|
quoteName,
|
||||||
|
decimals,
|
||||||
}: {
|
}: {
|
||||||
fees?: {
|
fees?: {
|
||||||
infrastructureFee: string;
|
infrastructureFee: string;
|
||||||
@ -56,53 +61,61 @@ export const FeesBreakdown = ({
|
|||||||
};
|
};
|
||||||
feeFactors?: Market['fees']['factors'];
|
feeFactors?: Market['fees']['factors'];
|
||||||
quoteName?: string;
|
quoteName?: string;
|
||||||
|
decimals: number;
|
||||||
}) => {
|
}) => {
|
||||||
if (!fees) return null;
|
if (!fees) return null;
|
||||||
const totalFees = new BigNumber(fees.makerFee)
|
const totalFees = new BigNumber(fees.makerFee)
|
||||||
.plus(fees.infrastructureFee)
|
.plus(fees.infrastructureFee)
|
||||||
.plus(fees.liquidityFee)
|
.plus(fees.liquidityFee)
|
||||||
.toString();
|
.toString();
|
||||||
|
const formatValue = (value: string | number | null | undefined): string => {
|
||||||
|
return value && !isNaN(Number(value))
|
||||||
|
? addDecimalsNormalizeNumber(value, decimals)
|
||||||
|
: '-';
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<dl className="grid grid-cols-3 gap-x-3">
|
<dl className="grid grid-cols-5">
|
||||||
<dt>{t('Infrastructure fee')}</dt>
|
<dt className="col-span-2">{t('Infrastructure fee')}</dt>
|
||||||
{feeFactors && (
|
{feeFactors && (
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-1">
|
||||||
{formatNumberPercentage(
|
{formatNumberPercentage(
|
||||||
new BigNumber(feeFactors.infrastructureFee).times(100)
|
new BigNumber(feeFactors.infrastructureFee).times(100)
|
||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
)}
|
)}
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-2">
|
||||||
{fees.infrastructureFee} {quoteName || ''}
|
{formatValue(fees.infrastructureFee)} {quoteName || ''}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>{t('Liquidity fee')}</dt>
|
<dt className="col-span-2">{t('Liquidity fee')}</dt>
|
||||||
{feeFactors && (
|
{feeFactors && (
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-1">
|
||||||
{formatNumberPercentage(
|
{formatNumberPercentage(
|
||||||
new BigNumber(feeFactors.liquidityFee).times(100)
|
new BigNumber(feeFactors.liquidityFee).times(100)
|
||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
)}
|
)}
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-2">
|
||||||
{fees.liquidityFee} {quoteName || ''}
|
{formatValue(fees.liquidityFee)} {quoteName || ''}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>{t('Maker fee')}</dt>
|
<dt className="col-span-2">{t('Maker fee')}</dt>
|
||||||
{feeFactors && (
|
{feeFactors && (
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-1">
|
||||||
{formatNumberPercentage(
|
{formatNumberPercentage(
|
||||||
new BigNumber(feeFactors.makerFee).times(100)
|
new BigNumber(feeFactors.makerFee).times(100)
|
||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
)}
|
)}
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-2">
|
||||||
{fees.makerFee} {quoteName || ''}
|
{formatValue(fees.makerFee)} {quoteName || ''}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>{t('Total fees')}</dt>
|
<dt className="col-span-2">{t('Total fees')}</dt>
|
||||||
{feeFactors && (
|
{feeFactors && (
|
||||||
<dd className="text-right">{totalFeesPercentage(feeFactors)}</dd>
|
<dd className="text-right col-span-1">
|
||||||
|
{totalFeesPercentage(feeFactors)}
|
||||||
|
</dd>
|
||||||
)}
|
)}
|
||||||
<dd className="text-right">
|
<dd className="text-right col-span-2">
|
||||||
{totalFees} {quoteName || ''}
|
{formatValue(totalFees)} {quoteName || ''}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
);
|
);
|
||||||
|
@ -14,9 +14,9 @@ describe('number react-helpers', () => {
|
|||||||
it.each([
|
it.each([
|
||||||
{ v: new BigNumber(123000), d: 5, o: '1.23' },
|
{ v: new BigNumber(123000), d: 5, o: '1.23' },
|
||||||
{ v: new BigNumber(123000), d: 3, o: '123' },
|
{ v: new BigNumber(123000), d: 3, o: '123' },
|
||||||
{ v: new BigNumber(123000), d: 1, o: '12,300.0' },
|
{ v: new BigNumber(123000), d: 1, o: '12,300' },
|
||||||
{ v: new BigNumber(123001), d: 2, o: '1,230.01' },
|
{ v: new BigNumber(123001), d: 2, o: '1,230.01' },
|
||||||
{ v: new BigNumber(123001000), d: 2, o: '1,230,010.00' },
|
{ v: new BigNumber(123001000), d: 2, o: '1,230,010' },
|
||||||
])(
|
])(
|
||||||
'formats with addDecimalsNormalizeNumber given number correctly',
|
'formats with addDecimalsNormalizeNumber given number correctly',
|
||||||
({ v, d, o }) => {
|
({ v, d, o }) => {
|
||||||
|
@ -49,6 +49,15 @@ export const getNumberFormat = memoize((digits: number) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const getMaximumDigitsNumberFormat = memoize((digits: number) => {
|
||||||
|
if (isNil(digits) || digits < 0) {
|
||||||
|
return new Intl.NumberFormat(getUserLocale());
|
||||||
|
}
|
||||||
|
return new Intl.NumberFormat(getUserLocale(), {
|
||||||
|
maximumFractionDigits: Math.min(Math.max(0, digits), MAX_FRACTION_DIGITS),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
export const getDecimalSeparator = memoize(
|
export const getDecimalSeparator = memoize(
|
||||||
() =>
|
() =>
|
||||||
getNumberFormat(1)
|
getNumberFormat(1)
|
||||||
@ -75,13 +84,10 @@ export const normalizeFormatNumber = (
|
|||||||
rawValue: string | number | BigNumber,
|
rawValue: string | number | BigNumber,
|
||||||
formatDecimals = 0
|
formatDecimals = 0
|
||||||
): string => {
|
): string => {
|
||||||
const numberToFormat = getNumberFormat(formatDecimals).format(
|
const numberToFormat = getMaximumDigitsNumberFormat(formatDecimals).format(
|
||||||
Number(rawValue)
|
new BigNumber(rawValue).toNumber()
|
||||||
);
|
);
|
||||||
// Multiplying by 1 safely removes the insignificant trailing zeros from the formatted number
|
return numberToFormat;
|
||||||
return !isNaN(Number(numberToFormat))
|
|
||||||
? (Number(numberToFormat) * 1).toString()
|
|
||||||
: numberToFormat;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addDecimalsFormatNumber = (
|
export const addDecimalsFormatNumber = (
|
||||||
|
Loading…
Reference in New Issue
Block a user