Skip to content

feat: add SUI USDC stablecoin transfer model#9521

Closed
Evan-Kim2028 wants to merge 3 commits intoduneanalytics:mainfrom
Evan-Kim2028:feat/sui-stablecoin-transfers
Closed

feat: add SUI USDC stablecoin transfer model#9521
Evan-Kim2028 wants to merge 3 commits intoduneanalytics:mainfrom
Evan-Kim2028:feat/sui-stablecoin-transfers

Conversation

@Evan-Kim2028
Copy link
Copy Markdown
Contributor

@Evan-Kim2028 Evan-Kim2028 commented Apr 2, 2026

Summary

Enhancement to #9308 that fixes Circle CCTP burn tracking and improves mint completeness using event-based amounts from sui.events.

Keeps #9308's object pipeline for direct sends and ownership transfers. Replaces object-based mint/burn detection with treasury::Mint and treasury::Burn event JSON payloads.

Circle CCTP Event Details

Contract and event types

Event Package ID Module Event Type
Mint 0xecf47609d7da919ea98e7fd04f6e0648a0a79b337aaad373fa37aac8febf19c8 treasury treasury::Mint<0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC>
Burn 0xecf47609d7da919ea98e7fd04f6e0648a0a79b337aaad373fa37aac8febf19c8 treasury treasury::Burn<0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC>

USDC coin type: 0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC

Event JSON payloads

Mint — contains amount and recipient:

{"amount": "826829", "mint_cap": "0xee9b9de94793bab42232dbdb82a8e090bb2e1eb192ef498e421b7e9390555918", "recipient": "0x39bb1dfbe50fbafa713369a6203ab56705fcbfc98cc6473f28ac57503479844b"}

Burn — contains amount (coins are destroyed, no recipient):

{"amount": "13846570", "mint_cap": "0xee9b9de94793bab42232dbdb82a8e090bb2e1eb192ef498e421b7e9390555918"}

How to query these events on Dune

-- All Circle USDC mints
SELECT
    transaction_digest,
    date,
    CAST(JSON_EXTRACT_SCALAR(event_json, '$.amount') AS BIGINT) / 1e6 AS usdc_amount,
    JSON_EXTRACT_SCALAR(event_json, '$.recipient') AS recipient
FROM sui.events
WHERE event_type LIKE '%treasury::Mint<0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC>%'
  AND date >= DATE '2024-09-18'

-- All Circle USDC burns
SELECT
    transaction_digest,
    date,
    CAST(JSON_EXTRACT_SCALAR(event_json, '$.amount') AS BIGINT) / 1e6 AS usdc_amount,
    TO_HEX(sender) AS burner
FROM sui.events
WHERE event_type LIKE '%treasury::Burn<0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC>%'
  AND date >= DATE '2024-09-18'

Two fixes

1. Burns: $5.1M/day recovered (was $0)

Deleted objects on Sui lose their coin_type field. #9308 filters sui.objects WHERE coin_type = USDC AND object_status = 'Deleted' — this returns zero rows. Burn amounts only exist in the treasury::Burn event JSON.

2. Mints: 38 additional events/$4.89M per day

The merged #9496 model's supply_signals only flags mints where tx_net_delta > 0, missing mint transactions that also have other balance changes. Event-based approach captures all treasury::Mint events.

Supply reconciliation (full history verification)

Cumulative mints minus burns from events should equal current USDC circulating supply. Tested across the full history from USDC launch (2024-09-18) through Apr 2, 2026:

Metric Value
Total treasury::Mint events 313,685
Total minted $8,624,079,621.96
Total treasury::Burn events 365,932
Total burned $8,244,739,349.24
Net supply (mints - burns) $379,340,272.72
Allium reported supply (Apr 2) $376,192,416
Allium reported supply (Apr 1) $380,601,984
Discrepancy ~$3.1M (0.8%)

The event-based net supply ($379.3M) lands squarely between Allium's Apr 1 and Apr 2 daily snapshots. The small discrepancy is consistent with intraday supply changes — Dune events include full-day activity while Allium snapshots at a fixed time.

Every USDC on Sui was minted via treasury::Mint and burned via treasury::Burn. The cumulative event sum reconciles to the actual circulating supply.

Dune query ID: 6942011 (supply reconciliation)

Transfer parity verification (Apr 1, 2026)

Transfer Type This PR Merged #9496 Match?
direct_send 6,472 / $36,373,219.88 6,472 / $36,373,219.88 (as object_created) Exact
transfer_with_balance_change 18 / $1,456,755.93 18 / $1,456,755.93 Exact
mint 188 / $9,583,732.72 150 / $4,694,457.97 (38 missed) More complete
burn 293 / $5,105,917.64 0 / $0 Fix

Direct sends and ownership transfers use the same anchor pipeline as #9308 — exact parity. Mint event amounts verified 188:188 exact match against Created object coin_balance (zero discrepancy).

Dune query ID: 6942000 (transfer parity)

Architecture

Object pipeline from #9308 for transfer detection:

day_rows → anchors → unioned → calc (LAG windows) → tx_senders → enriched → filtered

Then 4 output categories (credit-side, 1 row per transfer):

  • direct_sends — Created objects where tx_sender != receiver
  • ownership_transfers — Mutated objects where prev_owner != receiver and balance_delta > 0
  • mintstreasury::Mint event JSON amount + recipient
  • burnstreasury::Burn event JSON amount

Scope

Test plan

  • direct_send parity with merged model (6,472 rows, exact match)
  • transfer_with_balance_change parity (18 rows, exact match)
  • Burn events capture $5.1M/day that objects miss ($0)
  • Mint event amounts = object amounts (188:188, zero discrepancy)
  • Full-history supply reconciliation: mints - burns = $379.3M ≈ Allium $376-380M
  • dbt compile passes
  • unique_combination_of_columns test on (block_date, unique_key)

Redesign of duneanalytics#9308 with three clean sources:
- Direct sends from sui.objects Created objects
- Mints from Circle treasury::Mint events
- Burns from Circle treasury::Burn events

Key fix: burns must use events because Deleted objects lose their
coin_type on Sui. The duneanalytics#9308 approach silently produces $0 burn volume.

Verified against duneanalytics#9308 for Apr 1, 2026:
- direct_send: 6,472 rows / $36.4M (exact match)
- mint: 188 rows / $9.6M (exact match)
- burn: 293 rows / $5.1M (duneanalytics#9308 produces 0 rows)
@github-actions github-actions Bot marked this pull request as draft April 2, 2026 19:03
@github-actions github-actions Bot added WIP work in progress dbt: daily covers the Daily dbt subproject labels Apr 2, 2026
…9308

Drop the ownership_transfers CTE — matching duneanalytics#9496's reconciliation
logic requires their full model chain. Keep the focused contribution:
1. Event-based burns (the only working approach)
2. Event-based mints (verified exact match)
3. Credit-side direct sends (same as duneanalytics#9308)
…t mints/burns

- Restores day_rows/anchors/calc/enriched/filtered from duneanalytics#9308
  for full direct_send + transfer_with_balance_change coverage
- Event-based mints: captures all 188 treasury::Mint events
  (merged model misses 38 mints/$4.89M due to tx_net_delta filter)
- Event-based burns: captures 293 treasury::Burn events/$5.1M
  (merged model produces $0 — Deleted objects lose coin_type)
- Verified exact parity: 6,472 direct_sends + 18 ownership
  transfers match merged model to the cent
@tomfutago
Copy link
Copy Markdown
Contributor

@Evan-Kim2028 thanks for the feedback here, much appreciated! I incorporated it into PR #9517, so I’m closing this one in favor of that updated version.

@tomfutago tomfutago closed this Apr 17, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

dbt: daily covers the Daily dbt subproject WIP work in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants