fix(trading): fills table fees display (#3071)
This commit is contained in:
parent
f54a629179
commit
3b3fcab4f4
@ -104,6 +104,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Total')}
|
||||
type="rightAligned"
|
||||
field="deposited"
|
||||
headerTooltip={t(
|
||||
'This is the total amount of collateral used plus the amount available in your general account.'
|
||||
@ -121,6 +122,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Used')}
|
||||
type="rightAligned"
|
||||
field="used"
|
||||
headerTooltip={t(
|
||||
'This is the amount of collateral used from your general account.'
|
||||
@ -139,6 +141,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
<AgGridColumn
|
||||
headerName={t('Available')}
|
||||
field="available"
|
||||
type="rightAligned"
|
||||
headerTooltip={t(
|
||||
'This is the amount of collateral available in your general account.'
|
||||
)}
|
||||
|
@ -5,7 +5,7 @@ import * as Schema from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { Trade } from './fills-data-provider';
|
||||
|
||||
import { FillsTable } from './fills-table';
|
||||
import { FillsTable, getFeesBreakdown } from './fills-table';
|
||||
import { generateFill } from './test-helpers';
|
||||
|
||||
describe('FillsTable', () => {
|
||||
@ -75,7 +75,7 @@ describe('FillsTable', () => {
|
||||
'1.00 BTC',
|
||||
'3.00 BTC',
|
||||
'Maker',
|
||||
'0.06 BTC',
|
||||
'2.00 BTC',
|
||||
getDateTimeFormat().format(new Date(buyerFill.createdAt)),
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
@ -176,4 +176,36 @@ describe('FillsTable', () => {
|
||||
await screen.findByTestId('fee-breakdown-tooltip')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('getFeesBreakdown', () => {
|
||||
it('should return correct fees breakdown for a taker', () => {
|
||||
const fees = {
|
||||
makerFee: '1000',
|
||||
infrastructureFee: '2000',
|
||||
liquidityFee: '3000',
|
||||
};
|
||||
const expectedBreakdown = {
|
||||
infrastructureFee: '2000',
|
||||
liquidityFee: '3000',
|
||||
makerFee: '1000',
|
||||
totalFee: '6000',
|
||||
};
|
||||
expect(getFeesBreakdown('TAKER', fees)).toEqual(expectedBreakdown);
|
||||
});
|
||||
|
||||
it('should return correct fees breakdown for a maker', () => {
|
||||
const fees = {
|
||||
makerFee: '1000',
|
||||
infrastructureFee: '2000',
|
||||
liquidityFee: '3000',
|
||||
};
|
||||
const expectedBreakdown = {
|
||||
infrastructureFee: '2000',
|
||||
liquidityFee: '3000',
|
||||
makerFee: '-1000',
|
||||
totalFee: '4000',
|
||||
};
|
||||
expect(getFeesBreakdown('MAKER', fees)).toEqual(expectedBreakdown);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -27,6 +27,10 @@ import type {
|
||||
import { forwardRef } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { Trade } from './fills-data-provider';
|
||||
import type { FillFieldsFragment } from './__generated__/Fills';
|
||||
|
||||
const TAKER = 'TAKER';
|
||||
const MAKER = 'MAKER';
|
||||
|
||||
export type Props = (AgGridReactProps | AgReactUiProps) & {
|
||||
partyId: string;
|
||||
@ -228,66 +232,132 @@ const formatFee = (partyId: string) => {
|
||||
return '-';
|
||||
}
|
||||
const asset = value.settlementAsset;
|
||||
let feesObj;
|
||||
if (data?.buyer.id === partyId) {
|
||||
feesObj = data?.buyerFee;
|
||||
} else if (data?.seller.id === partyId) {
|
||||
feesObj = data?.sellerFee;
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
const { fees: feesObj, role } = getRoleAndFees({ data, partyId });
|
||||
if (!feesObj) return '-';
|
||||
|
||||
const fee = new BigNumber(feesObj.makerFee)
|
||||
.plus(feesObj.infrastructureFee)
|
||||
.plus(feesObj.liquidityFee);
|
||||
const totalFees = addDecimalsFormatNumber(fee.toString(), asset.decimals);
|
||||
const { totalFee } = getFeesBreakdown(role, feesObj);
|
||||
const totalFees = addDecimalsFormatNumber(totalFee, asset.decimals);
|
||||
return `${totalFees} ${asset.symbol}`;
|
||||
};
|
||||
};
|
||||
|
||||
export const getRoleAndFees = ({
|
||||
data,
|
||||
partyId,
|
||||
}: {
|
||||
data: Pick<
|
||||
FillFieldsFragment,
|
||||
'buyerFee' | 'sellerFee' | 'buyer' | 'seller' | 'aggressor'
|
||||
>;
|
||||
partyId?: string;
|
||||
}) => {
|
||||
let role;
|
||||
let feesObj;
|
||||
if (data?.buyer.id === partyId) {
|
||||
role = data.aggressor === Schema.Side.SIDE_BUY ? TAKER : MAKER;
|
||||
feesObj = role === TAKER ? data?.buyerFee : data.sellerFee;
|
||||
} else if (data?.seller.id === partyId) {
|
||||
role = data.aggressor === Schema.Side.SIDE_SELL ? TAKER : MAKER;
|
||||
feesObj = role === TAKER ? data?.sellerFee : data.buyerFee;
|
||||
} else {
|
||||
return { role: '-', feesObj: '-' };
|
||||
}
|
||||
return { role, fees: feesObj };
|
||||
};
|
||||
|
||||
const FeesBreakdownTooltip = ({
|
||||
data,
|
||||
value,
|
||||
valueFormatted,
|
||||
partyId,
|
||||
}: ITooltipParams & { partyId?: string }) => {
|
||||
if (!value?.settlementAsset || !data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const asset = value.settlementAsset;
|
||||
let feesObj;
|
||||
if (data?.buyer.id === partyId) {
|
||||
feesObj = data?.buyerFee;
|
||||
} else if (data?.seller.id === partyId) {
|
||||
feesObj = data?.sellerFee;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { role, fees: feesObj } = getRoleAndFees({ data, partyId }) ?? {};
|
||||
if (!feesObj) return null;
|
||||
const { infrastructureFee, liquidityFee, makerFee, totalFee } =
|
||||
getFeesBreakdown(role, feesObj);
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid="fee-breakdown-tooltip"
|
||||
className="max-w-sm border border-neutral-600 bg-neutral-100 dark:bg-neutral-800 px-4 py-2 z-20 rounded text-sm break-word text-black dark:text-white"
|
||||
>
|
||||
<dl className="grid grid-cols-3 gap-x-1">
|
||||
{role === MAKER && (
|
||||
<>
|
||||
<p className="mb-1">{t('The maker will receive the maker fee.')}</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is in monitoring auction the maker will pay half of the infrastructure and liquidity fees.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is active the maker will pay zero infrastructure and liquidity fees.'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{role === TAKER && (
|
||||
<>
|
||||
<p className="mb-1">{t('Fees to be paid by the taker.')}</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is in monitoring auction the taker will pay half of the infrastructure and liquidity fees.'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<dl className="grid grid-cols-2 gap-x-1">
|
||||
<dt className="col-span-1">{t('Infrastructure fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.infrastructureFee, asset.decimals)}{' '}
|
||||
<dd className="text-right col-span-1">
|
||||
{addDecimalsFormatNumber(infrastructureFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
</dd>
|
||||
<dt className="col-span-1">{t('Liquidity fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.liquidityFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
<dd className="text-right col-span-1">
|
||||
{addDecimalsFormatNumber(liquidityFee, asset.decimals)} {asset.symbol}
|
||||
</dd>
|
||||
<dt className="col-span-1">{t('Maker fee')}</dt>
|
||||
<dd className="text-right col-span-2">
|
||||
{addDecimalsFormatNumber(feesObj.makerFee, asset.decimals)}{' '}
|
||||
{asset.symbol}
|
||||
<dd className="text-right col-span-1">
|
||||
{addDecimalsFormatNumber(makerFee, asset.decimals)} {asset.symbol}
|
||||
</dd>
|
||||
<dt className="col-span-1">{t('Total fees')}</dt>
|
||||
<dd className="text-right col-span-2">{valueFormatted}</dd>
|
||||
<dd className="text-right col-span-1">
|
||||
{addDecimalsFormatNumber(totalFee, asset.decimals)} {asset.symbol}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const getFeesBreakdown = (
|
||||
role: string,
|
||||
feesObj: {
|
||||
__typename?: 'TradeFee' | undefined;
|
||||
makerFee: string;
|
||||
infrastructureFee: string;
|
||||
liquidityFee: string;
|
||||
}
|
||||
) => {
|
||||
const makerFee =
|
||||
role === MAKER
|
||||
? new BigNumber(feesObj.makerFee).times(-1).toString()
|
||||
: feesObj.makerFee;
|
||||
const infrastructureFee = feesObj.infrastructureFee;
|
||||
const liquidityFee = feesObj.liquidityFee;
|
||||
|
||||
const totalFee = new BigNumber(infrastructureFee)
|
||||
.plus(makerFee)
|
||||
.plus(liquidityFee)
|
||||
.toString();
|
||||
return {
|
||||
infrastructureFee,
|
||||
liquidityFee,
|
||||
makerFee,
|
||||
totalFee,
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user