Flipside Docs
  • Welcome to Flipside!
    • Welcome to Flipside
    • Growth Services
    • Data
      • Choose your Flipside plan
        • Free
        • Builder
        • Pro
          • Get Started in Snowflake
          • Incremental Table Pattern
          • Copy Data from Snowflake to AWS
          • Copy Data from Snowflake to GCP
          • Copy Data from Snowflake to Azure
        • Snowflake Data Shares
          • Mounting a Snowflake Data Share
    • Earn
    • Community
  • Data
    • Flipside Data
      • Table Docs by Chain
      • Data Modeling Approach
      • Labels
        • Centralized Exchange Label Type
        • Decentralized Exchange Label Type
        • Operator Label Type
        • Chain Admin Label Type
        • Decentralized Finance Label Type
        • NonFungible Tokens Label Type
        • Games Label Type
        • Bridge Label Type
        • Decentralized Applications Label Type
        • Token Label Type
        • Flotsam Label Type
      • Tags
      • Table Freshness Targets
      • Contribute to Our Data
        • Contract Decoding & ABIs
        • How to Add Your Own Tags
        • Community Curation
          • Getting Started
            • Contribution Workflow
          • Model Standards
            • dbt Tips
          • PR Checklist
    • Data Products
      • Data Studio (SQL Analysts)
        • Get Started
          • Write/fork your first query
        • Flipside AI
        • Studio in Depth
          • Query Editor
            • Query Referencing
            • Pro Tips for Querying
            • Keyboard Shortcuts
            • Hex-to-Integer Function
          • Create a Chart
            • Advanced Visualization
          • Build a Dashboard
            • Markdown Reference
          • Team Accounts
        • Tutorials
          • How to Analyze Web3 Data
          • Video Tutorials
            • Overview of Schemas & Tables
            • Ethereum Tutorials
              • Getting Started with Decoded Ethereum Events
              • Getting Started with Ethereum Balances
              • Block Level and Daily Balances
              • Finding Centralized Exchange Flows
            • Solana Tutorials
              • Solana Schema & Tables: Video Walkthrough
              • Solana Specialty Tables: Video Walkthrough
              • Exploring Transactions in solana.events
            • THORChain Tutorials
              • THORChain Schema & Tables
              • Calculating IL for THORChain
          • More Tools & Resources
        • Get Inspired
      • LiveQuery
        • Get Started
        • LiveQuery in Depth
          • Functions
            • 🤝Partner Functions
            • 🧙‍♂️EVM Functions
              • 💡Seaport: Real-time Orders
              • 💡WETH Pool Balances
              • 💡General EVM Node Queries
            • 🤖API Functions
              • 💡Query TheGraph
              • 💡Query Defi Llama
            • ⚙️Utility Functions
              • 💡Hex Converters
              • 💡JSON RPC Request Builder
              • 💡EVM Logs Decoder
              • 💡Keccak256 Encoder
          • QuickNode Setup Guide
        • Secrets Manager
        • Get Inspired
      • Snowflake
      • API/SDK (Developers)
        • Get Started - Your first API call in < 2 min
        • SDK in Depth
          • JSON RPC methods
          • Run A Query
          • Query Results
          • Pagination
          • Sorting
          • Filtering
          • Query Seconds
          • Caching (maxAgeMinutes)
          • Rate Limits
          • Errors
          • More Examples
          • Archive
            • [ARCHIVED] JS/TS SDK
            • ShroomDK Migration Guide
            • [LEGACY] R
        • Tutorials
          • Have Questions?
        • Get Inspired
    • Insights and Tools
  • Earn
    • Flipside Earn
    • Onchain Rewards
      • Quests
    • Analyst Rewards
      • Top Dashboards
        • Top Dashboard Guidelines
        • Skill Tree
      • Ambassador Program
      • Direct to Analyst Commissions
    • Wallet Management
    • Tax Center
  • Support
    • General Support
    • Open a Ticket
      • That email doesn't look quite right
    • 🌟Product Special Releases
      • 2025
        • 2025-02-06 | EVM Blockchain Standardization
          • Table Change Overview
      • 2024
        • 2024-06-13 | Solana native and wrapped addresses
        • 2024-05-01 | Improvements to Pricing Data
          • Actions for Data Studio Users
          • Actions for API Users
          • Action for Data Share Users
    • 🗒️Release Notes
      • 2025
        • 2025-05-15 | Release Notes
        • 2025-05-01 | Release Notes
        • 2025-04-17 | Release Notes
        • 2025-04-03 | Release Notes
        • 2025-03-20 | Release Notes
        • 2025-03-06 | Release Notes
        • 2025-02-20 | Release Notes
        • 2025-02-06 | Release Notes
        • 2025-01-23 | Release Notes
      • 2024
        • 2024-12-24 | Release Notes
        • 2024-12-12 | Release Notes
        • 2024-11-27 | Release Notes
        • 2024-11-14 | Release Notes
        • 2024-10-31 | Release Notes
        • 2024-10-03 | Release Notes
        • 2024-10-17 | Release Notes
        • 2024-09-19 | Release Notes
        • 2024-09-05 | Release Notes
        • 2024-08-22 | Release Notes
        • 2024-08-08 | Release Notes
        • 2024-07-25 | Release Notes
        • 2024-07-11 | Release Notes
        • 2024-06-27 | Release Notes
        • 2024-06-14 | Release Notes
        • 2024-05-30 | Release Notes
        • 2024-05-16 | Release Notes
        • 2024-05-02 | Release Notes
        • 2024-04-18 | Release Notes
        • 2024-04-05 | Release Notes
        • 2024-03-18 | Release Notes
        • 2024-03-05 | Release Notes
        • 2024-02-20 | Release Notes
        • 2024-02-05 | Release Notes
    • 📊Studio Change log
  • Flipside Community
    • Get Started
    • Ambassador Program
    • Join Our Discord
    • Join Our Guild
Powered by GitBook
On this page

Was this helpful?

  1. Data
  2. Data Products
  3. Data Studio (SQL Analysts)
  4. Tutorials
  5. Video Tutorials
  6. Ethereum Tutorials

Block Level and Daily Balances

In this guide, we're going to look at how to create a view of balances at a block level and daily level.

By using the snapshot data in ethereum.core.fact_token_balances we can create a block level view of balances or a daily view. The approach for both methods is similar, but we can start at a block level.

Please note: Balances data is very large. Queries without where filters on block_number of block_timestamp may take a long time. Please do your best to only query what you really need. However, we do realize that some use cases require full history.

We are going to use the same USDC-WETH Uniswap v3 pool from the prior example. We'll start by pulling the decimal transformed balances for the pool from the last 7 days.

select
  block_number,
  block_timestamp,
  user_address,
  contract_address,
  c.symbol,
  balance / pow(10, c.decimals) as balance
from
  ethereum.core.fact_token_balances b
  left join ethereum.core.dim_contracts c on b.contract_address = c.address
where
  user_address = '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640'
  and block_timestamp >= current_date() - 7
  and contract_address in (
    '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
  )

The next step involves filling all the gaps in blocks with the prior value. This pool has a lot of volume as of writing, so there is not much filling to do, as there is already almost a swap every block. However, something like an EOA (wallet) will have much less volume, and therefore has more filling to do. We will fill by block_number here, but if you only needed daily balances, you could fill by block_timestamp::date.

Once we have our spine of block_number, user_address, contract_address, and symbol, we can left join in our balances data, and fill the gaps with the prior valid value. Let's do this with a few CTEs.

with balances as (
  select
    block_number,
    block_timestamp,
    user_address,
    contract_address,
    c.symbol,
    balance / pow(10, c.decimals) as balance
  from
    ethereum.core.fact_token_balances b
    left join ethereum.core.dim_contracts c on b.contract_address = c.address
  where
    user_address = '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640'
    and block_timestamp >= current_date() - 7
    and contract_address in (
      '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
      '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
    )
),
-- create a spine of all the possible combos
spine as (
  select
    block_number,
    block_timestamp,
    user_address,
    contract_address,
    symbol
  from
    ethereum.core.fact_blocks b
    join (
      select
        distinct contract_address,
        user_address,
        symbol
      from
        balances
    ) on 1 = 1
  where
    block_number between (
      select
        min(block_number)
      from
        balances
    )
    and (
      select
        max(block_number)
      from
        balances
    )
),
-- join all options with transfer based data and fill gaps 
block_level_balances as (
  select
    s.block_number,
    s.block_timestamp,
    s.user_address,
    s.contract_address,
    s.symbol,
    b.balance,
    LAST_VALUE(b.balance ignore nulls) over(
      PARTITION BY s.user_address,
      s.contract_address
      ORDER BY
        s.block_number ASC rows unbounded preceding
    ) as balance_filled
  from
    spine s
    left join balances b using (block_number, user_address, contract_address)
)
select
  *
from
  block_level_balances;

This gives us the WETH and USDC balance, per block, for the Uniswap V3 pool. We could take this a step further by filtering to just the last balace per day using the following final step.

select
  block_timestamp :: date as block_date,
  block_number,
  user_address,
  contract_address,
  symbol,
  balance_filled as balance
from
  block_level_balances qualify (
    row_number() over (
      partition by user_address,
      contract_address,
      block_date
      order by
        block_number desc
    ) = 1
  )
order by
  block_date,
  user_address,
  contract_address

If you wanted to analyze the total supply of a token, you would want to remove the user_address filter. There are many possibilities with these tables, but remember to use as many filters as possible for optimal performance.

PreviousGetting Started with Ethereum BalancesNextFinding Centralized Exchange Flows

Last updated 1 year ago

Was this helpful?