Skip to main content
Schema: ethereum.defi Table: ez_liquid_staking_withdrawals Type: View

What

This table tracks liquid staking withdrawals/unstaking events across major LSD protocols. It captures when users burn their liquid staking tokens to reclaim ETH, providing insights into unstaking patterns, liquidity needs, and protocol exit flows.

Key Use Cases

  • Monitoring withdrawal volumes and exit liquidity
  • Analyzing net staking flows (deposits minus withdrawals)
  • Understanding staker holding periods and behavior
  • Detecting large withdrawals and de-risking events
  • Tracking exchange rates at withdrawal time

Important Relationships

  • Links to ez_liquid_staking_deposits for position lifecycle analysis
  • Connects to core.fact_event_logs for transaction details
  • References withdrawal queue contracts for protocols with exit delays
  • Uses price.ez_prices_hourly for USD valuations

Commonly-used Fields

  • staker: Address performing the unstaking
  • platform: Liquid staking protocol name
  • eth_amount: Amount of ETH received
  • token_amount: LSD tokens burned
  • token_symbol: Symbol of the LSD token
  • block_timestamp: When withdrawal occurred

Sample queries

-- Daily withdrawal patterns by protocol
SELECT 
    DATE_TRUNC('day', block_timestamp) AS date,
    platform,
    COUNT(*) AS withdrawal_txns,
    COUNT(DISTINCT staker) AS unique_unstakers,
    SUM(eth_amount) AS eth_withdrawn,
    SUM(eth_amount_usd) AS usd_withdrawn,
    AVG(eth_amount) AS avg_withdrawal_size
FROM defi.ez_liquid_staking_withdrawals
WHERE block_timestamp >= CURRENT_DATE - 30
    AND eth_amount_usd IS NOT NULL
GROUP BY 1, 2
ORDER BY 1 DESC, 5 DESC;

-- Net staking flows (deposits vs withdrawals)
WITH daily_deposits AS (
    SELECT 
        DATE_TRUNC('day', block_timestamp) AS date,
        platform,
        SUM(eth_amount) AS eth_deposited,
        COUNT(DISTINCT staker) AS depositors
    FROM defi.ez_liquid_staking_deposits
    WHERE block_timestamp >= CURRENT_DATE - 30
        AND eth_amount IS NOT NULL
    GROUP BY 1, 2
),
daily_withdrawals AS (
    SELECT 
        DATE_TRUNC('day', block_timestamp) AS date,
        platform,
        SUM(eth_amount) AS eth_withdrawn,
        COUNT(DISTINCT staker) AS withdrawers
    FROM defi.ez_liquid_staking_withdrawals
    WHERE block_timestamp >= CURRENT_DATE - 30
        AND eth_amount IS NOT NULL
    GROUP BY 1, 2
)
SELECT 
    COALESCE(d.date, w.date) AS date,
    COALESCE(d.platform, w.platform) AS platform,
    COALESCE(d.eth_deposited, 0) AS eth_deposited,
    COALESCE(w.eth_withdrawn, 0) AS eth_withdrawn,
    COALESCE(d.eth_deposited, 0) - COALESCE(w.eth_withdrawn, 0) AS net_eth_flow,
    COALESCE(d.depositors, 0) AS depositors,
    COALESCE(w.withdrawers, 0) AS withdrawers
FROM daily_deposits d
FULL OUTER JOIN daily_withdrawals w 
    ON d.date = w.date AND d.platform = w.platform
ORDER BY date DESC, ABS(net_eth_flow) DESC;

-- Staker holding period analysis
WITH staker_lifecycle AS (
    SELECT 
        d.staker,
        d.platform,
        d.block_timestamp AS deposit_time,
        MIN(w.block_timestamp) AS withdrawal_time,
        d.eth_amount AS deposit_amount,
        d.token_amount AS tokens_received
    FROM defi.ez_liquid_staking_deposits d
    LEFT JOIN defi.ez_liquid_staking_withdrawals w
        ON d.staker = w.staker 
        AND d.platform = w.platform
        AND d.token_address = w.token_address
        AND w.block_timestamp > d.block_timestamp
    WHERE d.eth_amount IS NOT NULL
    GROUP BY 1, 2, 3, 5, 6
)
SELECT 
    platform,
    COUNT(CASE WHEN withdrawal_time IS NOT NULL THEN 1 END) AS completed_cycles,
    COUNT(CASE WHEN withdrawal_time IS NULL THEN 1 END) AS still_staking,
    AVG(CASE 
        WHEN withdrawal_time IS NOT NULL 
        THEN EXTRACT(EPOCH FROM (withdrawal_time - deposit_time)) / 86400 
    END) AS avg_holding_days,
    PERCENTILE_CONT(0.5) WITHIN GROUP (
        ORDER BY CASE 
            WHEN withdrawal_time IS NOT NULL 
            THEN EXTRACT(EPOCH FROM (withdrawal_time - deposit_time)) / 86400 
        END
    ) AS median_holding_days
FROM staker_lifecycle
WHERE deposit_time >= CURRENT_DATE - 365
GROUP BY platform
ORDER BY completed_cycles DESC;

-- Exchange rate at withdrawal (profit/loss analysis)
SELECT 
    platform,
    token_symbol,
    DATE_TRUNC('week', block_timestamp) AS week,
    AVG(eth_amount / NULLIF(token_amount, 0)) AS avg_redemption_rate,
    MIN(eth_amount / NULLIF(token_amount, 0)) AS min_rate,
    MAX(eth_amount / NULLIF(token_amount, 0)) AS max_rate,
    COUNT(*) AS withdrawals
FROM defi.ez_liquid_staking_withdrawals
WHERE token_amount > 0 
    AND eth_amount > 0
    AND block_timestamp >= CURRENT_DATE - 90
GROUP BY 1, 2, 3
ORDER BY 1, 3 DESC;

-- Large withdrawals monitoring (potential de-risking)
SELECT 
    block_timestamp,
    tx_hash,
    platform,
    staker,
    eth_amount,
    eth_amount_usd,
    token_symbol,
    token_amount,
    eth_amount / NULLIF(token_amount, 0) AS redemption_rate
FROM defi.ez_liquid_staking_withdrawals
WHERE eth_amount >= 100
    AND block_timestamp >= CURRENT_DATE - 3
ORDER BY eth_amount DESC;

-- Withdrawal pressure indicators
WITH hourly_flows AS (
    SELECT 
        DATE_TRUNC('hour', block_timestamp) AS hour,
        platform,
        SUM(eth_amount) AS hourly_withdrawals,
        COUNT(*) AS withdrawal_count,
        COUNT(DISTINCT staker) AS unique_withdrawers
    FROM defi.ez_liquid_staking_withdrawals
    WHERE block_timestamp >= CURRENT_DATE - 7
        AND eth_amount IS NOT NULL
    GROUP BY 1, 2
)
SELECT 
    platform,
    MAX(hourly_withdrawals) AS peak_hourly_withdrawal,
    AVG(hourly_withdrawals) AS avg_hourly_withdrawal,
    MAX(withdrawal_count) AS peak_withdrawal_count,
    STDDEV(hourly_withdrawals) AS withdrawal_volatility
FROM hourly_flows
GROUP BY platform
HAVING MAX(hourly_withdrawals) > 100
ORDER BY peak_hourly_withdrawal DESC;

Columns

Column NameData TypeDescription
BLOCK_NUMBERNUMBERSequential counter representing the position of a block in the blockchain since genesis (block 0). Key Facts: Immutable once finalized Primary ordering mechanism for blockchain data Increments by 1 for each new block Used as a proxy for time in many analyses Usage in Queries: Important: Block numbers are chain-specific. Block 15000000 on Ethereum ≠ block 15000000 on Polygon.
BLOCK_TIMESTAMPTIMESTAMP_NTZUTC timestamp when the block was produced by validators/miners. Format: TIMESTAMP_NTZ (no timezone) Precision: Second-level accuracy Reliability: Set by block producer Can have minor variations (±15 seconds) Always increasing (newer blocks = later timestamps) Best Practices: Note: Use for time-series analysis, but be aware that block production rates vary by chain.
ORIGIN_FUNCTION_SIGNATURETEXTFunction signature (first 4 bytes) of the called method. Format: 0x + 8 hex characters Common Signatures: 0xa9059cbb: transfer(address,uint256) 0x095ea7b3: approve(address,uint256) 0x23b872dd: transferFrom(address,address,uint256) Note: NULL for simple transfers or invalid calls
ORIGIN_FROM_ADDRESSTEXTThe externally-owned account (EOA) or contract address that initiated the transaction. Key Points: Always 42 characters (0x + 40 hex chars) Lowercase normalized in all tables Cannot be NULL for valid transactions For contract creation: sender of creation transaction Common Patterns: EOA → EOA: Simple transfer EOA → Contract: User interaction Contract → Contract: Internal calls (see fact_traces) Known addresses: Exchange hot wallets, protocol deployers Query Examples:
ORIGIN_TO_ADDRESSTEXTThe destination address for the transaction - either an EOA or contract address. Special Cases: NULL: Contract creation transaction Contract address: Interacting with smart contract EOA address: Simple transfer or receiving funds Important Patterns: Note: For token transfers, this is the token contract, not the recipient. See eztokentransfers tables for recipient.
TX_HASHTEXTUnique 66-character identifier for the transaction. Format: 0x + 64 hexadecimal characters Usage: Primary key for transaction lookups Join key for traces, logs, and token transfers Immutable once confirmed Example: 0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060
EVENT_INDEXNUMBERZero-based sequential position of the event within a transaction’s execution. Key Facts: Starts at 0 for first event Increments across all contracts in transaction Preserves execution order Essential for deterministic event ordering Usage Example:
EVENT_NAMETEXTThe event name as defined in the contract’s ABI. Format: PascalCase event identifier Examples: Transfer - Token transfers Swap - DEX trades OwnershipTransferred - Admin changes Approval - Token approvals Usage Pattern:
CONTRACT_ADDRESSTEXTSmart contract address that emitted this event or received the transaction. Key Points: Always the immediate event emitter for logs May differ from transaction to_address Lowercase normalized format Never NULL for valid events
STAKERTEXTThe address performing the staking or unstaking action. Example: ‘0x1234567890123456789012345678901234567890’
PLATFORMTEXTThe liquid staking protocol processing the transaction. Example: ‘lido’
TOKEN_SYMBOLTEXTThe symbol of the liquid staking derivative token. Example: ‘stETH’
TOKEN_ADDRESSTEXTThe contract address of the liquid staking token. Example: ‘0xae7ab96520de3a18e5e111b5eaab095312d7fe84’
TOKEN_AMOUNT_UNADJNUMBERThe raw amount of liquid staking tokens without decimal adjustment. Example: 999500000000000000
TOKEN_AMOUNTFLOATThe decimal-adjusted amount of liquid staking tokens minted or burned. Example: 0.9995
TOKEN_AMOUNT_USDFLOATThe USD value of liquid staking tokens minted or burned. Example: 2498.75
ETH_AMOUNT_UNADJFLOATThe raw amount of ETH without decimal adjustment. Example: 1000000000000000000
ETH_AMOUNTFLOATThe decimal-adjusted amount of ETH staked or withdrawn. Example: 1.0
ETH_AMOUNT_USDFLOATThe USD value of ETH staked or withdrawn. Example: 2500.50
EZ_LIQUID_STAKING_WITHDRAWALS_IDTEXTPrimary key - unique identifier for each row ensuring data integrity. Format: Usually VARCHAR containing composite key generated using MD5 hash of the relevant columns. Example: MD5(blocknumber, txhash, trace_index) Usage: Deduplication in incremental loads Join operations for data quality checks Troubleshooting specific records Important: Implementation varies by table - check table-specific documentation.
INSERTED_TIMESTAMPTIMESTAMP_NTZUTC timestamp when the record was first added to the Flipside database. Format: TIMESTAMP_NTZ Use Cases: Data freshness monitoring Incremental processing markers Debugging data pipeline issues SLA tracking Query Example:
MODIFIED_TIMESTAMPTIMESTAMP_NTZUTC timestamp of the most recent update to this record. Format: TIMESTAMP_NTZ Triggers for Updates: Data corrections Enrichment additions Reprocessing for accuracy Schema migrations Monitoring Usage: