> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superearn.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Balances, cost and returns

> Accounting models, the 4 core audit invariants, cost basis, PnL recognition, and partner audit FAQs.

[Scalar API reference](https://api.superearn.io/v1/docs) · [Data API overview](/en/developers/data-access) · [Integration patterns](/en/developers/data-api) · [Valuation and harvest reporting](/en/developers/accrual-accounting) · [Reconciliation walkthrough](/en/developers/reconciliation-guide)

## TL;DR

**Call `GET /v1/earnings` to obtain a complete financial statement for any reporting period.** Select `account` and `vault`, then choose your start and end dates.

For each period in `data[]`, read the following fields in each `assets[]` entry:

| Financial Question                               | API Field                                  | Accounting Meaning                                                                                                                      |
| ------------------------------------------------ | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| How much did I hold at the start/end?            | `opening.totalValue`, `closing.totalValue` | Total balance sheet assets, including pending claims                                                                                    |
| How many vault shares do I hold?                 | `shares`                                   | Raw vault share token balance (before redemption/burn)                                                                                  |
| What are the share token details?                | `shareToken`                               | Share token metadata (`chainId`, `address`, `symbol`, `decimals`)                                                                       |
| What are the active position and pending claims? | `positionValue`, `redemptionReceivable`    | Active earning assets vs non-earning claimable assets                                                                                   |
| What cost remains in active shares?              | `costBasis`                                | Historical acquisition cost allocated to remaining active shares                                                                        |
| What unrealized PnL remains?                     | `unrealizedPnl`                            | Active position value less remaining cost basis                                                                                         |
| How much net profit did I earn?                  | `pnl`                                      | Net economic profit after netting external capital flows                                                                                |
| How much PnL was realized?                       | `realizedPnl`                              | Confirmed gain on redemptions/disposals less allocated cost                                                                             |
| How did unrealized PnL change?                   | `unrealizedPnlChange`                      | Closing unrealized PnL less opening unrealized PnL                                                                                      |
| How much unrealized PnL entered via transfers?   | `netTransferredUnrealizedPnl`              | Net embedded unrealized gain carried in/out via share transfers                                                                         |
| What true return did this period earn?           | `return.periodRate`                        | Ground truth period return (True TWR); multiply by 100 for %                                                                            |
| What is its official linear annual rate?         | `return.apr`                               | ACT/365 linear annualization (standard across all windows)                                                                              |
| What is its compound annual rate?                | `return.apy`                               | ACT/365 compound rate (computed for every period with a defined return; below 7 days a hypothetical extrapolation, prefer `return.apr`) |
| Which return method was used?                    | `return.method`                            | `time_weighted` (True TWR across every external flow)                                                                                   |

**Verification rules before closing statements**

* **Total Balance**: `totalValue = positionValue + redemptionReceivable`
* **Shares vs Value**: `shares` represents the vault LP share token balance (`shareToken` unit), while `positionValue` represents those shares valued in underlying assets (`shares × PPS`, `asset` unit).
* **Pending Redemption Units**: `redemptionReceivable` is denominated in **underlying asset units (`asset`)**, NOT share tokens. Upon redemption, shares are burned/locked and the exact asset claim is deposited into the CooldownVault, so it sums directly with `positionValue`.
* **Cost Basis**: Tracks historical acquisition cost of active shares using pro-rata moving average cost.
* **Unrealized PnL Change**: A period flow (`closing - opening`), whereas `opening.unrealizedPnl` and `closing.unrealizedPnl` are boundary balance sheet stocks.
* **Rate conventions**: Present `return.periodRate` and `return.apr` first. `return.apy` is computed for every period with a defined return; below 7 days it is a hypothetical annual extrapolation, so prefer `return.apr` and `return.periodRate` for short windows.
* **Preserve nulls**: Check `quality.status` and `quality.reasons`. Missing historical evidence leaves dependent fields as `null`. Preserve these `null`s rather than converting them to zero.

## API Request & Response Field Reference

Key request parameters and response fields for the unified financial endpoints `GET /v1/balances` and `GET /v1/earnings`. For the interactive OpenAPI specification and live testing, see the [Scalar API reference](https://api.superearn.io/v1/docs).

### Unit System

All numerical quantities in SuperEarn adhere to rigorous unit definitions:

| Unit Annotation          | Applicable Fields                                                                                                                                                                      | Definition & Scope                                                                                                                |
| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| **`[Unit: asset]`**      | `totalValue`, `positionValue`, `redemptionReceivable`, `costBasis`, `unrealizedPnl`, `inflows`, `outflows`, `pnl`, `realizedPnl`, `unrealizedPnlChange`, `netTransferredUnrealizedPnl` | Vault underlying asset currency unit (e.g. USDT, JPYC). Serves as the numeraire for portfolio valuation and statutory accounting. |
| **`[Unit: shareToken]`** | `shares`                                                                                                                                                                               | Vault LP share ERC-20 token unit (e.g. EarnUSDT, EarnJPYC). Raw share token balance held by the wallet.                           |
| **`[Unit: ratio]`**      | `return.periodRate`, `return.apr`, `return.apy`                                                                                                                                        | Dimensionless percentage decimal ratio (1.0 = 100%).                                                                              |

### `GET /v1/balances` (Point-in-Time Balance Snapshot)

Queries asset valuation and balance composition at a specific confirmed block (for balance sheet reporting).

#### Request Parameters

| Parameter   |   Required   | Type                     | Default | Description                                                                                                                |
| ----------- | :----------: | ------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| `at`        | **Required** | ISO-8601                 | -       | Target snapshot timestamp (e.g. `2026-09-01T00:00:00Z`). Uses the latest confirmed block strictly before this instant.     |
| `account`   |   Optional   | Address (`0x...`)        | all     | Target wallet address. Omit to aggregate all share holders (including fee shares).                                         |
| `vault`     |   Optional   | Vault ID                 | all     | Target vault ID (`eip155:8217:0x...`). Omit to aggregate all published vaults.                                             |
| `valuation` |   Optional   | `pps` \| `estimated_nav` | `pps`   | Valuation basis (`pps`: official vault share-value arithmetic / `estimated_nav`: includes unharvested strategy estimates). |
| `include`   |   Optional   | `reconciliation`         | -       | Includes underlying reported-asset reconciliation evidence.                                                                |

#### Response Fields (`data[].assets[]`)

| Field                  |     Unit     | Type                   | Accounting Meaning & Definition                                                                                     |                               |
| ---------------------- | :----------: | ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| `totalValue`           |    `asset`   | Decimal String         | **Total Managed Assets** = `positionValue` + `redemptionReceivable`. (Excludes unmanaged wallet cash).              |                               |
| `shares`               | `shareToken` | Decimal String \| null | **Active Share Balance** (Raw vault share ERC-20 tokens held. `null` or `0` if none).                               |                               |
| `shareToken`           |       -      | Object \| null         | **Share Token Metadata** (`chainId`, `address`, `symbol`, `decimals`).                                              |                               |
| `positionValue`        |    `asset`   | Decimal String         | **Active Position Value** (Earning vault shares valued at confirmed PPS, `shares × PPS`).                           |                               |
| `redemptionReceivable` |    `asset`   | Decimal String         | **Pending Redemption Receivables** (Principal locked in cooldown or ready to claim. Non-earning fixed claim).       |                               |
| `costBasis`            |    `asset`   | Decimal String \| null | **Remaining Cost Basis** (Pro-rata moving average cost allocated to remaining active shares. `null` if unverified). |                               |
| `unrealizedPnl`        |    `asset`   | Decimal String \| null | **Cumulative Unrealized PnL** = `positionValue - costBasis`.                                                        |                               |
| `block`                |       -      | Object                 | Target confirmed block evidence (`number`, `hash`, `timestamp`).                                                    |                               |
| `quality`              |       -      | Object                 | Completeness status (\`status: "complete"                                                                           | "partial"`, `reasons: \[]\`). |

***

### `GET /v1/earnings` (Period PnL and Returns)

Queries balance sheet changes, capital flows, realized/unrealized PnL, and period returns across any interval (for income statement reporting).

#### Request Parameters

| Parameter   |   Required   | Type                                          | Default    | Description                                                                                       |
| ----------- | :----------: | --------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------- |
| `start`     | **Required** | ISO-8601 / Date                               | -          | Inclusive start instant or date (`[start, end)`).                                                 |
| `end`       | **Required** | ISO-8601 / Date                               | -          | Exclusive end instant or date. Must be after `start`.                                             |
| `account`   |   Optional   | Address (`0x...`)                             | all        | Target wallet address.                                                                            |
| `vault`     |   Optional   | Vault ID                                      | all        | Target vault ID (`eip155:8217:0x...`).                                                            |
| `interval`  |   Optional   | `all` \| `hour` \| `day` \| `week` \| `month` | `all`      | Calendar interval (`all`: single aggregated period, `hour`: 1 hour, `day`: 1 calendar day, etc.). |
| `timezone`  |   Optional   | IANA name / Offset                            | `UTC`      | Calendar timezone (e.g. `Asia/Seoul`, `+09:00`).                                                  |
| `cutoff`    |   Optional   | `HH:mm:ss`                                    | `00:00:00` | Local business closing time (e.g. `09:00:00` splits days at 09:00 local time).                    |
| `valuation` |   Optional   | `pps` \| `estimated_nav`                      | `pps`      | Valuation basis.                                                                                  |
| `limit`     |   Optional   | Integer (1\~100)                              | `20`       | Maximum rows per page (omitted for `interval=all`).                                               |
| `cursor`    |   Optional   | String                                        | -          | Pagination continuation cursor (`page.nextCursor`).                                               |

#### Response Fields (`data[].assets[]`)

| Field                         |   Unit  | Type                   | Accounting Meaning & Definition                                                                                                                                                                                                                                                                                               |
| ----------------------------- | :-----: | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `opening`                     |    -    | Object                 | **Beginning Balance Snapshot** (`totalValue`, `shares`, `positionValue`, `costBasis`, etc. at start).                                                                                                                                                                                                                         |
| `closing`                     |    -    | Object                 | **Ending Balance Snapshot** (`totalValue`, `shares`, `positionValue`, `costBasis`, etc. at end).                                                                                                                                                                                                                              |
| `shareToken`                  |    -    | Object \| null         | **Share Token Metadata** (`chainId`, `address`, `symbol`, `decimals`).                                                                                                                                                                                                                                                        |
| `inflows`                     | `asset` | Decimal String \| null | **External Capital Inflows** (Sum of positive transaction-net external flows: deposits and, in wallet scope, inbound share transfers valued at the transfer operation. Not gross deposit volume).                                                                                                                             |
| `outflows`                    | `asset` | Decimal String \| null | **External Capital Outflows** (Absolute sum of negative transaction-net external flows: redemption payments recognized when the claim is paid and, in wallet scope, outbound share transfers valued at the transfer operation. Not gross withdrawal volume).                                                                  |
| `pnl`                         | `asset` | Decimal String \| null | **Period Net PnL** = `closing.totalValue - opening.totalValue - inflows + outflows`.                                                                                                                                                                                                                                          |
| `realizedPnl`                 | `asset` | Decimal String \| null | **Confirmed Realized Gain** (Disposal proceeds less allocated cost basis).                                                                                                                                                                                                                                                    |
| `unrealizedPnlChange`         | `asset` | Decimal String \| null | **Unrealized PnL Delta** = `closing.unrealizedPnl - opening.unrealizedPnl`.                                                                                                                                                                                                                                                   |
| `netTransferredUnrealizedPnl` | `asset` | Decimal String \| null | **Transferred Unrealized Gain** (Embedded paper gain carried via inbound/outbound share transfers).                                                                                                                                                                                                                           |
| `return.periodRate`           | `ratio` | Decimal String         | **True Period Return** (True Time-Weighted Return ratio. Multiply by 100 for %).                                                                                                                                                                                                                                              |
| `return.apr`                  | `ratio` | Decimal String         | **Linear Annualized Rate** (ACT/365 linear annual rate = `periodRate × 365 / days`).                                                                                                                                                                                                                                          |
| `return.apy`                  | `ratio` | Decimal String \| null | **Compound Annualized Rate** (ACT/365 compound annual rate = `(1 + periodRate) ^ (31,536,000 / elapsed seconds) - 1`, computed for every period with a defined return. `null` only when the return is unavailable or the result cannot be represented. Below 7 days it is a hypothetical extrapolation; prefer `return.apr`). |
| `return.method`               |    -    | String                 | Return calculation methodology (`time_weighted`).                                                                                                                                                                                                                                                                             |
| `quality`                     |    -    | Object                 | Data completeness and reconciliation quality.                                                                                                                                                                                                                                                                                 |

## The 4 core audit invariants

The SuperEarn accounting model operates on **4 core audit invariants**. Partner finance teams and external auditors can use these identities to independently verify and reconcile balances, flows, and cost basis.

| Area                         | Audit Invariant                                                                 | Economic Substance Guaranteed                                                                                                                                               |
| :--------------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1. Balance Sheet Asset**   | `totalValue = positionValue + redemptionReceivable`                             | Active earning assets plus non-earning claimable receivables equal total assets (`positionValue = shares × PPS`)                                                            |
| **2. Balance Sheet Cost**    | `positionValue = costBasis + unrealizedPnl`                                     | Active position value decomposes into remaining cost basis and cumulative unrealized gain                                                                                   |
| **3. Income Statement Flow** | `pnl = realizedPnl + unrealizedPnlChange - netTransferredUnrealizedPnl`         | Period net PnL decomposes into realized gain, paper gain delta, and transfer adjustments                                                                                    |
| **4. Lifetime Ledger**       | `pnl = closing.totalValue + outflows - inflows` (when `opening.totalValue = 0`) | Lifetime net profit equals current assets + lifetime `outflows` - lifetime `inflows`. This is the period PnL identity with a zero opening balance, not an independent check |

**Reading the lifetime ledger**

* Call `GET /v1/earnings` with `interval=all` and a `start` at or before the account's first activity, so that `opening.totalValue` is 0. Take `start` from `openedAt` on `GET /v1/accounts/{account}/positions` (any earlier instant also works) and set `end` to the reporting boundary. The row's `inflows`, `outflows` and `pnl` are then the lifetime totals.
* `inflows` and `outflows` are netted per transaction, recognize withdrawals when the redemption claim is paid, and in wallet scope include share transfers valued at the vault share value at the transfer operation. They are not total cash deposited or withdrawn. For a [custody migration](#partner-accounting-faq), the migrated shares enter the receiver's `inflows` at value: e.g. an inflow of 21,509,075.692925 = carried cost 21,503,019.316660 + embedded gain 6,056.376265, where the gain is reported in `netTransferredUnrealizedPnl`.
* `null` `inflows`, `outflows` or `pnl` mean the check is not evaluable for that row (see `quality.reasons`), not that it failed.
* Do not mix these figures with `totalEarnings` from `/v1/accounts/{account}/positions`; the two figures are computed differently and do not reconcile.
* The lifetime read can take 10 seconds or more uncached; run it as its own request.

### Scope

| Balance/earnings scope | Filters   | Coverage                                                                               |
| ---------------------- | --------- | -------------------------------------------------------------------------------------- |
| **Protocol**           | Omit both | Managed assets of all share holders across published root vaults, including fee shares |
| **Vault**              | `vault`   | All share holders in that root vault, including fee shares                             |
| **Wallet**             | `account` | That wallet across published root vaults                                               |
| **Wallet–vault**       | Both      | That wallet in one root vault                                                          |

**Key points**

* Resolve the chain-qualified `vault.id` through `/v1/vaults`; retain inactive holdings.
* Each asset has its own `{chainId, address, decimals}`. Combine amounts only within that identity.
* A wallet scope follows its on-chain address. Beneficial-owner consolidation requires verified address ownership, effective dates and transfer links in a separate partner ledger. A transfer alone establishes no common-owner mapping.
* Omitting `account` aggregates holder investment performance. Operator revenue requires a separate accounting scope; strategy gain/loss comes from [harvest reports](/en/developers/accrual-accounting#harvest-to-investor-earnings).

### One request: a KST daily report

For a September 8 KST close, select the wallet and Vault, September 8–9, a daily interval and `Asia/Seoul`. Use the [earnings reference](https://api.superearn.io/v1/docs#tag/earnings/GET/earnings) for the exact request.

**Reconcile each asset row**

* `closing.totalValue = opening.totalValue + inflows - outflows + pnl`
* With complete cost/PnL evidence: `pnl = realizedPnl + unrealizedPnlChange - netTransferredUnrealizedPnl`
* The example closes at September 9 00:00 KST; the next day opening uses the same boundary. `opening.block` / `closing.block` identify the confirmed states strictly before those times.

### Change the reporting period

| Report             | Parameters                                                         |
| ------------------ | ------------------------------------------------------------------ |
| One whole period   | Omit `interval`; read one combined period                          |
| Exact KST day      | `start=2026-09-01T00:00:00+09:00`, `end=2026-09-02T00:00:00+09:00` |
| Daily UTC          | Date pair + `interval=day`; timezone defaults to `UTC`             |
| Daily KST          | Date pair + `interval=day&timezone=Asia/Seoul`                     |
| Monthly KST        | Date pair + `interval=month&timezone=Asia/Seoul`                   |
| Fixed UTC+05:45    | Date pair + `timezone=+05:45`                                      |
| Hourly             | Either pair + `interval=hour`                                      |
| Custom local close | Date pair or calendar interval + `cutoff=HH:mm:ss`                 |

**Key points**

* KST daily/monthly reports follow the selected local calendar. IANA zones track DST; fixed offsets keep a constant clock rule.
* For daily/monthly holdings, read every row `opening` and `closing`; use `interval=hour` for hourly boundaries. A time-weighted average holding needs a separate calculation policy.
* Query any full period with `interval` omitted. Matching adjacent TWRs link geometrically: `1 + full-period rate = Product(1 + row rate)`. Require the same scope, valuation, policy and complete evidence; preserve precision and query the whole period for its annual equivalents.
* Read every page before closing a report. Preserve the query, response and evidence with the export.
* Exact input combinations, field definitions and error conditions: [earnings](https://api.superearn.io/v1/docs#tag/earnings/GET/earnings) · [balances](https://api.superearn.io/v1/docs#tag/balances/GET/balances).

### Valuation and return availability

| Selected valuation / flows                                  | Available result                                                                                                                                                                |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PPS, with external flows                                    | True TWR requires verified portfolio values around every external-flow operation; missing evidence leaves rates null                                                            |
| Estimated NAV, without external flows                       | Supported from verified opening/closing NAV with valid capital; verified internal replacements remain internal                                                                  |
| Estimated NAV, with external flows                          | Operation NAV states are unavailable; rates are null with `twr_nav_flow_state_unavailable`. Verified cash flows can still support PnL                                           |
| Estimated NAV, external share transfer without its NAV mark | `inflows`, `outflows`, `pnl` and `netTransferredUnrealizedPnl` are null. Verified `costBasis`, independently known `realizedPnl` and raw `unrealizedPnlChange` remain available |

Read `quality` for the specific evidence gap. An unavailable rate stays null through annualization; see [period return](#period-return) for capital and linking rules.

**Claim receivers:** The index lacks complete historical receiver lineage, so a canonical range check screens for relevant changes. Wallet periods affected by `RedeemReceiverUpdated`, including changes out and back, return `receiver_change_unsupported`: dependent money and rates are null while independently verified boundary holdings, active cost and unrealized balances remain available. `receiver_change_collection_pending` is retryable; retries reuse stored progress. Reassignment between included receivers remains internal to whole-holder scope.

## Boundary value

Snapshots for a requested boundary timestamp `T` are taken at the latest canonical confirmed block strictly before `T`.

At that block, total balance is the sum of active positions and pending redemptions:

```text theme={null}
Total Balance (totalValue) = Active Position Value (positionValue) + Redemption Receivables (redemptionReceivable)
Active Position Value (positionValue) = Held Shares (shares) × PPS
```

Active position value is derived from the holder proportional share of free funds:

* **Free funds**: `Free Funds = Reported Total Assets - Effective Locked Profit`
* **Underlying token allocation**: `Underlying Amount = floor(Held Shares * Free Funds / Total Supply)`
* **Asset conversion**: For wrapper vaults (e.g. EarnUSDT converting through seCDV to USDT), the underlying amount is converted via the underlying vault exact `convertToAssets` at the same block, retaining integer floors before dividing by asset decimals (10^6).
* **Redemption receivables**: Nominal value of uncollected redemption claims.

**Key points**

* Multiply raw shares by free funds, divide by supply once, then convert the resulting underlying amount. The rounded `pricePerShare` quote is a diagnostic; multiplying a large holding by that quote loses precision.
* EarnUSDT converts through seCDV to USDT at the same block. Each contract conversion retains its integer floor.
* A valid empty vault has zero supply and zero held shares, yielding zero held value. Inconsistent share/supply state is unavailable.
* Free funds exclude effective locked profit; reported assets follow strategy reports. Estimated NAV can include supported strategy estimates before a report. Read the [accrual coverage and adjustment rules](/en/developers/accrual-accounting) before financial-statement use.
* Whole-vault valuation converts total supply once; per-wallet floors can produce a different sum.
* Periods are `[t_0, t_1)`: an event at `t_0` is included; an event at `t_1` enters the next period.
* Adjacent periods share the same boundary snapshot. Hourly collection provides reusable boundaries; custom boundaries use verified archive reads.

**Cautions**

* Unsupported conversion, unfinalized boundaries or missing evidence return an explicit error.
* Aggregate root assets once. Exclude nested claims already represented in the root valuation.
* Cooldown token conversion remains 1:1, and awaiting liquidity leaves unpaid claims at their nominal contract amounts. Strategy debt and shortfall are reconciled separately in the protocol book. [Cooldown principal and settlement](/en/developers/accrual-accounting#cooldown-principal-and-settlement).

## Cost and recognition

At a boundary, active share valuation separates into acquisition cost and unrealized gain/loss:

```text theme={null}
Unrealized PnL = Position Value - Cost Basis
```

* **Position value (`positionValue`)**: Active shares under the selected valuation basis.
* **Cost basis (`costBasis`)**: Verified remaining acquisition cost for active shares under the wallet convention (excludes nominal claims).
* **Unrealized PnL (`unrealizedPnl`)**: Valuation gain or loss relative to cost basis at the boundary.

When shares leave a wallet through a transfer or redemption, cost is allocated proportionally:

```text theme={null}
Allocated Cost = floor(Pre-movement Cost * Disposed Shares / Pre-movement Shares)
Remaining Cost = Pre-movement Cost - Allocated Cost
Realized PnL   = Disposal Consideration - Allocated Cost
```

* For a genuine share transfer, the allocated cost carries over to the receiving wallet.
* For a verified redemption or disposal, the difference between consideration received and allocated cost recognizes as `realizedPnl`.
* **Custody migration (wallet-to-wallet transfer)**: Moving shares from an old custody wallet to a new custody wallet follows the same generic rule (`wallet-transfer-pro-rata-v1`) as any receipt-verified share transfer between any two wallets. SuperEarn keeps no address or entity registry and makes no beneficial-owner assertion. A full-balance transfer moves all remaining cost; a partial transfer moves `floor(cost × shares sent / shares held)` and the remainder stays with the sender. A pure transfer is not a disposal, so realized PnL is 0. See [FAQ Q3](#partner-accounting-faq).

### PnL decomposition and reconciliation

Total PnL decomposes across realized earnings, valuation changes on remaining holdings, and net embedded gains/losses transferred in or out:

```text theme={null}
Total PnL = Realized PnL + Unrealized PnL Change - Net Transferred Unrealized PnL
```

Where:

* **Unrealized PnL Change (`unrealizedPnlChange`)**: `Ending Unrealized PnL - Beginning Unrealized PnL`
* **Net Transferred Unrealized PnL (`netTransferredUnrealizedPnl`)**: Net embedded gain/loss entering the scope via share transfers:
  ```text theme={null}
  Net Transferred Unrealized PnL = Sum of Inbound(Market Value - Carried Cost) - Sum of Outbound(Market Value - Carried Cost)
  ```
* **Reconciliation residual (`residual`)**: Verified books confirm that `Total PnL - (Realized PnL + Unrealized PnL Change - Net Transferred Unrealized PnL) = 0`. Nonzero residuals suppress return calculations.

### Share transfer example

Cost 50 and value 60 move from one wallet to another. Prices stay unchanged and amounts divide exactly. Each row describes that wallet separate period; the receiver redeems in a later period.

| Wallet / event                             | `realizedPnl` | `unrealizedPnlChange` | `netTransferredUnrealizedPnl` | `pnl` |
| ------------------------------------------ | ------------: | --------------------: | ----------------------------: | ----: |
| Sender transfers all shares                |             0 |                   -10 |                           -10 |     0 |
| Receiver receives shares, carrying cost 50 |             0 |                   +10 |                           +10 |     0 |
| Receiver later redeems for 60              |           +10 |                   -10 |                             0 |     0 |

### Example

One wallet, same claim receiver, opening value 110 and cost 100; subsequent prices stay unchanged:

\| Event | Position value | Cost basis | Unrealized PnL | Redemption receivable | Period effect |
\| --- | ---: | ---: | ---: | ---: | ---: | --- |
\| Opening | 110 | 100 | 10 | 0 | Managed balance 110 |
\| Burn -> fixed claim | 0 | 0 | 0 | 110 | Realized +10; unrealized change -10; PnL 0 |
\| Unpaid after cooldown | 0 | 0 | 0 | 110 | Claim retains nominal value |
\| Payment 110 | 0 | 0 | 0 | 0 | Outflow 110; additional PnL 0 |
\| Accepted-loss settlement: payment 109 | 0 | 0 | 0 | 0 | Request closed; outflow 109; payment loss 1 |

## Earnings

Period earnings reconcile opening and closing balances with external cash flows under the standard accounting identity:

```text theme={null}
Ending Balance (closing.totalValue) = Beginning Balance (opening.totalValue) + Inflows - Outflows + PnL
```

Solving for period PnL:

```text theme={null}
PnL = Ending Balance (closing.totalValue) - Beginning Balance (opening.totalValue) - (Inflows - Outflows)
```

| Movement                                    | Wallet scope                    | Whole-vault scope           |
| ------------------------------------------- | ------------------------------- | --------------------------- |
| Deposit from a free wallet                  | Inflow                          | Inflow                      |
| Share transfer between holders              | Sender outflow; receiver inflow | Internal movement           |
| Fixed redemption claim, same owner/receiver | Investment reclassification     | Investment reclassification |
| Claim payment to a free wallet              | Outflow                         | Outflow                     |

## Period return

`return.method=time_weighted` calculates True Time-Weighted Return (TWR) by breaking the reporting period at each external cash flow:

* **Holding sub-periods**: Across intervals without external flows, growth is:
  ```text theme={null}
  Sub-period Growth = Ending Balance / Beginning Balance
  ```
* **Operation boundaries**: At each external flow operation, portfolio values are measured immediately before and after the flow to isolate external capital additions and withdrawals from investment performance.
* **Period TWR**: All sub-period growth factors link geometrically:
  ```text theme={null}
  1 + Period TWR = Product(Sub-period Growth Factors)
  ```

### Annualized rates

Let `Elapsed Seconds` be the actual elapsed seconds in the period and `Year Seconds = 365 * 86,400 = 31,536,000`:

```text theme={null}
Linear APR   = Period TWR * (Year Seconds / Elapsed Seconds)
Compound APY = (1 + Period TWR) ^ (Year Seconds / Elapsed Seconds) - 1
```

* **Linear APR (`return.apr`)**: Standard official annualized rate across all time horizons (1 hour, 1 day, 1 month).
* **Compound APY (`return.apy`)**: Computed for every period with a defined return, including windows shorter than 7 days. It is `null` only when the period return is unavailable or the annualized result cannot be represented. Below 7 days it is a hypothetical annual equivalent that amplifies harvest and lock-release timing, so a non-null `return.apy` is not necessarily display-safe. Prefer `return.apr` and `return.periodRate` for short windows, and apply your own display threshold (e.g. hide `apy` when `end - start < 7 days`) if you need one.

## PPS APY

`/v1/apy` targets a trailing seven-day PPS window. Request `start/end` filter UTC daily observation anchors (`at`) in `[start, end)`; each row `start/end` gives the actual trailing measurement window, which can begin before the request range.

```text theme={null}
PPS APY = (Closing PPS / Opening PPS) ^ (Year Seconds / Elapsed Seconds) - 1
```

* `Opening PPS` and `Closing PPS` are the observed share prices at the start and end of the trailing measurement window (`start/end` in the API response).
* `Elapsed Seconds` is the actual duration between observations, with `Year Seconds = 31,536,000`.

## Contract interest

Institution `/interest` uses checkpointed principal and fixed-rate ACT/365 accrual:

```text theme={null}
Period Interest = Credited Interest + Ending Accrued Interest - Beginning Accrued Interest
```

Where accrued interest at a boundary timestamp `T` is calculated from the last checkpoint before `T`:

```text theme={null}
Accrued Interest = floor((Checkpoint Scaled Interest + Principal * Rate_bps * Active Accrual Seconds) / (10,000 * Year Seconds))
```

* **Active Accrual Seconds**: Elapsed seconds from `max(last checkpoint, start time)` to `min(T, maturity)`. Maturity of 0 means uncapped.
* **Credited Interest**: Change in cumulative interest already credited to the claim ledger (`credited`).
* **Principal & Rate**: Checkpointed principal in raw token atoms and annual rate in basis points (100 bps = 1%).

## Partner accounting FAQ

<AccordionGroup>
  <Accordion title="Q1: Large withdrawal & $27.5M offset mechanism — Why did unrealized PnL drop while net profit stayed positive?">
    **Context**: During a large redemption (e.g. withdrawing 90% of a fund position), the remaining paper gain drops abruptly. In June 2026, a partner noticed that `unrealizedPnlChange` dropped by -\$27.5M, raising concern about an apparent loss.

    **Accounting Reality**:
    When shares are redeemed, accumulated paper gains are converted into cash. Under the pro-rata moving average cost model:

    * The unrealized gain bucket decreases by \*\*-$27.5M** (`unrealizedPnlChange = -$27.5M\`).
    * Simultaneously, the realized gain bucket increases by \*\*+$27.5M** (`realizedPnl = +$27.5M\`).
    * The PL identity confirms:
      ```text theme={null}
      PnL = realizedPnl + unrealizedPnlChange = (+27.5M) + (-27.5M) = 0
      ```

    The net period earnings are completely undisturbed; paper profits simply shifted into realized profits.
  </Accordion>

  <Accordion title="Q2: Redemption receivables — What is their accounting status and why is yield 0% during cooldown?">
    **Context**: When a user submits a redemption request, burned shares become `redemptionReceivable` in the CooldownVault.

    **Accounting Reality**:

    * **100% Principal Protection**: The nominal redemption consideration is locked and guaranteed by the protocol. Cross-chain routing and strategy unravelling are internal protocol operations.
    * **Non-earning Asset**: Because the underlying shares were burned at the confirmed block PPS, this capital no longer participates in vault growth. It earns 0% interest during the cooldown waiting period.
    * **Balance Sheet Classification**: On the partner balance sheet, `redemptionReceivable` is classified as a short-term financial receivable awaiting settlement, distinct from active earning investments (`positionValue`).
  </Accordion>

  <Accordion title="Q3: Custody migration & multi-wallet transfers — How is cost basis preserved?">
    **Context**: When moving shares from an old custody wallet to a new custody wallet, how does the API avoid creating false disposals?

    **Accounting Reality**:

    * **Generic transfer rule**: Every receipt-verified share transfer between any two wallets carries the sender's pro-rata acquisition cost to the receiver (policy `wallet-transfer-pro-rata-v1`). No registration or onboarding step exists: SuperEarn keeps no address or entity registry, and the rule makes no beneficial-owner assertion. A transfer to an unrelated wallet receives the same treatment.
    * **Cost Carryover**: A full-balance transfer moves all remaining cost. A partial transfer moves `floor(cost × shares sent / shares held)`, and the remainder stays with the sender.
    * **Zero Realized PnL**: A pure transfer is not a disposal, so `realizedPnl` is 0 on both sides.
    * **Both sides in `/v1/earnings`**: The sender reports the transfer value in `outflows` and a negative `netTransferredUnrealizedPnl` (value less carried cost). The receiver reports the same value in `inflows`, a `costBasis` increase equal to the carried cost, and a positive `netTransferredUnrealizedPnl` of the same magnitude. Wallet-level `inflows` / `outflows` therefore include migrations and are not deposit or withdrawal volume.
    * **Worked example**: A full-balance migration valued at 21,509,075.692925 carried cost 21,503,019.316660 and embedded gain 6,056.376265. The sender shows `outflows = 21,509,075.692925`, `costBasis` 21,503,019.316660 → 0, `realizedPnl = 0` and `netTransferredUnrealizedPnl = -6,056.376265`; the receiver shows `netTransferredUnrealizedPnl = +6,056.376265`.
    * **Reason codes**: When evidence is missing, the carried cost or the PnL split is `null` and `quality.reasons` lists the cause:
      * `transfer_cost_basis_unverified`: the sender's acquisition cost for the transferred shares is not verified.
      * `transfer_evidence_unavailable`: the transfer receipt could not be verified.
      * `transfer_valuation_unavailable`: the value of the transfer at its operation is unavailable.
      * `receiver_change_unsupported`: a pending redemption's claim receiver changed in the period; see [Claim receivers](#valuation-and-return-availability).
      * `redemption_intermediary_cost_unavailable`: a Router (redemption transit contract) held pre-existing shares, so transit cost cannot be isolated.
    * **Before migrating**: Claim or settle pending redemptions first. Reassigning a pending redemption's receiver during a migration returns `receiver_change_unsupported` for the affected wallet periods.
    * **Activity feed**: `GET /v1/accounts/{account}/activity` shows a migration only as a `SEND` or `RECEIVE` position row with its share amount; `principal`, `value`, `earnings` and `realizedGain` are `null`, so read the monetary effect from `/v1/earnings`.
  </Accordion>

  <Accordion title="Q4: Vault lockedProfit buffer & legacy harvestReport — Why is locked profit excluded from official balance/PnL, and how can it be queried?">
    **Context**: Morpho, Pendle PT, and RWA strategies generate interest continuously, but the vault PPS unlocks that yield linearly over 7 days. In legacy prototypes, an experimental `accountedBy=harvestReport` mode existed that included unreleased locked profit in earnings. Why is this excluded from v1 canonical earnings, and how do we query it?

    **Accounting Reality**:

    * In the SuperVault architecture, when a strategy reports earnings via a `harvest` transaction, the profit is placed into a `lockedProfit` buffer that unlocks linearly over 7 days to protect against sandwich attacks and flash loans.
    * **Why it is excluded from official balance and PnL**:
      1. *No legal entitlement at report time (IFRS asset recognition)*: If a holder redeems shares immediately after harvest, the smart contract settles strictly at PPS (`freeFunds`), paying zero locked profit. Recognizing an unredeemable amount as balance/income violates IFRS control and realizability standards.
      2. *Share dilution*: New deposits over the 7 days acquire shares at current PPS and participate in the remaining unlock, diluting the original holders.
      3. *Ledger integrity*: Treating locked profit as balance creates an artificial disposal loss when an investor exits at true contract PPS.
    * **How to query this information in v1**:
      1. *Audit reconciliation*: Add `include=reconciliation` to `/v1/earnings` to receive `reportedAssets`, `lockedProfit`, and `rounding` adjustments alongside canonical PPS numbers.
      2. *Strategy harvest events*: Query `GET /v1/harvests` to see verified keeper reports, net gain, assessed fees, and gross report-block wallet allocations.
      3. *Real-time venue accruals*: Set `valuation=estimated_nav` on `/v1/earnings` to inspect live economic yield directly from underlying protocol adapters before root harvest.
  </Accordion>

  <Accordion title="Q5: Linear APR vs compound APY — Why is linear APR the standard for short observation windows?">
    **Context**: Why should partners prefer `return.apr` over `return.apy` on periods under 7 days?

    **Accounting Reality**:

    * Compounding a 1-day or 1-hour return over 365 days involves raising `(1 + R)` to the power of 365 or 8,760. Even minor block-timing jitter or discrete harvest events can cause APY to wildly explode (e.g. spike to 300% or drop negative).
    * Therefore, **linear APR (`return.apr`)** is the official, distortion-free standard across all intervals. The API still computes `return.apy` for every period with a defined return and does not set it to `null` below 7 days, so treat a short-window `apy` as a hypothetical extrapolation: present `return.periodRate` and `return.apr`, and show `apy` only as a supplementary figure.
  </Accordion>

  <Accordion title="Q6: Audit Check Matrix — How can external auditors verify reports in Excel?">
    External auditors can directly verify the integrity of SuperEarn statements by exporting CSV/JSON rows and verifying the following column formulas in Excel:

    | Verification Step                                                         | Excel Formula                                                                      | Expected Residual |
    | :------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- | :---------------- |
    | **1. BS Balance**                                                         | `=ROUND(positionValue + redemptionReceivable - totalValue, 6)`                     | `0.000000`        |
    | **2. BS Cost & Gain**                                                     | `=ROUND(costBasis + unrealizedPnl - positionValue, 6)`                             | `0.000000`        |
    | **3. Period PnL**                                                         | `=ROUND(closing_totalValue - opening_totalValue - inflows + outflows - pnl, 6)`    | `0.000000`        |
    | **4. PnL Decomposition**                                                  | `=ROUND(realizedPnl + unrealizedPnlChange - netTransferredUnrealizedPnl - pnl, 6)` | `0.000000`        |
    | **5. Lifetime Ledger** (`interval=all` row with `opening_totalValue = 0`) | `=ROUND(closing_totalValue + outflows - inflows - pnl, 6)`                         | `0.000000`        |
  </Accordion>
</AccordionGroup>

## Report evidence

| Step               | Reporting action                                                          |
| ------------------ | ------------------------------------------------------------------------- |
| Preserve precision | Keep integer/decimal calculations and the floors shown in each equation   |
| Review coverage    | Inspect missing values, quality reasons and reconciliation before posting |
| Freeze             | Save the query, response, policy, asset membership and source evidence    |
| Correct            | Link a new result/version and reason while preserving the issued original |

* Scalar defines [balance fields](https://api.superearn.io/v1/docs#tag/balances/GET/balances), [earnings fields and precision](https://api.superearn.io/v1/docs#tag/earnings/GET/earnings) and [APY fields](https://api.superearn.io/v1/docs#tag/apy/GET/apy).
* Apply separately supported impairment and reporting adjustments; see [valuation and harvest reporting](/en/developers/accrual-accounting).
* Existing QA/legacy exports retain route-specific formulas and verified coverage; see [legacy comparison](/en/private/data-api-migration-guide).
