Back to blog
sui onchain datasui dune analyticssui defi datablockchain data quality

Sui Onchain Data on Dune: A Practitioner's Guide

Vincent Charles

Vincent Charles

August 6, 2026 · 15 min read

Sui Onchain Data on Dune: A Practitioner's Guide

TL;DR:

  • Sui has very few decoded DeFi tables, so a dashboard's title is a claim, not a guarantee.
  • Verify the package bytes, decide where state lives, price in a deliberate order, and let the protocol's own invariants grade your work.
  • The traps are encodable. Catching the error that makes a plausible dashboard a wrong one still is not.

On Ethereum, building a lending dashboard is close to a solved problem. The events are parsed for you, whether you use a protocol's decoded tables or Dune's curated lending tables. You query and move on.

Sui hands you almost nothing for DeFi. As of mid-2026 there are five curated tables covering swaps, BTC on Sui, chain activity, Walrus storage, and exchange addresses. None of them cover lending, perps, or protocol state. Every figure gets rebuilt from raw events and objects.

That gap has a consequence most people never think about. When nothing is decoded, a dashboard's title and the contract it actually queries are only as aligned as its author made them. The chain will quite happily let a dashboard say "Navi" while it reads someone else's package.

I have now rebuilt three Sui protocols from primitives: Navi's lending markets, Suilend's full liquidation history, and Bluefin Pro's perps settlement layer. This is the method that came out of it, and the three findings it produced that nobody had assembled before.

Rule 1: Verify the package before you trust the label

This is the single most important skill on Sui, and it is the one nobody does.

I found it by accident. I was rebuilding Navi's markets from raw on-chain state over a weekend, and my totals kept missing the dashboard everyone cites for Navi's TVL. I assumed my reconstruction was wrong. It took decoding the actual package each query reads to see what was happening. Mine was reading Navi's package. The most-cited one, 19 charts under the Navi name, was filtering on a ReserveAssetDataEvent from Suilend's package.

I cross-checked three ways before saying anything: Suilend's SDK, their open-source Move code, and DefiLlama.

The numbers on that dashboard are real. They are a different protocol's. Suilend emits a clean, well-structured event, so nothing about it looks broken. The label points at the wrong protocol, and on a chain with few decoded tables that mislabel sat unchallenged because almost nobody re-derives package bytes.

Bluefin produced a second version of the same failure, in a different disguise. Every monetary field in the package is nine-decimal fixed point, so you divide by 1e9 uniformly. But the market metadata carries a field called base_asset_decimals, which looks exactly like the thing you should be scaling by. It is not. The most visible public query for that package keys off it, then hand-patches BTC, ETH, and SOL with an adjustment, which silently mis-scales the four markets nobody patched.

I verified the uniform 1e9 three independent ways: on-chain step sizes matched the documented contract specs, oracle prices matched real spot on every market and date, and the open interest parity check only holds under a single uniform scale.

The practical version of this rule: decode the package and event_type a query filters on, then check that hex against the protocol's own docs, SDK, or GitHub. It sounds paranoid until you find a 19-chart dashboard pointing at the wrong protocol.

Rule 2: Decide where the state actually lives

Sui is object-centric. Protocol state sits inside typed objects rather than account mappings, and that one design choice changes how every analytics question gets answered.

Three sources, three different jobs:

  • Flows (deposits, borrows, swaps, fills, liquidations) come from sui.events.
  • Historical state at a past date comes from sui.objects, taking the latest version per object.
  • Current state, when the events carry no USD value, comes from reading the RPC live.

Navi and Suilend are the clearest illustration that this is a per-protocol decision, not a chain-wide one. Two lending protocols on the same chain, and the extraction paths have almost nothing in common. The split comes down to one question: does the protocol write USD values into its events?

Suilend does. Its ReserveAssetDataEvent carries supplied and borrowed amounts already in USD, scaled 1e18 in fixed-point. You read the event, divide, and you have TVL. State lives in the event stream, which is exactly why an events-only dashboard works there.

Navi does not. Its events record actions, not dollar-denominated state. To know what Navi holds right now you read the reserve objects directly and price them yourself. The reconstruction runs inside Dune using http_post to call Sui's RPC mid-query, discovering markets from MarketCreated events, pulling every reserve object across all four markets, normalizing raw balances with each reserve's interest index, and pricing the result. Forty-eight reserves, no separate indexer, refreshed on every run.

Miss the interest index and TVL under-reports by 5 to 11% while looking entirely correct.

Perps add a third variation. Bluefin has no open interest field anywhere on-chain. But FundingRateApplied stamps every open position every hour with account, market, side, and size, 8.7 million stamps and counting. So open interest becomes a census: take the latest hourly snapshot per market, sum size by side, value at the oracle mark. The number you want does not exist, and the chain still contains enough to reconstruct it.

Rule 3: Price in a deliberate order

Dune's standard price tables do not cover Sui reliably, so the usual shortcut of joining to a price feed is not available. The order I use:

  1. The protocol's own on-chain oracle. For Navi I price from its PriceOracle, the exact oracle it uses to decide liquidations. That is not an arbitrary preference. A dashboard built on it agrees with the protocol by construction. It is also the only source that prices Navi's gold and silver tokens and its private-credit token, where Pyth's historical endpoint returns null.
  2. Let the protocol price itself. Suilend continuously emits both its supply and the USD estimate of that supply per reserve. Divide one by the other and you have a protocol-native exchange rate in the protocol's own marks, with the 1e18 scaling cancelling cleanly on both sides.
  3. prices.hour as a fallback for major tokens. One trap: it double-encodes addresses, so a natural-looking join silently returns zero matches until you encode the address the same way.
  4. DEX trades for thin tokens with no clean oracle history.

Suilend also carries a trap worth stating on its own, because it is where I have seen other public dashboards slip. When Suilend liquidates a position, the seized collateral, the protocol fee, and the liquidator bonus are emitted in cTokens, the protocol's internal share unit, while the repaid debt is emitted in the underlying. Treat them as the same unit and the seized-collateral figure is simply wrong, off by the exchange rate between a cToken and its underlying. Price each side in its own unit, pulling both prices from the reserve's own state so no token decimal is ever hardcoded.

One more, from Bluefin: Move serializes signed numbers as a struct, a magnitude plus a boolean, and nothing tells you which boolean value means positive. I pinned funding three ways before trusting it, including checking that the long side visibly receives the credit on negative epochs.

Rule 4: Let the protocol's own invariants grade you

This is what separates a dashboard you can stake a decision on from one that merely looks finished. Find a rule the protocol documents or a constraint its design forces, then check whether your pipeline reproduces it.

Three that did real work:

A documented constant. Bluefin's docs state that when a liquidation closes at a premium, 30% flows to the market's insurance fund and 70% to the liquidator. Across all 7,899 liquidations in the venue's history, the events record $80,079 of insurance inflow and $186,850 of liquidator premium. Divide 80,079 by 266,929 and you get 30.000%. The protocol's own economic rule falling out of the raw bytes to the third decimal, which it would not if the scaling, the signs, or the field semantics were wrong anywhere in the chain.

A structural constraint. A perpetual book must balance, so long size has to equal short size. The open interest census balances to 0.004%. Since that figure is the one number resting on a snapshot rather than a settlement fact, the parity check is what keeps it honest.

An unambiguous subset. With no Sui price table to cross-check against, I leaned on stablecoins. About four fifths of all Suilend debt repaid is stablecoin-denominated, where a dollar of debt is a dollar, and there the protocol-native USD matches the raw token amount to within rounding error. That substitutes for the price-table check the chain cannot give you.

Alongside this: run an independent recount straight from raw events and require it to match the priced pipeline exactly. Same liquidation count, same distinct obligations, same set of liquidators, zero difference.

Rule 5: Fail loud, never hardcode

A missing price should break the row, not get filled with a stale constant. Where a price is missing I leave it null and flag it, never zero-filled.

The same discipline applies to fields you cannot defend. On Suilend, the raw sum of one deposit-value field carries obvious garbage outliers, so it stays out of the dashboard entirely while the sane weighted figure stays in. And where a metric has a known seam, say so on the dashboard rather than papering over it: Suilend's seized collateral is valued at daily oracle marks that run high during violent intraday cascades, so the realized liquidation penalty is better read from the price-independent share-token proportions, which put it around 6%.

Hardcoded balances and prices are the fastest route to a dashboard that looks fine today and is quietly wrong next week.

What the method surfaced

Three findings that existed on-chain the whole time and that nobody had assembled.

Suilend's one bad debt. The protocol emits a specific event when it forgives debt it cannot recover, and it has fired in exactly one episode: September 2025, roughly $395,000 of IKA across 53 accounts. Current bad debt is zero. The cause is reconstructable. IKA is thin, and on 8 September 2025 it roughly doubled in a day on a tenfold spike in DEX volume. Borrowers were squeezed as their debt ballooned and the engine cleared close to $794,000 of IKA debt across 84 accounts in one day. What it could not cover became the write-off.

Bluefin's one violent hour. The liquidation engine has come up short 200 times, $76,667 total, against $80,079 of insurance inflow. Pooled, it looks self-funding. Pooled is the wrong lens, because Bluefin runs a separate insurance fund per market by design. Seven of eight markets are comfortably self-funding. The eighth is WAL: $57,376 of bad debt, three quarters of everything the venue has ever written, against $6,888 of WAL insurance inflow ever collected. Almost all of it landed inside about ninety minutes on 10 October 2025, WAL longs entered around 30 to 36 cents gapped through their bankruptcy prices to marks as low as 16 cents, every one of the largest shortfalls in that window. The chain records the aftermath too: WAL funding has printed negative in 84% of hours since, shorts paying longs almost continuously nine months later.

The mis-scaled markets. Covered above, and worth restating as a finding rather than a methodology note. Two of the most-referenced Sui dashboards in their categories were reporting numbers that were either the wrong protocol's or wrongly scaled, and both had been sitting there unchallenged.

The rhyme between the first two is exact. A thin token, one violent day, and the loss landing precisely where the mechanism design said it would. In both cases the protocol's own events kept a complete record, and in both cases nobody had assembled it.

What cannot be automated

The traps above are encodable, and I have encoded them. The query patterns, verified package IDs, pricing order, and known failure modes live in an open-source toolkit I maintain for agent-assisted Sui analytics. Paired with a Dune MCP, an agent will build a dashboard like these on request, and it will avoid every mistake I already made.

I am not going to pretend that is hard to reach.

What the toolkit cannot carry is the thing the Bluefin build turned on. An automated version would have run clean and shipped a false claim: that the insurance fund covered the bad debt. It does, pooled. It does not for WAL, the one market where it mattered. The only reason the published version is right is that I audited it against the docs and asked the per-market question the automated build had no reason to ask.

The toolkit encodes the mistakes I already know about. Mapping a protocol nobody has mapped, and catching the error that turns a plausible dashboard into a wrong one, is still the work.

Common questions about Sui onchain data

Does Dune have decoded tables for Sui lending?

Almost none. As of mid-2026 Sui has five curated tables on Dune: dex_sui.trades for swaps across nine DEXs, sui_tvl.btc_ecosystem, sui_daily.stats for chain activity, sui_walrus.base_table, and cex.addresses. None cover lending, perps, or protocol state. For Navi, Suilend, Scallop, Bluefin, and most protocol internals you drop to sui.events and sui.objects and filter on the raw event_type string, computing every figure yourself.

Why does the most-cited Navi TVL dashboard on Dune show different numbers?

Because it reads a different protocol. The most-referenced Navi dashboard runs 19 charts under the Navi name while filtering on a ReserveAssetDataEvent from Suilend's package, not Navi's. The numbers are real Suilend numbers. I verified this three ways against Suilend's SDK, their open-source Move code, and DefiLlama. On a chain with very few decoded tables, a dashboard's title is a claim rather than a guarantee.

Has Suilend ever had bad debt?

Once. Suilend emits a specific event when it forgives debt it cannot recover, and it has fired in exactly one episode: September 2025, roughly $395,000 of IKA across 53 accounts. Current bad debt is zero. The cause is visible on-chain, since IKA roughly doubled in a day on 8 September 2025 on a tenfold spike in DEX volume, and the engine cleared close to $794,000 of IKA debt across 84 accounts in that single day.

How do you calculate open interest for Bluefin perps?

There is no open interest field anywhere on-chain, so you reconstruct it as a census. Bluefin's FundingRateApplied event stamps every open position every hour with account, market, side, and size. Take the latest hourly snapshot per market, sum size by side, and value it at the oracle mark. Because a perpetual book must balance, long size should equal short size, which is the check that keeps the figure honest.

How do you price Sui tokens on Dune when there is no reliable price table?

In a deliberate order. Reach first for the protocol's own on-chain oracle, since a dashboard built on the oracle a protocol liquidates against agrees with it by construction. Second, let the protocol price itself where it emits both a supply and the USD estimate of that supply. Third, prices.hour as a fallback for majors, noting that it double-encodes addresses so a natural-looking join silently returns zero matches. Fourth, Sui DEX trades for thin tokens with no clean oracle history.

Where this leaves you

Sui's data is uneven. Solid curated coverage for swaps and chain stats, raw archaeology for everything else. That unevenness is exactly why labels and bytes drift apart, and why checking them is worth doing in public.

If you are building on Sui data and the numbers are not lining up, the gap between the label and the bytes is where I would start looking.

The full technical write-ups are on my newsletter: Navi and the object model, Suilend's liquidations and its one bad debt, and Bluefin's perps. All three dashboards are public and forkable: Navi, Suilend, Bluefin.

If your protocol needs its own on-chain record, that is what we build: Sui Dune dashboards, scoped to delivery in a week, every number traceable to a contract.

Key Takeaways

  • Sui has five curated tables on Dune and none cover lending, perps, or protocol state. Everything else is raw event and object archaeology.
  • Verify the package bytes before trusting any dashboard's label. The most-cited Navi dashboard, 19 charts, reads Suilend's contract.
  • Flows come from events, historical state from objects, current state from live RPC when events carry no USD. The right source is a per-protocol decision.
  • Price from the protocol's own oracle first, then let the protocol price itself, then fall back. Never hardcode.
  • Test scale against an independent anchor rather than believing a decimals field. Bluefin's base_asset_decimals is a decoy that mis-scales four markets.
  • Let documented constants and structural invariants grade your pipeline. Bluefin's 30/70 insurance split reproduces to 30.000% from raw events.
  • Fail loud. A missing price should break the row, not become a stale constant.
  • Pooled numbers hide per-market risk. Bluefin's insurance funds look self-funding in aggregate and do not for the one market where it mattered.
Vincent Charles

Vincent Charles

Fractional head of data and founder of Unchain Data. Former data lead at Binance and Morpho.