Skip to main content
rwa_multichain.nav_intervals turns the discrete NAV events in 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”.

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

The point-in-time join pattern

Two things to get right: the half-open range predicate, and the VARBINARY-to-VARCHAR address cast.
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, compare on dates rather than timestamps:
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.

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”.