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

# rwa_multichain.nav_intervals

> Forward-filled NAV validity windows derived from NAV events, for point-in-time USD pricing of any RWA transfer, balance, or trade.

export const PremiumDatasetAccessCard = ({href = "https://dune.com/enterprise#contact-form"}) => <Card title="Premium dataset access" icon="info" href={href}>
    This dataset is part of a premium offering and requires additional access. Contact the Dune enterprise team to request access.
  </Card>;

`rwa_multichain.nav_intervals` turns the discrete NAV events in [`nav`](/data-catalog/curated/rwa/valuation/nav) into validity windows. Grain: one row per NAV value per asset with a `valid_from` / `valid_to` range, keyed on `unique_key`. This is the table you want whenever you need "what was this worth at that moment".

<PremiumDatasetAccessCard />

## Why it exists

NAV is published irregularly — daily for some issuers, weekly or on demand for others. Valuing a transfer that happened between two publications means finding the most recent NAV at or before that timestamp. Doing that inline is a correlated subquery or a window function over the full NAV history, repeated for every join.

This table forward-fills instead: each NAV value carries the window over which it was the prevailing value, so a point-in-time join becomes a plain range predicate. The most recent value per asset has `valid_to IS NULL`, meaning it is still in force.

## Table schema

| Column           | Type            | Description                                                                              |
| ---------------- | --------------- | ---------------------------------------------------------------------------------------- |
| `blockchain`     | `VARCHAR`       | Chain where the NAV was published                                                        |
| `chain_id`       | `BIGINT`        | Numeric chain identifier                                                                 |
| `asset_address`  | `VARBINARY`     | Token the NAV applies to. **`VARBINARY`, unlike `token_address` on the activity tables** |
| `oracle_address` | `VARBINARY`     | Contract that published the update                                                       |
| `usd_nav_price`  | `DOUBLE`        | NAV in USD per token, prevailing over this window                                        |
| `nav_raw`        | `UINT256`       | Raw NAV value as emitted onchain                                                         |
| `nav_decimals`   | `INTEGER`       | Decimal precision of `nav_raw`                                                           |
| `quote_currency` | `VARCHAR`       | Currency the source published in                                                         |
| `issuer`         | `VARCHAR`       | Issuer of the asset                                                                      |
| `symbol`         | `VARCHAR`       | Asset ticker                                                                             |
| `valid_from`     | `TIMESTAMP`     | Start of the window, inclusive                                                           |
| `valid_to`       | `TIMESTAMP`     | End of the window, exclusive. `NULL` for the currently prevailing value                  |
| `block_time`     | `TIMESTAMP`     | When the underlying update was published onchain                                         |
| `block_number`   | `BIGINT`        | Block height of the underlying update                                                    |
| `tx_hash`        | `VARBINARY`     | Transaction that published the update                                                    |
| `evt_index`      | `BIGINT`        | Event position within the transaction                                                    |
| `trace_address`  | `ARRAY(BIGINT)` | Trace position, where NAV was read from a call                                           |
| `unique_key`     | `VARCHAR`       | Row identifier                                                                           |
| `_updated_at`    | `TIMESTAMP`     | When this row was last written by the pipeline                                           |

## The point-in-time join pattern

Two things to get right: the half-open range predicate, and the `VARBINARY`-to-`VARCHAR` address cast.

```sql theme={null}
-- Value each transfer at the NAV in force when it happened
SELECT
  t.block_time,
  t.token_symbol,
  n.issuer,
  t.amount,
  n.usd_nav_price,
  t.amount * n.usd_nav_price AS amount_usd_at_nav
FROM rwa_multichain.transfers t
JOIN rwa_multichain.nav_intervals n
  ON n.blockchain = t.blockchain
  AND '0x' || lower(to_hex(n.asset_address)) = t.token_address
  AND t.block_time >= n.valid_from
  AND (n.valid_to IS NULL OR t.block_time < n.valid_to)
WHERE t.block_date >= current_date - INTERVAL '7' day
ORDER BY t.block_time DESC
LIMIT 100
```

`valid_to IS NULL` must be handled explicitly. Without it, every row priced by the currently prevailing NAV drops out of the result, which silently biases any total toward historical activity.

For daily data such as [`balances`](/data-catalog/curated/rwa/holders-supply/balances), compare on dates rather than timestamps:

```sql theme={null}
  AND b.day >= date(n.valid_from)
  AND (n.valid_to IS NULL OR b.day < date(n.valid_to))
```

<Note>
  `balances.balance_usd` is already priced from NAV, so join this table only when you need a different NAV source, a different valuation timestamp, or want to inspect which rows lack coverage.
</Note>

## Coverage

NAV covers 366 assets across 18 chains from 48 issuers, which matches roughly 14% of RWA balance rows. An asset with no NAV feed produces no interval rows at all, so an inner join silently drops it. Use a `LEFT JOIN` when you need to distinguish "worth zero" from "not priced".

```sql theme={null}
-- Which assets lack NAV coverage
SELECT
  b.blockchain,
  b.token_symbol,
  SUM(b.balance) AS balance,
  COUNT(n.unique_key) AS nav_rows_matched
FROM rwa_multichain.balances b
LEFT JOIN rwa_multichain.nav_intervals n
  ON n.blockchain = b.blockchain
  AND '0x' || lower(to_hex(n.asset_address)) = b.token_address
  AND b.day >= date(n.valid_from)
  AND (n.valid_to IS NULL OR b.day < date(n.valid_to))
WHERE b.day = current_date - INTERVAL '1' day
  AND b.balance > 0
GROUP BY 1, 2
HAVING COUNT(n.unique_key) = 0
ORDER BY 3 DESC
```
