silver model -> direct volume. split out router vol. upd token join in gold

This commit is contained in:
Jack Forgash 2025-07-29 15:56:21 -06:00
parent 879f1785dc
commit 9e907a1b1f
4 changed files with 79 additions and 104 deletions

View File

@ -69,7 +69,7 @@ token_prices_in AS (
-- Join with dim_tokens for token metadata
LEFT JOIN {{ ref('core__dim_tokens') }} dim_in
ON bs.token_in_type = dim_in.coin_type
ON lower(bs.token_in_type) = lower(dim_in.coin_type)
-- Standard token address join
LEFT JOIN crosschain.price.ez_prices_hourly p_in_std
@ -119,7 +119,7 @@ with_all_prices AS (
-- Join with dim_tokens for token metadata
LEFT JOIN {{ ref('core__dim_tokens') }} dim_out
ON tpi.token_out_type = dim_out.coin_type
ON lower(tpi.token_out_type) = lower(dim_out.coin_type)
-- Standard token address join
LEFT JOIN crosschain.price.ez_prices_hourly p_out_std

View File

@ -1,59 +0,0 @@
# DEX Router Analysis Notes
## Problem Statement
Universal router contracts on Sui create transactions with >2 token types, making token parsing ambiguous for dex swap models. Router transactions orchestrate complex multi-hop swaps across different protocols.
## Router vs Direct Swap Patterns
Based on analysis of 3-day transaction data, each DEX protocol has distinct router usage patterns:
### **Cetus**
- Direct swaps: `transaction_module = 'cetus'` (331,336 events)
- Router swaps: Various modules including:
- `'router'` (147,071 events)
- `'swap_router'` (24,168 events)
- `'pool_script_v2'` (25,965 events)
- **Recommendation**: Filter to `transaction_module = 'cetus'` for direct swaps only
### **Turbos**
- Direct swaps: `transaction_module = 'turbos'` (74,925 events)
- Router swaps:
- `'swap_router'` (47,184 events)
- `'router'` (14,247 events)
- **Recommendation**: Filter to `transaction_module = 'turbos'` for direct swaps only
### **FlowX**
- Direct swaps: `transaction_module = 'flowx_clmm'` (56,747 events)
- Router swaps: `'swap_router'` (15,680 events), `'router'` (6,303 events)
- **Status**: Already correctly filtered to `flowx_clmm` in current model
### **Aftermath**
- Only router swaps: `transaction_module = 'router'` (65,999 events)
- **Recommendation**: Keep as-is (no direct swap module available)
### **Bluefin**
- Only direct swaps: `transaction_module = 'bluefin'` (238,066 events)
- **Status**: No router patterns detected
### **Momentum**
- Only direct swaps: `transaction_module = 'momentum'` (101,503 events)
- **Status**: No router patterns detected
### **Universal Router**
- Router-only protocol: `transaction_module = 'universal_router'` (29,784 events)
- **Recommendation**: Remove from silver__dex_swaps entirely (already planned)
## Example Router Transaction
Transaction `HCBEk7jHxAV2uK89FkSKjU7v7ebTSsTrZ3hYU1C3ot3R` demonstrates the multi-token issue:
- Router orchestrates USDC → STSUI → SUI swap
- Contains 3 token types in transaction payload
- Events show calls to both router and underlying DEX modules
## Implementation Plan
1. Remove `universal_router_swaps` CTE entirely
2. Add `transaction_module` filters for Cetus and Turbos
3. Keep Aftermath, Bluefin, Momentum, and FlowX as-is
4. Update event type filter to remove Universal Router events
## Date: 2025-07-29
## Analysis Period: 3-day lookback from 2025-07-26

View File

@ -36,13 +36,14 @@ WITH core_events AS (
{% endif %}
(
type = '0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302::cetus::CetusSwapEvent' -- Cetus
OR type = '0x91bfbc386a41afcfd9b2533058d7e915a1d3829089cc268ff4333d54d6339ca1::pool::SwapEvent' -- Turbos
OR type = '0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302::turbos::TurbosSwapEvent' -- Turbos
OR type = '0x3b6d71bdeb8ce5b06febfd3cfc29ecd60d50da729477c8b8038ecdae34541b91::bluefin::BluefinSwapEvent' -- Bluefin
OR type = '0xd675e6d727bb2d63087cc12008bb91e399dc7570100f72051993ec10c0428f4a::events::SwapCompletedEventV2' -- Aftermath AMM
OR type = '0x25929e7f29e0a30eb4e692952ba1b5b65a3a4d65ab5f2a32e1ba3edcb587f26d::pool::Swap' -- FlowX
OR type = '0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302::flowx_clmm::FlowxClmmSwapEvent' -- FlowX
OR type = '0xe8f996ea6ff38c557c253d3b93cfe2ebf393816487266786371aa4532a9229f2::settle::Swap' -- DeepBook
OR type = '0x0018f7bbbece22f4272ed2281b290f745e5aa69d870f599810a30b4eeffc1a5e::momentum::MomentumSwapEvent' -- Momentum
OR type = '0x200e762fa2c49f3dc150813038fbf22fd4f894ac6f23ebe1085c62f2ef97f1ca::obric::ObricSwapEvent' -- OBRIC
OR type = '0x1cb7b329ad70808d67401b84aac86823f9e0a117b3f10758cf474a19a6b966f4::magma_clmm::MagmaSwapEvent' -- Magma
)
-- limit to 30 days for dev
AND block_timestamp >= sysdate() - interval '30 days'
@ -116,18 +117,18 @@ turbos_swaps AS (
parsed_json:pool::STRING AS pool_address,
parsed_json:amount_in::NUMBER AS amount_in_raw,
parsed_json:amount_out::NUMBER AS amount_out_raw,
parsed_json:a_to_b::BOOLEAN AS a_to_b,
parsed_json:a2b::BOOLEAN AS a_to_b,
parsed_json:fee_amount::NUMBER AS fee_amount_raw,
NULL AS partner_address,
NULL AS referral_amount_raw,
1 AS steps,
IFF(
parsed_json:a_to_b::BOOLEAN,
parsed_json:a2b::BOOLEAN,
parsed_json:coin_a:name::STRING,
parsed_json:coin_b:name::STRING
) AS token_in_type,
IFF(
parsed_json:a_to_b::BOOLEAN,
parsed_json:a2b::BOOLEAN,
parsed_json:coin_b:name::STRING,
parsed_json:coin_a:name::STRING
) AS token_out_type,
@ -135,7 +136,7 @@ turbos_swaps AS (
transaction_module,
modified_timestamp
FROM core_events
WHERE type = '0x91bfbc386a41afcfd9b2533058d7e915a1d3829089cc268ff4333d54d6339ca1::pool::SwapEvent'
WHERE type = '0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302::turbos::TurbosSwapEvent'
AND transaction_module = 'turbos'
),
@ -199,48 +200,36 @@ aftermath_amm_swaps AS (
flowx_swaps AS (
SELECT
e.checkpoint_number,
e.block_timestamp,
e.tx_digest,
e.event_index,
checkpoint_number,
block_timestamp,
tx_digest,
event_index,
'FlowX' AS platform,
e.event_address AS platform_address,
e.parsed_json:pool_id::STRING AS pool_address,
-- FlowX uses amount_x/amount_y with x_for_y direction flag
IFF(
parsed_json:x_for_y::BOOLEAN,
parsed_json:amount_x::NUMBER,
parsed_json:amount_y::NUMBER
) AS amount_in_raw,
IFF(
parsed_json:x_for_y::BOOLEAN,
parsed_json:amount_y::NUMBER,
parsed_json:amount_x::NUMBER
) AS amount_out_raw,
e.parsed_json:x_for_y::BOOLEAN AS a_to_b,
e.parsed_json:fee_amount::NUMBER AS fee_amount_raw,
event_address AS platform_address,
parsed_json:pool::STRING AS pool_address,
parsed_json:amount_in::NUMBER AS amount_in_raw,
parsed_json:amount_out::NUMBER AS amount_out_raw,
parsed_json:a2b::BOOLEAN AS a_to_b,
parsed_json:fee_amount::NUMBER AS fee_amount_raw,
NULL AS partner_address,
NULL AS referral_amount_raw,
1 AS steps,
-- Token types based on swap direction
IFF(
e.parsed_json:x_for_y::BOOLEAN,
tx.payload_details:type_arguments[0]::STRING,
tx.payload_details:type_arguments[1]::STRING
parsed_json:a2b::BOOLEAN,
parsed_json:coin_a:name::STRING,
parsed_json:coin_b:name::STRING
) AS token_in_type,
IFF(
e.parsed_json:x_for_y::BOOLEAN,
tx.payload_details:type_arguments[1]::STRING,
tx.payload_details:type_arguments[0]::STRING
parsed_json:a2b::BOOLEAN,
parsed_json:coin_b:name::STRING,
parsed_json:coin_a:name::STRING
) AS token_out_type,
e.parsed_json:sender::STRING AS trader_address,
e.transaction_module,
e.modified_timestamp
FROM core_events e
LEFT JOIN fact_transactions tx ON e.tx_digest = tx.tx_digest
AND tx.payload_details:module::STRING = 'flowx_clmm'
WHERE e.type = '0x25929e7f29e0a30eb4e692952ba1b5b65a3a4d65ab5f2a32e1ba3edcb587f26d::pool::Swap'
AND e.transaction_module = 'flowx_clmm'
tx_sender AS trader_address,
transaction_module,
modified_timestamp
FROM core_events
WHERE type = '0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302::flowx_clmm::FlowxClmmSwapEvent'
AND transaction_module = 'flowx_clmm'
),
deepbook_swaps AS (
@ -335,6 +324,40 @@ obric_swaps AS (
WHERE type = '0x200e762fa2c49f3dc150813038fbf22fd4f894ac6f23ebe1085c62f2ef97f1ca::obric::ObricSwapEvent'
),
magma_swaps AS (
SELECT
checkpoint_number,
block_timestamp,
tx_digest,
event_index,
'Magma' AS platform,
event_address AS platform_address,
parsed_json:pool::STRING AS pool_address,
parsed_json:amount_in::NUMBER AS amount_in_raw,
parsed_json:amount_out::NUMBER AS amount_out_raw,
parsed_json:a2b::BOOLEAN AS a_to_b,
NULL AS fee_amount_raw,
parsed_json:partner_id::STRING AS partner_address,
NULL AS referral_amount_raw,
1 AS steps,
IFF(
parsed_json:a2b::BOOLEAN,
parsed_json:coin_a:name::STRING,
parsed_json:coin_b:name::STRING
) AS token_in_type,
IFF(
parsed_json:a2b::BOOLEAN,
parsed_json:coin_b:name::STRING,
parsed_json:coin_a:name::STRING
) AS token_out_type,
tx_sender AS trader_address,
transaction_module,
modified_timestamp
FROM core_events
WHERE type = '0x1cb7b329ad70808d67401b84aac86823f9e0a117b3f10758cf474a19a6b966f4::magma_clmm::MagmaSwapEvent'
AND transaction_module = 'magma_clmm'
),
all_swaps AS (
SELECT * FROM cetus_swaps
UNION ALL
@ -351,6 +374,8 @@ all_swaps AS (
SELECT * FROM momentum_swaps
UNION ALL
SELECT * FROM obric_swaps
UNION ALL
SELECT * FROM magma_swaps
)
SELECT
@ -368,8 +393,16 @@ SELECT
partner_address,
referral_amount_raw,
steps,
token_in_type,
token_out_type,
IFF(
LEFT(token_in_type, 2) = '0x',
token_in_type,
'0x' || token_in_type
) AS token_in_type,
IFF(
LEFT(token_out_type, 2) = '0x',
token_out_type,
'0x' || token_out_type
) AS token_out_type,
trader_address,
transaction_module,
{{ dbt_utils.generate_surrogate_key(['tx_digest', 'platform_address', 'trader_address', 'token_in_type', 'token_out_type', 'amount_in_raw', 'amount_out_raw']) }} AS dex_swaps_id,

View File

@ -5,7 +5,8 @@
cluster_by = ['modified_timestamp::DATE','block_timestamp::DATE'],
incremental_predicates = ["dynamic_range_predicate", "block_timestamp::date"],
merge_exclude_columns = ["inserted_timestamp"],
tags = ['scheduled_non_core']
tags = ['scheduled_non_core'],
enabled = false
) }}
WITH core_events AS (