diff --git a/packages/ui-components/src/lib/services/historicalOrderCharts.ts b/packages/ui-components/src/lib/services/historicalOrderCharts.ts index 7fc7e9875c..09949f5420 100644 --- a/packages/ui-components/src/lib/services/historicalOrderCharts.ts +++ b/packages/ui-components/src/lib/services/historicalOrderCharts.ts @@ -48,7 +48,15 @@ export function prepareHistoricalOrderChartData( (acc, d) => acc + d.outputAmount, 0, ); - const ioratioAverage = ioratioSum / outputAmountSum; + const finiteValues = objectsWithSameTimestamp + .map((d) => d.value) + .filter((v) => isFinite(v)); + const ioratioAverage = + outputAmountSum === 0 + ? finiteValues.length > 0 + ? finiteValues.reduce((acc, v) => acc + v, 0) / finiteValues.length + : 0 + : ioratioSum / outputAmountSum; finalData.push({ value: ioratioAverage, time: timestamp, @@ -467,6 +475,87 @@ if (import.meta.vitest) { expect(result[0].value).toEqual(ioratioAverage); }); + it("falls back to zero when same-timestamp outputAmounts sum to zero and all ioratios are non-finite", () => { + // outputVaultBalanceChange.amount (BigInt) = 0 for both trades → outputAmountSum = 0. + // outputVaultBalanceChange.formattedAmount = "0" (consistent with amount = 0) → value = Infinity (non-finite). + // Fallback: filter non-finite values → empty → return 0. + const makeZeroAmountTrade = ( + id: `0x${string}`, + inputFormattedAmount: string, + ) => + ({ + id, + timestamp: BigInt(1632000000), + transaction: { + id: "tx", + from: "0xsender", + timestamp: BigInt(1632000000), + blockNumber: BigInt(0), + } as unknown as RaindexTransaction, + outputVaultBalanceChange: { + amount: BigInt(0), + formattedAmount: "0", + vaultId: BigInt(1), + __typename: "Withdraw", + token: { + id: "tok", + address: "0xtok", + name: "tok", + symbol: "tok", + decimals: BigInt(1), + } as unknown as RaindexVaultToken, + newBalance: BigInt(0), + formattedNewBalance: "0", + oldBalance: BigInt(0), + formattedOldBalance: "0", + timestamp: BigInt(0), + transaction: { + id: "tx", + from: "0xsender", + timestamp: BigInt(1632000000), + blockNumber: BigInt(0), + } as unknown as RaindexTransaction, + raindex: "0x1", + } as unknown as RaindexVaultBalanceChange, + orderHash: "0xorderHash" as `0x${string}`, + inputVaultBalanceChange: { + vaultId: BigInt(1), + token: { + id: "tok", + address: "0xtok", + name: "tok", + symbol: "tok", + decimals: BigInt(1), + } as unknown as RaindexVaultToken, + amount: BigInt(0), + formattedAmount: inputFormattedAmount, + __typename: "Withdraw", + newBalance: BigInt(0), + formattedNewBalance: "0", + oldBalance: BigInt(0), + formattedOldBalance: "0", + timestamp: BigInt(0), + transaction: { + id: "tx", + from: "0xsender", + timestamp: BigInt(1632000000), + blockNumber: BigInt(0), + } as unknown as RaindexTransaction, + raindex: "0x1", + } as unknown as RaindexVaultBalanceChange, + raindex: "0x00", + }) as unknown as RaindexTrade; + + const takeOrderEntities: RaindexTrade[] = [ + makeZeroAmountTrade("0x1", "200"), + makeZeroAmountTrade("0x2", "400"), + ]; + + const result = prepareHistoricalOrderChartData(takeOrderEntities, "dark"); + expect(result.length).toEqual(1); + expect(result[0].value).toEqual(0); + }); + // Minimal trade builder: prepareHistoricalOrderChartData only reads // timestamp, the two formattedAmount values and the output amount. const makeTrade = (args: {