Skip to Content
Symmio Trading-SDK — the SDK surface for builders on Arbitrum
CoreUnified QuotesaggregateGroupFunding

aggregateGroupFunding

Fold the per-quote funding rows of a group’s children into a single QuoteGroupFunding. Pure, order-independent, no IO — fetch the rows with getQuoteFunding, then hand them to this.

import { aggregateGroupFunding, getQuoteFunding } from "@symmio/trading-core"; const quoteIds = group.quotes.flatMap((quote) => (quote.quoteId === undefined ? [] : [quote.quoteId])); const { rows } = await getQuoteFunding(config, { quoteIds }); const funding = aggregateGroupFunding(group.quotes, rows);

Sign convention

netReceived = received − paid, the P&L perspective every trading venue presents. A positive netReceived means the group has earned funding; a negative one means it has paid for it. This matches QuoteFundingData.netReceived and aggregateGroupUpnl, and is the inverse of the cost-positive on-chain int256.

A UI that renders “green = income” uses the value as-is — no negation anywhere. Every SDK funding amount uses this one convention — including the on-chain pending read, which the SDK negates for you — and flipping it in one place is how sign bugs get shipped. Raw per-unit rates such as FundingFee are passed through cost-positive; the sign table lists every surface.

Settled to date only

The totals cover funding the protocol has already charged and the analytics subgraph has indexed. Funding accrued since a quote’s last funding charge is not included — the subgraph does not index it. Read it on-chain with getQuotePendingFunding and show it as a separate figure: the two come from different sources at different heights, so do not add them into one lifetime total. Label this number accordingly (“funding paid to date”), not as a live accrual.

isComplete is not optional reading

netReceived is always the sum over the children that did resolve — a lower bound while rows are still missing, never suppressed to 0n. isComplete is the flag that tells you whether to trust it:

  • isComplete: true — every on-chain child produced a row; the amounts are the group’s complete settled-to-date funding.
  • isComplete: false — either the subgraph is still indexing (missingQuoteIds non-empty) or the group has no on-chain children at all. Treat this as “funding unknown” and render a loading/partial state; rendering it as “no funding” is wrong.

An all-optimistic group (every child still off-chain) and an empty group both report isComplete: false with netReceived: 0n — which is exactly why the flag exists.

Behaviour

  • De-duplicated by quoteId. The fold runs over the distinct on-chain ids among quotes, so a quote listed twice contributes its funding once. Duplicate rows for the same id in rows are likewise counted once (first row wins).
  • Optimistic children are skipped. A child with no quoteId has nothing to look up, so it neither inflates expectedCount nor lands in missingQuoteIds.
  • Extra rows are ignored. A row whose quoteId is not among the children is never summed — passing a shared, over-fetched row set is safe.
  • Empty input yields all-zero amounts with isComplete: false.

Do not substitute Σ UnifiedQuote.accumulatedPaidFunding as a shortcut. That field is the quote’s per-unit cumulative funding rate index on-chain, recorded at its last settlement — not a settled amount. Summing it across quotes is dimensionally meaningless, and it is cost-positive where netReceived is income-positive.

Parameters

The group’s child quotes (pass group.quotes). Optimistic children are allowed and are skipped.

rowsreadonly QuoteFundingData[]required

Funding rows fetched for those quotes — { quoteId, paid, received, netReceived }, all wei. Extras and duplicates are tolerated.

Returns

The aggregated funding for the group, plus the resolution counters and isComplete.

Last updated on