diff --git a/.github/workflows/dbt_run_abi_refresh.yml b/.github/workflows/dbt_run_abi_refresh.yml index 2474ff4..7cc1dfe 100644 --- a/.github/workflows/dbt_run_abi_refresh.yml +++ b/.github/workflows/dbt_run_abi_refresh.yml @@ -3,9 +3,8 @@ run-name: dbt_run_abi_refresh on: workflow_dispatch: - schedule: - # Runs “At minute 10 past every 12th hour.” (see https://crontab.guru) - - cron: '10 */12 * * *' + branches: + - "main" env: DBT_PROFILES_DIR: ./ @@ -42,7 +41,11 @@ jobs: run: | pip install -r requirements.txt dbt deps - - name: Run DBT Jobs + + - name: Update ABI models run: | dbt run -m "blast_models,tag:abis" - \ No newline at end of file + + - name: Kick off decoded logs history, if there are new ABIs from users + run: | + dbt run-operation run_decoded_logs_history \ No newline at end of file diff --git a/.github/workflows/dbt_run_scheduled_decoded_logs_history_user_abis.yml b/.github/workflows/dbt_run_traces_fix.yml similarity index 60% rename from .github/workflows/dbt_run_scheduled_decoded_logs_history_user_abis.yml rename to .github/workflows/dbt_run_traces_fix.yml index 63bf5a2..7d076cb 100644 --- a/.github/workflows/dbt_run_scheduled_decoded_logs_history_user_abis.yml +++ b/.github/workflows/dbt_run_traces_fix.yml @@ -1,10 +1,15 @@ -name: dbt_run_scheduled_decoded_logs_history_user_abis -run-name: dbt_run_scheduled_decoded_logs_history_user_abis +name: dbt_run_traces_fix +run-name: dbt_run_traces_fix on: workflow_dispatch: - branches: - - "main" + inputs: + use_xl_env: + description: "Use the 2xl environment" + type: boolean + schedule: + # every 15 minutes (see https://crontab.guru) + - cron: "*/15 * * * *" env: DBT_PROFILES_DIR: ./ @@ -25,7 +30,7 @@ jobs: run_dbt_jobs: runs-on: ubuntu-latest environment: - name: workflow_prod + name: ${{ github.event_name == 'workflow_dispatch' && inputs.use_xl_env && 'workflow_prod_2xl' || 'workflow_prod_backfill' }} steps: - uses: actions/checkout@v3 @@ -40,6 +45,6 @@ jobs: pip install -r requirements.txt dbt deps - - name: Kick off decoded logs history, if there are new ABIs from users + - name: run traces fix model run: | - dbt run-operation run_decoded_logs_history \ No newline at end of file + dbt run -m "blast_models,tag:traces_fix" diff --git a/.github/workflows/dbt_test_tasks.yml b/.github/workflows/dbt_test_tasks.yml deleted file mode 100644 index a1ffffa..0000000 --- a/.github/workflows/dbt_test_tasks.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: dbt_test_tasks -run-name: dbt_test_tasks - -on: - workflow_dispatch: - branches: - - "main" - -env: - DBT_PROFILES_DIR: ./ - - ACCOUNT: "${{ vars.ACCOUNT }}" - ROLE: "${{ vars.ROLE }}" - USER: "${{ vars.USER }}" - PASSWORD: "${{ secrets.PASSWORD }}" - REGION: "${{ vars.REGION }}" - DATABASE: "${{ vars.DATABASE }}" - WAREHOUSE: "${{ vars.WAREHOUSE }}" - SCHEMA: "${{ vars.SCHEMA }}" - -concurrency: - group: ${{ github.workflow }} - - - -jobs: - called_workflow_template: - uses: FlipsideCrypto/analytics-workflow-templates/.github/workflows/dbt_test_tasks.yml@main - secrets: inherit \ No newline at end of file diff --git a/data/github_actions__workflows.csv b/data/github_actions__workflows.csv index 3f7d109..e510212 100644 --- a/data/github_actions__workflows.csv +++ b/data/github_actions__workflows.csv @@ -2,7 +2,6 @@ workflow_name,workflow_schedule dbt_run_scheduled_non_realtime,"17,47 * * * *" dbt_run_streamline_chainhead,"10,40 * * * *" dbt_run_streamline_decoder,"25,55 * * * *" -dbt_test_tasks,"10 * * * *" -dbt_run_scheduled_curated,"30 * * * *" +dbt_run_scheduled_curated,"30 */4 * * *" dbt_run_streamline_decoded_logs_history,"5 3 * * 6" -dbt_run_scheduled_decoded_logs_history_user_abis,"56 23 * * *" \ No newline at end of file +dbt_run_abi_refresh,"48 23 * * *" \ No newline at end of file diff --git a/data/silver_bridge__layerzero_bridge_seed.csv b/data/silver_bridge__layerzero_bridge_seed.csv new file mode 100644 index 0000000..882e2bf --- /dev/null +++ b/data/silver_bridge__layerzero_bridge_seed.csv @@ -0,0 +1,94 @@ +chain,eid +Ape, 30312 +Arbitrum, 30110 +Arbitrum Nova, 30175 +Astar, 30210 +Astar zkEVM, 30257 +Avalanche, 30106 +Base, 30184 +Bevm, 30317 +Binance Smart Chain, 30102 +Bitlayer, 30314 +Blast, 30243 +Bob, 30279 +Canto, 30159 +Celo, 30125 +Codex, 30323 +Conflux eSpace, 30212 +Core Blockchain, 30153 +Cyber, 30283 +DOS Chain, 30149 +DeFi Kingdoms, 30115 +Degen, 30267 +Dexalot Subnet, 30118 +Dm2verse, 30315 +EBI, 30282 +Edu, 30328 +Ethereum, 30101 +Etherlink, 30292 +Fantom, 30112 +Flare, 30295 +Fraxtal, 30255 +Fuse, 30138 +Gnosis, 30145 +Gravity, 30294 +Harmony, 30116 +Hedera, 30316 +Hemi, 30329 +Homeverse, 30265 +Horizen EON, 30215 +Hubble, 30182 +Iota, 30284 +Japan Open Chain, 30285 +Kaia, 30150 +Kava, 30177 +Lightlink, 30309 +Linea, 30183 +Lisk, 30321 +Loot, 30197 +Lyra, 30311 +Manta, 30217 +Mantle, 30181 +Masa, 30263 +Meritcircle, 30198 +Merlin, 30266 +Meter, 30176 +Metis, 30151 +Mode, 30260 +Moonbeam, 30126 +Moonriver, 30167 +Morph, 30322 +Near Aurora, 30211 +OKXChain, 30155 +Optimism, 30111 +Orderly, 30213 +Peaq, 30302 +Polygon, 30109 +Polygon zkEVM, 30158 +Rari Chain, 30235 +Reya, 30313 +Sanko, 30278 +Scroll, 30214 +Sei, 30280 +Shimmer, 30230 +Skale, 30273 +Solana, 30168 +Superposition, 30327 +Taiko, 30290 +TelosEVM, 30199 +Tenet, 30173 +Tiltyard, 30238 +Tron, 30420 +Viction, 30196 +Worldchain, 30319 +X Layer, 30274 +XChain, 30291 +XPLA, 30216 +Xai, 30236 +Zircuit, 30303 +Zora, 30195 +inEVM, 30234 +opBNB, 30202 +re.al, 30237 +zkLink, 30301 +zkSync Era, 30165 \ No newline at end of file diff --git a/data/silver_bridge__orbiter_bridge_seed.csv b/data/silver_bridge__orbiter_bridge_seed.csv new file mode 100644 index 0000000..38bdfee --- /dev/null +++ b/data/silver_bridge__orbiter_bridge_seed.csv @@ -0,0 +1,52 @@ +name,chainid,identificationcode +ethereum,1,9001 +arbitrum,42161,9002 +zksync_lite,zksync,9003 +starknet,SN_MAIN,9004 +polygon,137,9006 +optimism,10,9007 +immutable_x,immutableX,9008 +loopring,loopring,9009 +metis,1088,9010 +zkspace,ZKSpace,9012 +zksynce_era,324,9014 +bsc,56,9015 +arbitrum_nova,42170,9016 +polygon_zkevm,1101,9017 +scroll,534352,9019 +taiko,167000,9020 +base,8453,9021 +linea,59144,9023 +mantle,5000,9024 +opbnb,204,9025 +x_layer,196,9027 +zora,7777777,9030 +manta,169,9031 +kroma,255,9036 +zkfair,42766,9038 +blast,81457,9040 +zetachain,7000,9041 +b2_network,223,9046 +mode,34443,9047 +zklink_nova,810180,9048 +solana,SOLANA_MAIN,9051 +morph,2818,9052 +proof_of_play_apex,70700,9053 +merlin,4200,9054 +bevm,11501,9055 +ton,TON,9056 +bob,60808,9057 +core_blockchain,1116,9058 +bitlayer,200901,9059 +bouncebit,6001,9064 +eclipse,ECLIPSE_MAIN,9065 +optopia,62050,9066 +cyber,7560,9067 +mint,185,9068 +tron,728126428,9079 +matchain,698,9084 +lisk,1135,9086 +redstone,690,9087 +kaia,8217,9089 +fuel,FUEL_MAIN,9094 +worldchain,480,9095 \ No newline at end of file diff --git a/data/silver_bridge__standard_dst_chain_seed.csv b/data/silver_bridge__standard_dst_chain_seed.csv new file mode 100644 index 0000000..58dd484 --- /dev/null +++ b/data/silver_bridge__standard_dst_chain_seed.csv @@ -0,0 +1,139 @@ +destination_chain,standard_destination_chain +acala,acala +algorand,algorand +aptos,aptos +arbitrum,arbitrum +arbitrum nova,arbitrum nova +arbitrum_nova,arbitrum nova +arbitrum one,arbitrum +archway,archway +astar,astar +aurora,aurora +aurora mainnet,aurora +avalanche,avalanche +avalanche c-chain,avalanche +base,base +bnb,bsc +bnb chain,bsc +bnb smart chain mainnet,bsc +bob,boba +boba bnb mainnet,boba +boba network,boba +bsc,bsc +canto,canto +carbon,carbon +celo,celo +celo mainnet,celo +coinweb,coinweb +conflux,conflux +conflux espace,conflux +core blockchain mainnet,core +crab network,crab +crescent,crescent +cronos mainnet,cronos +crypto chain,crypto +cyber,cyber +cyber mainnet,cyber +dfk chain,dfk +dogechain mainnet,dogechain +eos,eos +endurance smart chain mainnet,endurance smart chain +ethereum,ethereum +ethereum mainnet,ethereum +everclear mainnet,everclear +evmos,evmos +fantom,fantom +fantom opera,fantom +filecoin,filecoin +flare mainnet,flare +fraxchain mainnet,fraxchain +fuse,fuse +fuse mainnet,fuse +gnosis,gnosis +gravity,gravity +gravity alpha mainnet,gravity +harmony mainnet shard 0,harmony +huobi eco chain mainnet,huobi eco +inevm,inevm +inevm mainnet,inevm +injective,injective +immutable,immutable x +immutable_x,immutable x +juno,juno +karura,karura +kava,kava +klaytn,klaytn +klaytn mainnet cypress,klaytn +kujira,kujira +linea,linea +lukso mainnet,lukso +manta,manta +manta pacific mainnet,manta +mantle,mantle +metis,metis +metis andromeda mainnet,metis +mint,mint +mint mainnet,mint +moonbeam,moonbeam +moonriver,moonriver +nautilus,nautilus +near,near +neutron,neutron +oasis,oasis +okbchain mainnet,okbchain +okxchain mainnet,okxchain +ontology mainnet,ontology +op mainnet,optimism +opbnb,opbnb +optimism,optimism +osmosis,osmosis +orderly mainnet,orderly +polygon,polygon +polygon mainnet,polygon +polygon pos,polygon +polygon zkevm,polygon zkevm +polygon_zkevm,polygon zkevm +proof of play - apex,proof of play apex +proof_of_play_apex,proof of play apex +ronin,ronin +scroll,scroll +secret-snip,secret +sei,sei +sei network,sei +skale europa,skale europa +skale nebula,skale nebula +solana,solana +stargaze,stargaze +starknet,starknet +sui,sui +taiko,taiko +taiko mainnet,taiko +telos evm mainnet,telos +terra,terra +terra-2,terra2 +terra2,terra2 +tezos,tezos +tron,tron +umee,umee +waves,waves +world chain,worldchain +worldchain,worldchain +xpla,xpla +xrpl,xrpl +x layer,x layer +x_layer,x layer +zkfair,zkfair +zetachain,zetachain +zetachain mainnet,zetachain +zircuit,zircuit +zircuit mainnet,zircuit +zklink_nova,zklink nova +zksync era,zksync era +zksync era mainnet,zksync era +zksynce_era,zksync era +zksync lite,zksync lite +zksync_lite,zksync lite +zora,zora +zzz,zzz + + diff --git a/models/bronze/api_udf/bronze_api__contract_abis.sql b/models/bronze/api_udf/bronze_api__contract_abis.sql index 622e30d..0d8fa36 100644 --- a/models/bronze/api_udf/bronze_api__contract_abis.sql +++ b/models/bronze/api_udf/bronze_api__contract_abis.sql @@ -26,7 +26,7 @@ FROM {% endif %} order by total_interaction_count desc LIMIT - 50 + 400 ), all_contracts AS ( SELECT contract_address @@ -48,7 +48,7 @@ row_nos AS ( FROM all_contracts ), -batched AS ({% for item in range(101) %} +batched AS ({% for item in range(501) %} SELECT rn.contract_address, live.udf_api('GET', CONCAT('https://api.blastscan.io/api?module=contract&action=getabi&address=', rn.contract_address, '&apikey={key}'),{ 'User-Agent': 'FlipsideStreamline' },{}, 'Vault/prod/block_explorers/blast_scan') AS abi_data, SYSDATE() AS _inserted_timestamp FROM diff --git a/models/doc_descriptions/blitz/blitz_table_docs.md b/models/doc_descriptions/blitz/blitz_table_docs.md index 1cc4d25..356cf42 100644 --- a/models/doc_descriptions/blitz/blitz_table_docs.md +++ b/models/doc_descriptions/blitz/blitz_table_docs.md @@ -58,4 +58,29 @@ All staking actions taken with the VRTX staking contract. All edge trades paired with the associated trader/subaccount. +{% enddocs %} + +{% docs blitz_money_markets %} + +Blitz integrates a decentralized money market directly into its DEX, enabling borrowing and lending of crypto assets using overcollateralized lending rules. Interest rates are dynamically adjusted based on supply and demand, incentivizing liquidity provision and balancing borrowing costs. The money market operates on-chain (e.g., on Arbitrum) and is managed through Vertex’s risk engine and clearinghouse, offering users automated borrowing via portfolio margin and passive yield opportunities on idle assets. This table tracks the money market products available on Vertex on an hourly basis. + + +{% enddocs %} + +{% docs blitz_deposit_apr %} + +The recorded deposit APR for the money market product in that hour. + +{% enddocs %} + +{% docs blitz_borrow_apr %} + +The recorded borrow APR for the money market product in that hour. + +{% enddocs %} + +{% docs blitz_tvl %} + +The sum total value locked for the money market product in that hour. + {% enddocs %} \ No newline at end of file diff --git a/models/doc_descriptions/bridge/evm_bridge_activity.md b/models/doc_descriptions/bridge/evm_bridge_activity.md index 4462b99..9886265 100644 --- a/models/doc_descriptions/bridge/evm_bridge_activity.md +++ b/models/doc_descriptions/bridge/evm_bridge_activity.md @@ -1,6 +1,6 @@ {% docs evm_bridge_table_doc %} -A convenience table that aggregates bridge activity from event_logs, traces and transfers, including bridge deposits and transfers sent from the following protocols: ACROSS, AXELAR, CELER, CBRIDGE, DLN, DEBRIDGE, HOP, MESON, STARGATE, SYMBIOSIS, SYNAPSE, WORMHOLE along with other helpful columns, including an amount USD where available. Note, this table only includes records for the protocols listed above with live, onchain bridge activity and may not represent the complete bridging picture. +A convenience table that aggregates bridge activity from event_logs, traces and transfers, including bridge deposits and transfers sent from the following protocols: ACROSS, AXELAR, HYPERLANE, LAYERZERO, ORBITER, SYMBIOSIS, SYNAPSE along with other helpful columns, including an amount USD where available. Note, this table only includes records for the protocols listed above with live, onchain bridge activity and may not represent the complete bridging picture. {% enddocs %} diff --git a/models/doc_descriptions/general/__overview__.md b/models/doc_descriptions/general/__overview__.md index d6d2494..1ab8c4f 100644 --- a/models/doc_descriptions/general/__overview__.md +++ b/models/doc_descriptions/general/__overview__.md @@ -44,6 +44,7 @@ There is more information on how to use dbt docs in the last section of this doc ### DeFi Tables (blast.defi) - [ez_dex_swaps](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__ez_dex_swaps) - [dim_dex_liquidity_pools](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__dim_dex_liquidity_pools) +- [ez_bridge_activity](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__ez_bridge_activity) - [ez_lending_borrows](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__ez_lending_borrows) - [ez_lending_deposits](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__ez_lending_deposits) - [ez_lending_liquidations](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.defi__ez_lending_liquidations) @@ -64,6 +65,7 @@ There is more information on how to use dbt docs in the last section of this doc - [ez_edge_trades](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.blitz__ez_edge_trades) - [ez_market_depth_stats](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.blitz__ez_market_depth_stats) - [ez_market_stats](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.blitz__ez_market_stats) +- [ez_money_markets](https://flipsidecrypto.github.io/blast-models/#!/model/model.blast_models.blitz__ez_money_markets) ## **Helpful User-Defined Functions (UDFs)** diff --git a/models/gold/defi/defi__ez_bridge_activity.sql b/models/gold/defi/defi__ez_bridge_activity.sql new file mode 100644 index 0000000..0863227 --- /dev/null +++ b/models/gold/defi/defi__ez_bridge_activity.sql @@ -0,0 +1,51 @@ +{{ config( + materialized = 'view', + persist_docs ={ "relation": true, + "columns": true }, + meta ={ + 'database_tags':{ + 'table':{ + 'PROTOCOL': 'ACROSS, AXELAR, HYPERLANE, LAYERZERO, ORBITER, SYMBIOSIS, SYNAPSE', + 'PURPOSE': 'BRIDGE' + } } } +) }} + +SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + sender, + receiver, + destination_chain_receiver, + COALESCE( + standard_destination_chain, + b.destination_chain + ) AS destination_chain, + destination_chain_id, + token_address, + token_symbol, + amount_unadj, + amount, + ROUND( + CASE + WHEN amount_usd < 1e+15 THEN amount_usd + ELSE NULL + END, + 2 + ) AS amount_usd, + complete_bridge_activity_id AS ez_bridge_activity_id, + inserted_timestamp, + modified_timestamp +FROM + {{ ref('silver_bridge__complete_bridge_activity') }} + b + LEFT JOIN {{ ref('silver_bridge__standard_dst_chain_seed') }} C + ON b.destination_chain = C.destination_chain + diff --git a/models/gold/defi/defi__ez_bridge_activity.yml b/models/gold/defi/defi__ez_bridge_activity.yml new file mode 100644 index 0000000..2f37964 --- /dev/null +++ b/models/gold/defi/defi__ez_bridge_activity.yml @@ -0,0 +1,54 @@ +version: 2 +models: + - name: defi__ez_bridge_activity + description: '{{ doc("evm_bridge_table_doc") }}' + + columns: + - name: BLOCK_NUMBER + description: '{{ doc("blast_block_number") }}' + - name: BLOCK_TIMESTAMP + description: '{{ doc("blast_block_timestamp") }}' + - name: TX_HASH + description: '{{ doc("blast_logs_tx_hash") }}' + - name: CONTRACT_ADDRESS + description: '{{ doc("blast_logs_contract_address") }}' + - name: EVENT_NAME + description: '{{ doc("blast_event_name") }}' + - name: EVENT_INDEX + description: '{{ doc("blast_event_index") }}' + - name: ORIGIN_FUNCTION_SIGNATURE + description: '{{ doc("nft_origin_sig") }}' + - name: ORIGIN_FROM_ADDRESS + description: '{{ doc("evm_bridge_origin_from") }}' + - name: ORIGIN_TO_ADDRESS + description: '{{ doc("blast_origin_from") }}' + - name: PLATFORM + description: '{{ doc("evm_bridge_platform") }}' + - name: SENDER + description: '{{ doc("evm_bridge_sender") }}' + - name: RECEIVER + description: '{{ doc("evm_bridge_receiver") }}' + - name: DESTINATION_CHAIN_RECEIVER + description: '{{ doc("evm_bridge_destination_chain_receiver") }}' + - name: DESTINATION_CHAIN + description: '{{ doc("evm_bridge_destination_chain") }}' + - name: DESTINATION_CHAIN_ID + description: '{{ doc("evm_bridge_destination_chain_id") }}' + - name: BRIDGE_ADDRESS + description: '{{ doc("evm_bridge_address") }}' + - name: TOKEN_ADDRESS + description: '{{ doc("evm_bridge_token_address") }}' + - name: TOKEN_SYMBOL + description: '{{ doc("evm_bridge_token_symbol") }}' + - name: AMOUNT_UNADJ + description: '{{ doc("evm_bridge_amount_unadj") }}' + - name: AMOUNT + description: '{{ doc("evm_bridge_amount") }}' + - name: AMOUNT_USD + description: '{{ doc("evm_bridge_amount_usd") }}' + - name: EZ_BRIDGE_ACTIVITY_ID + description: '{{ doc("pk") }}' + - name: INSERTED_TIMESTAMP + description: '{{ doc("inserted_timestamp") }}' + - name: MODIFIED_TIMESTAMP + description: '{{ doc("modified_timestamp") }}' \ No newline at end of file diff --git a/models/gold/protocol/blitz/blitz__ez_money_markets.sql b/models/gold/protocol/blitz/blitz__ez_money_markets.sql new file mode 100644 index 0000000..7650acf --- /dev/null +++ b/models/gold/protocol/blitz/blitz__ez_money_markets.sql @@ -0,0 +1,27 @@ + {{ config( + materialized = 'view', + persist_docs ={ "relation": true, + "columns": true }, + meta={ + 'database_tags':{ + 'table': { + 'PROTOCOL': 'BLITZ', + 'PURPOSE': 'CLOB, DEX, STATS' + } + } + } +) }} + +SELECT + hour, + ticker_id, + symbol, + product_id, + deposit_apr, + borrow_apr, + tvl, + blitz_money_markets_id as ez_money_markets_id, + inserted_timestamp, + modified_timestamp +FROM + {{ ref('silver__blitz_money_markets') }} \ No newline at end of file diff --git a/models/gold/protocol/blitz/blitz__ez_money_markets.yml b/models/gold/protocol/blitz/blitz__ez_money_markets.yml new file mode 100644 index 0000000..2d3025f --- /dev/null +++ b/models/gold/protocol/blitz/blitz__ez_money_markets.yml @@ -0,0 +1,26 @@ +version: 2 +models: + - name: blitz__ez_money_markets + description: '{{ doc("blitz_money_markets") }}' + + columns: + - name: HOUR + description: '{{ doc("blitz_hour") }}' + - name: TICKER_ID + description: '{{ doc("blitz_ticker_id") }}' + - name: SYMBOL + description: '{{ doc("blitz_symbol") }}' + - name: PRODUCT_ID + description: '{{ doc("blitz_product_id") }}' + - name: DEPOSIT_APR + description: '{{ doc("blitz_deposit_apr") }}' + - name: BORROW_APR + description: '{{ doc("blitz_borrow_apr") }}' + - name: TVL + description: '{{ doc("blitz_tvl") }}' + - name: INSERTED_TIMESTAMP + description: '{{ doc("inserted_timestamp") }}' + - name: MODIFIED_TIMESTAMP + description: '{{ doc("modified_timestamp") }}' + - name: VERTEX_MONEY_MARKETS_ID + description: '{{ doc("pk") }}' \ No newline at end of file diff --git a/models/silver/core/silver__fact_traces2.sql b/models/silver/core/silver__fact_traces2.sql index 59abaa2..6911d1e 100644 --- a/models/silver/core/silver__fact_traces2.sql +++ b/models/silver/core/silver__fact_traces2.sql @@ -8,7 +8,479 @@ tags = ['non_realtime','core'], full_refresh = false ) }} -{{ fsc_evm.gold_traces_v1( - full_reload_start_block = 3000000, - full_reload_blocks = 1000000 -) }} + +WITH silver_traces AS ( + + SELECT + block_number, + tx_position, + trace_address, + parent_trace_address, + trace_address_array, + trace_json, + traces_id, + 'regular' AS source + FROM + {{ ref('silver__traces2') }} + WHERE + 1 = 1 + +{% if is_incremental() and not full_reload_mode %} +AND modified_timestamp > ( + SELECT + MAX(modified_timestamp) + FROM + {{ this }} +) {% elif is_incremental() and full_reload_mode %} +AND block_number BETWEEN ( + SELECT + MAX( + block_number + ) + FROM + {{ this }} +) +AND ( + SELECT + MAX( + block_number + ) + 1000000 + FROM + {{ this }} +) +{% else %} + AND block_number <= 3000000 +{% endif %} +), +sub_traces AS ( + SELECT + block_number, + tx_position, + parent_trace_address, + COUNT(*) AS sub_traces + FROM + silver_traces + GROUP BY + block_number, + tx_position, + parent_trace_address +), +trace_index_array AS ( + SELECT + block_number, + tx_position, + trace_address, + ARRAY_AGG(flat_value) AS number_array + FROM + ( + SELECT + block_number, + tx_position, + trace_address, + IFF( + VALUE :: STRING = 'ORIGIN', + -1, + VALUE :: INT + ) AS flat_value + FROM + silver_traces, + LATERAL FLATTEN ( + input => trace_address_array + ) + ) + GROUP BY + block_number, + tx_position, + trace_address +), +trace_index_sub_traces AS ( + SELECT + b.block_number, + b.tx_position, + b.trace_address, + IFNULL( + sub_traces, + 0 + ) AS sub_traces, + number_array, + ROW_NUMBER() over ( + PARTITION BY b.block_number, + b.tx_position + ORDER BY + number_array ASC + ) - 1 AS trace_index, + b.trace_json, + b.traces_id, + b.source + FROM + silver_traces b + LEFT JOIN sub_traces s + ON b.block_number = s.block_number + AND b.tx_position = s.tx_position + AND b.trace_address = s.parent_trace_address + JOIN trace_index_array n + ON b.block_number = n.block_number + AND b.tx_position = n.tx_position + AND b.trace_address = n.trace_address +), +errored_traces AS ( + SELECT + block_number, + tx_position, + trace_address, + trace_json + FROM + trace_index_sub_traces + WHERE + trace_json :error :: STRING IS NOT NULL +), +error_logic AS ( + SELECT + b0.block_number, + b0.tx_position, + b0.trace_address, + b0.trace_json :error :: STRING AS error, + b1.trace_json :error :: STRING AS any_error, + b2.trace_json :error :: STRING AS origin_error + FROM + trace_index_sub_traces b0 + LEFT JOIN errored_traces b1 + ON b0.block_number = b1.block_number + AND b0.tx_position = b1.tx_position + AND b0.trace_address RLIKE CONCAT( + '^', + b1.trace_address, + '(_[0-9]+)*$' + ) + LEFT JOIN errored_traces b2 + ON b0.block_number = b2.block_number + AND b0.tx_position = b2.tx_position + AND b2.trace_address = 'ORIGIN' +), +aggregated_errors AS ( + SELECT + block_number, + tx_position, + trace_address, + error, + IFF(MAX(any_error) IS NULL + AND error IS NULL + AND origin_error IS NULL, TRUE, FALSE) AS trace_succeeded + FROM + error_logic + GROUP BY + block_number, + tx_position, + trace_address, + error, + origin_error), + json_traces AS ( + SELECT + block_number, + tx_position, + trace_address, + sub_traces, + number_array, + trace_index, + trace_json AS DATA, + trace_succeeded, + trace_json :error :: STRING AS error_reason, + trace_json :revertReason :: STRING AS revert_reason, + trace_json :from :: STRING AS from_address, + trace_json :to :: STRING AS to_address, + IFNULL( + trace_json :value :: STRING, + '0x0' + ) AS value_hex, + IFNULL( + utils.udf_hex_to_int( + trace_json :value :: STRING + ), + '0' + ) AS value_precise_raw, + utils.udf_decimal_adjust( + value_precise_raw, + 18 + ) AS value_precise, + value_precise :: FLOAT AS VALUE, + utils.udf_hex_to_int( + trace_json :gas :: STRING + ) :: INT AS gas, + utils.udf_hex_to_int( + trace_json :gasUsed :: STRING + ) :: INT AS gas_used, + trace_json :input :: STRING AS input, + trace_json :output :: STRING AS output, + trace_json :type :: STRING AS TYPE, + concat_ws( + '_', + TYPE, + trace_address + ) AS identifier, + IFF( + trace_succeeded, + 'SUCCESS', + 'FAIL' + ) AS trace_status, + traces_id + FROM + trace_index_sub_traces + JOIN aggregated_errors USING ( + block_number, + tx_position, + trace_address + ) + ), + incremental_traces AS ( + SELECT + f.block_number, + t.tx_hash, + t.block_timestamp, + t.origin_function_signature, + t.from_address AS origin_from_address, + t.to_address AS origin_to_address, + t.tx_status, + f.tx_position, + f.trace_index, + f.from_address AS from_address, + f.to_address AS to_address, + f.value_hex, + f.value_precise_raw, + f.value_precise, + f.value, + f.gas, + f.gas_used, + f.input, + f.output, + f.type, + f.identifier, + f.sub_traces, + f.error_reason, + f.revert_reason, + f.trace_status, + f.data, + f.traces_id, + f.trace_succeeded, + f.trace_address, + IFF( + t.tx_status = 'SUCCESS', + TRUE, + FALSE + ) AS tx_succeeded + FROM + json_traces f + LEFT OUTER JOIN {{ ref('silver__transactions') }} + t + ON f.tx_position = t.position + AND f.block_number = t.block_number + +{% if is_incremental() and not full_reload_mode %} +AND t.modified_timestamp >= ( + SELECT + DATEADD('hour', -24, MAX(modified_timestamp)) + FROM + {{ this }}) + {% endif %} +) + +{% if is_incremental() %}, +overflow_blocks AS ( + SELECT + DISTINCT block_number + FROM + silver_traces + WHERE + source = 'overflow' +), +heal_missing_data AS ( + SELECT + t.block_number, + txs.tx_hash, + txs.block_timestamp, + txs.origin_function_signature, + txs.from_address AS origin_from_address, + txs.to_address AS origin_to_address, + txs.tx_status, + t.tx_position, + t.trace_index, + t.from_address, + t.to_address, + t.value_hex, + t.value_precise_raw, + t.value_precise, + t.value, + t.gas, + t.gas_used, + t.input, + t.output, + t.type, + t.identifier, + t.sub_traces, + t.error_reason, + t.revert_reason, + t.trace_status, + t.data, + t.fact_traces_id AS traces_id, + t.trace_succeeded, + t.trace_address, + IFF( + txs.tx_status = 'SUCCESS', + TRUE, + FALSE + ) AS tx_succeeded + FROM + {{ this }} + t + JOIN {{ ref('silver__transactions') }} + txs + ON t.tx_position = txs.position + AND t.block_number = txs.block_number + WHERE + t.tx_hash IS NULL + OR t.block_timestamp IS NULL + OR t.tx_status IS NULL +) +{% endif %}, +all_traces AS ( + SELECT + block_number, + tx_hash, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_status, + tx_position, + trace_index, + from_address, + to_address, + value_hex, + value_precise_raw, + value_precise, + VALUE, + gas, + gas_used, + input, + output, + TYPE, + identifier, + sub_traces, + error_reason, + revert_reason, + trace_status, + DATA, + trace_succeeded, + trace_address, + tx_succeeded + FROM + incremental_traces + +{% if is_incremental() %} +UNION ALL +SELECT + block_number, + tx_hash, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_status, + tx_position, + trace_index, + from_address, + to_address, + value_hex, + value_precise_raw, + value_precise, + VALUE, + gas, + gas_used, + input, + output, + TYPE, + identifier, + sub_traces, + error_reason, + revert_reason, + trace_status, + DATA, + trace_succeeded, + trace_address, + tx_succeeded +FROM + heal_missing_data +UNION ALL +SELECT + block_number, + tx_hash, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_status, + tx_position, + trace_index, + from_address, + to_address, + value_hex, + value_precise_raw, + value_precise, + VALUE, + gas, + gas_used, + input, + output, + TYPE, + identifier, + sub_traces, + error_reason, + revert_reason, + trace_status, + DATA, + trace_succeeded, + trace_address, + tx_succeeded +FROM + {{ this }} + JOIN overflow_blocks USING (block_number) +{% endif %} +) +SELECT + block_number, + block_timestamp, + tx_hash, + tx_position, + trace_index, + from_address, + to_address, + input, + output, + TYPE, + trace_address, + sub_traces, + VALUE, + value_precise_raw, + value_precise, + value_hex, + gas, + gas_used, + origin_from_address, + origin_to_address, + origin_function_signature, + trace_succeeded, + error_reason, + revert_reason, + tx_succeeded, + identifier, + DATA, + tx_status, + trace_status, + {{ dbt_utils.generate_surrogate_key( + ['tx_hash', 'trace_index'] + ) }} AS fact_traces_id, + SYSDATE() AS inserted_timestamp, + SYSDATE() AS modified_timestamp +FROM + all_traces qualify(ROW_NUMBER() over(PARTITION BY block_number, tx_position, trace_index +ORDER BY + modified_timestamp DESC, block_timestamp DESC nulls last)) = 1 diff --git a/models/silver/core/traces2_fix/silver__fact_traces2_fix.sql b/models/silver/core/traces2_fix/silver__fact_traces2_fix.sql new file mode 100644 index 0000000..98397ee --- /dev/null +++ b/models/silver/core/traces2_fix/silver__fact_traces2_fix.sql @@ -0,0 +1,164 @@ +{{ config ( + materialized = "incremental", + incremental_strategy = 'delete+insert', + unique_key = ["block_number", "tx_position", "trace_address"], + tags = ['traces_fix'] +) }} + +{% set batch_query %} + +SELECT + MAX(next_batch_id) AS next_batch_id +FROM + ( + SELECT + 1 AS next_batch_id + +{% if is_incremental() %} +UNION ALL +SELECT + COALESCE(MAX(batch_id), 0) + 1 AS next_batch_id +FROM + {{ this }} +{% endif %}) {% endset %} +{% if execute %} + {% set result = run_query(batch_query) %} + {{ log( + "Debug - Batch Query result: " ~ result, + info = True + ) }} + + {% set batch_id = result.columns [0] [0] %} + {% if batch_id > 28 %} + {{ exceptions.raise_compiler_error("Processing complete - reached max batch_id of 28") }} + {% endif %} + + {% set block_size = 500000 %} + {% set block_start = 1 + ( + batch_id - 1 + ) * block_size %} + {% set block_end = batch_id * block_size %} + {{ log( + "Processing batch_id: " ~ batch_id ~ ", blocks: " ~ block_start ~ " to " ~ block_end, + info = True + ) }} +{% endif %} + +WITH silver_traces AS ( + SELECT + block_number, + tx_position, + trace_address, + parent_trace_address, + trace_json + FROM + {{ ref('silver__traces2') }} + WHERE + block_number BETWEEN {{ block_start }} + AND {{ block_end }} +), +errored_traces AS ( + SELECT + block_number, + tx_position, + trace_address, + trace_json + FROM + silver_traces + WHERE + trace_json :error :: STRING IS NOT NULL +), +error_logic AS ( + SELECT + b0.block_number, + b0.tx_position, + b0.trace_address, + b0.trace_json :error :: STRING AS error, + b1.trace_json :error :: STRING AS any_error, + b2.trace_json :error :: STRING AS origin_error + FROM + silver_traces b0 + LEFT JOIN errored_traces b1 + ON b0.block_number = b1.block_number + AND b0.tx_position = b1.tx_position + AND b0.trace_address RLIKE CONCAT( + '^', + b1.trace_address, + '(_[0-9]+)*$' + ) + LEFT JOIN errored_traces b2 + ON b0.block_number = b2.block_number + AND b0.tx_position = b2.tx_position + AND b2.trace_address = 'ORIGIN' +), +aggregated_errors AS ( + SELECT + block_number, + tx_position, + trace_address, + error, + IFF(MAX(any_error) IS NULL + AND error IS NULL + AND origin_error IS NULL, TRUE, FALSE) AS trace_succeeded + FROM + error_logic + GROUP BY + block_number, + tx_position, + trace_address, + error, + origin_error), + prod AS ( + SELECT + block_number, + tx_position, + tx_hash, + trace_address, + trace_succeeded AS prod_trace_succeeded + FROM + {{ ref('silver__fact_traces2') }} + WHERE + block_number BETWEEN {{ block_start }} + AND {{ block_end }} + ), + final_errors AS ( + SELECT + block_number, + tx_position, + trace_address, + error, + trace_succeeded, + prod_trace_succeeded + FROM + aggregated_errors + INNER JOIN prod USING ( + block_number, + tx_position, + trace_address + ) + WHERE + prod_trace_succeeded != trace_succeeded + UNION ALL + SELECT + NULL AS block_number, + NULL AS tx_position, + NULL AS trace_address, + NULL AS error, + NULL AS trace_succeeded, + NULL AS prod_trace_succeeded + ), + batch AS ( + SELECT + CAST({{ batch_id }} AS NUMBER(10, 0)) AS batch_id + ) + SELECT + batch_id, + block_number, + tx_position, + trace_address, + error, + trace_succeeded, + prod_trace_succeeded + FROM + batch + CROSS JOIN final_errors diff --git a/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.sql b/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.sql new file mode 100644 index 0000000..a950e6c --- /dev/null +++ b/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.sql @@ -0,0 +1,108 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH base_evt AS ( + + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + contract_address, + 'across-v3' AS NAME, + topics, + DATA, + event_index, + event_name, + utils.udf_hex_to_int( + topics [1] :: STRING + ) AS destinationChainId, + utils.udf_hex_to_int( + topics [2] :: STRING + ) AS depositId, + CONCAT('0x', SUBSTR(topics [3] :: STRING, 27, 40)) AS depositor, + regexp_substr_all(SUBSTR(DATA, 3, len(DATA)), '.{64}') AS segmented_data, + CONCAT('0x', SUBSTR(segmented_data [0] :: STRING, 25, 40)) AS inputToken, + CONCAT('0x', SUBSTR(segmented_data [1] :: STRING, 25, 40)) AS outputToken, + TRY_TO_NUMBER(utils.udf_hex_to_int( + segmented_data [2] :: STRING + )) AS inputAmount, + TRY_TO_NUMBER(utils.udf_hex_to_int( + segmented_data [3] :: STRING + )) AS outputAmount, + utils.udf_hex_to_int( + segmented_data [4] :: STRING + ) AS quotedTimestamp, + utils.udf_hex_to_int( + segmented_data [5] :: STRING + ) AS fillDeadline, + utils.udf_hex_to_int( + segmented_data [6] :: STRING + ) AS exclusivityDeadline, + CONCAT('0x', SUBSTR(segmented_data [7] :: STRING, 25, 40)) AS recipient, + CONCAT('0x', SUBSTR(segmented_data [8] :: STRING, 25, 40)) AS exclusiveRelayer, + segmented_data [9] :: STRING AS message, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__ez_decoded_event_logs') }} + WHERE + topics [0] :: STRING = '0xa123dc29aebf7d0c3322c8eeb5b999e859f39937950ed31056532713d0de396f' + AND contract_address = '0x2d509190ed0172ba588407d4c2df918f955cc6e1' + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +) +SELECT + block_number, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_hash, + event_index, + topics, + event_name, + tx_succeeded, + contract_address AS bridge_address, + NAME AS platform, + depositor AS sender, + recipient AS receiver, + recipient AS destination_chain_receiver, + destinationChainId AS destination_chain_id, + inputAmount AS amount, + inputToken AS token_address, + depositId AS deposit_id, + message, + exclusiveRelayer AS exclusive_relayer, + exclusivityDeadline AS exclusivity_deadline, + fillDeadline AS fill_deadline, + outputAmount AS output_amount, + outputToken AS output_token, + _log_id, + modified_timestamp +FROM + base_evt diff --git a/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.yml b/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.yml new file mode 100644 index 0000000..124becb --- /dev/null +++ b/models/silver/defi/bridge/across/silver_bridge__across_v3fundsdeposited.yml @@ -0,0 +1,72 @@ +version: 2 +models: + - name: silver_bridge__across_v3fundsdeposited + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.sql b/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.sql new file mode 100644 index 0000000..f1aac83 --- /dev/null +++ b/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.sql @@ -0,0 +1,239 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH base_evt AS ( + + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + contract_address, + 'axelar' AS NAME, + event_index, + topics [0] :: STRING AS topic_0, + event_name, + decoded_log, + TRY_TO_NUMBER( + decoded_log :"amount" :: STRING + ) AS amount, + decoded_log :"destinationChain" :: STRING AS destinationChain, + LOWER( + decoded_log :"destinationContractAddress" :: STRING + ) AS destinationContractAddress, + decoded_log :"payload" :: STRING AS payload, + origin_from_address AS recipient, + decoded_log :"payloadHash" :: STRING AS payloadHash, + decoded_log :"sender" :: STRING AS sender, + decoded_log :"symbol" :: STRING AS symbol, + decoded_log, + event_removed, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__ez_decoded_event_logs') }} + WHERE + topics [0] :: STRING = '0x7e50569d26be643bda7757722291ec66b1be66d8283474ae3fab5a98f878a7a2' + AND contract_address = LOWER('0xe432150cce91c13a887f7D836923d5597adD8E31') + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +native_gas_paid AS ( + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + contract_address, + 'axelar' AS NAME, + event_index, + topics [0] :: STRING AS topic_0, + event_name, + decoded_log, + TRY_TO_NUMBER( + decoded_log :"amount" :: STRING + ) AS amount, + decoded_log :"destinationChain" :: STRING AS destinationChain, + LOWER( + decoded_log :"destinationAddress" :: STRING + ) AS destinationAddress, + TRY_TO_NUMBER( + decoded_log :"gasFeeAmount" :: STRING + ) AS gasFeeAmount, + decoded_log :"payloadHash" :: STRING AS payloadHash, + decoded_log :"refundAddress" :: STRING AS refundAddress, + decoded_log :"sourceAddress" :: STRING AS sourceAddress, + decoded_log :"symbol" :: STRING AS symbol, + decoded_log, + event_removed, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__ez_decoded_event_logs') }} + WHERE + topics [0] :: STRING = '0x999d431b58761213cf53af96262b67a069cbd963499fd8effd1e21556217b841' + AND contract_address = '0x2d5d7d31f671f86c782533cc367f14109a082712' + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +transfers AS ( + SELECT + block_number, + tx_hash, + event_index, + contract_address AS token_address, + _log_id, + _inserted_timestamp + FROM + {{ ref('silver__transfers') }} + WHERE + from_address = '0x492751ec3c57141deb205ec2da8bfcb410738630' + AND to_address IN ( + LOWER('0xe432150cce91c13a887f7D836923d5597adD8E31'), + '0x0000000000000000000000000000000000000000' + ) + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +FINAL AS ( + SELECT + b.block_number, + b.block_timestamp, + b.origin_function_signature, + b.origin_from_address, + b.origin_to_address, + b.tx_hash, + b.event_index, + b.topic_0, + b.event_name, + b.event_removed, + b.tx_succeeded, + b.contract_address AS bridge_address, + b.name AS platform, + b.origin_from_address AS sender, + CASE + WHEN b.recipient = '0x0000000000000000000000000000000000000000' THEN refundAddress + ELSE b.recipient + END AS receiver, + CASE + WHEN LOWER( + b.destinationChain + ) = 'avalanche' THEN 'avalanche c-chain' + WHEN LOWER( + b.destinationChain + ) = 'binance' THEN 'bnb smart chain mainnet' + WHEN LOWER( + b.destinationChain + ) = 'celo' THEN 'celo mainnet' + WHEN LOWER( + b.destinationChain + ) = 'ethereum' THEN 'ethereum mainnet' + WHEN LOWER( + b.destinationChain + ) = 'fantom' THEN 'fantom opera' + WHEN LOWER( + b.destinationChain + ) = 'polygon' THEN 'polygon mainnet' + ELSE LOWER( + b.destinationChain + ) + END AS destination_chain, + b.destinationContractAddress AS destination_contract_address, + CASE + WHEN destination_chain IN ( + 'arbitrum', + 'avalanche c-chain', + 'base', + 'bnb smart chain mainnet', + 'celo mainnet', + 'centrifuge', + 'ethereum mainnet', + 'fantom opera', + 'filecoin', + 'fraxtal', + 'immutable', + 'kava', + 'linea', + 'mantle', + 'moonbeam', + 'neutron', + 'optimism', + 'osmosis', + 'polygon mainnet', + 'scroll' + ) THEN receiver + ELSE destination_contract_address + END AS destination_chain_receiver, + b.amount, + b.payload, + b.payloadHash AS payload_hash, + b.symbol AS token_symbol, + t.token_address, + b._log_id, + b.modified_timestamp + FROM + base_evt b + INNER JOIN transfers t + ON b.block_number = t.block_number + AND b.tx_hash = t.tx_hash + LEFT JOIN native_gas_paid n + ON n.block_number = b.block_number + AND n.tx_hash = b.tx_hash +) +SELECT + * +FROM + FINAL qualify (ROW_NUMBER() over (PARTITION BY _log_id +ORDER BY + modified_timestamp DESC)) = 1 diff --git a/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.yml b/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.yml new file mode 100644 index 0000000..805fa58 --- /dev/null +++ b/models/silver/defi/bridge/axelar/silver_bridge__axelar_contractcallwithtoken.yml @@ -0,0 +1,72 @@ +version: 2 +models: + - name: silver_bridge__axelar_contractcallwithtoken + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.sql b/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.sql new file mode 100644 index 0000000..b54fef4 --- /dev/null +++ b/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.sql @@ -0,0 +1,207 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH dispatch AS ( + + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + event_index, + contract_address, + event_removed, + CONCAT('0x', SUBSTR(topics [1] :: STRING, 27, 40)) AS src_bridge_token, + -- src bridge token address, not user address + TRY_TO_NUMBER(utils.udf_hex_to_int(topics [2] :: STRING)) AS destination, + CONCAT('0x', SUBSTR(topics [3] :: STRING, 27, 40)) AS dst_bridge_token, + -- dst bridge token address, not recipient address + DATA, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + topics [0] :: STRING = '0x769f711d20c679153d382254f59892613b58a97cc876b249134ac25c80f9c814' + AND contract_address = LOWER('0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7') + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +dispatch_id AS ( + SELECT + block_number, + block_timestamp, + tx_hash, + event_index, + topics [1] :: STRING AS messageId, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + topics [0] :: STRING = '0x788dbc1b7152732178210e7f4d9d010ef016f9eafbe66786bd7169f56e0c353a' + AND contract_address = LOWER('0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7') + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +gas_payment AS ( + SELECT + block_number, + block_timestamp, + tx_hash, + event_index, + topics [1] :: STRING AS messageId, + TRY_TO_NUMBER(utils.udf_hex_to_int(topics [2] :: STRING)) AS destinationDomain, + regexp_substr_all(SUBSTR(DATA, 3, len(DATA)), '.{64}') AS segmented_data, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [0] :: STRING)) AS gasAmount, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [1] :: STRING)) AS payment, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + topics [0] = '0x65695c3748edae85a24cc2c60b299b31f463050bc259150d2e5802ec8d11720a' + AND contract_address = LOWER('0xB3fCcD379ad66CED0c91028520C64226611A48c9') + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +sent_transfer_remote AS ( + SELECT + block_number, + block_timestamp, + tx_hash, + event_index, + CONCAT('0x', SUBSTR(topics [1] :: STRING, 27, 40)) AS destination, + CONCAT('0x', SUBSTR(topics [2] :: STRING, 27, 40)) AS recipient, + -- actual recipient + TRY_TO_NUMBER(utils.udf_hex_to_int(DATA :: STRING)) AS amount, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + topics [0] :: STRING = '0xd229aacb94204188fe8042965fa6b269c62dc5818b21238779ab64bdd17efeec' + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +token_transfer AS ( + -- this matches tx_hash with each token's burn tx. this works since each contract only handles 1 token, but can be replaced by a 1 contract read of contracts in the hyperlane_asset (hyperlane_asset contracts have a wrappedtoken function) + SELECT + tx_hash, + contract_address AS token_address + FROM + {{ ref('silver__transfers') }} + WHERE + tx_hash IN ( + SELECT + tx_hash + FROM + sent_transfer_remote + ) + AND to_address = '0x0000000000000000000000000000000000000000' +) +SELECT + block_number, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_hash, + event_index, + contract_address AS bridge_address, + 'Dispatch' AS event_name, + event_removed, + tx_succeeded, + recipient AS destination_chain_receiver, + destination AS destination_chain_id, + messageId :: STRING AS message_id, + gasAmount AS gas_amount, + payment, + origin_from_address AS sender, + recipient AS receiver, + amount, + token_address, + 'hyperlane' AS platform, + _log_id, + modified_timestamp +FROM + dispatch + INNER JOIN dispatch_id USING(tx_hash) + INNER JOIN gas_payment USING(tx_hash) + INNER JOIN token_transfer USING(tx_hash) + INNER JOIN sent_transfer_remote USING(tx_hash) diff --git a/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.yml b/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.yml new file mode 100644 index 0000000..783e374 --- /dev/null +++ b/models/silver/defi/bridge/hyperlane/silver_bridge__hyperlane_bridge.yml @@ -0,0 +1,72 @@ +version: 2 +models: + - name: silver_bridge__hyperlane_bridge + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.sql b/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.sql new file mode 100644 index 0000000..250e766 --- /dev/null +++ b/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.sql @@ -0,0 +1,174 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH oft_asset_contract_creation AS ( + + SELECT + block_number, + block_timestamp, + tx_hash, + from_address AS oft_address, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CASE + WHEN trace_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS trace_succeeded, + modified_timestamp + FROM + {{ ref('core__fact_traces') }} + WHERE + TYPE = 'CALL' + AND LEFT( + input, + 10 + ) = '0xca5eb5e1' + AND to_address = '0x1a44076050125825900e736c501f859c50fe728c' -- layerzero v2 + AND tx_succeeded + AND trace_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} + +qualify ROW_NUMBER() over ( + PARTITION BY oft_address + ORDER BY + block_timestamp DESC +) = 1 +), +oft_asset_base_token AS ( + SELECT + block_number, + block_timestamp, + tx_hash, + from_address AS wrap_address, + to_address AS underlying_address, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CASE + WHEN trace_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS trace_succeeded, + modified_timestamp + FROM + {{ ref('core__fact_traces') }} + WHERE + tx_hash IN ( + SELECT + tx_hash + FROM + oft_asset_contract_creation + ) + AND TYPE = 'STATICCALL' + AND input = '0x313ce567' qualify ROW_NUMBER() over ( + PARTITION BY tx_hash + ORDER BY + trace_index ASC + ) = 1 +), +oft_asset AS ( + SELECT + oft_address, + underlying_address + FROM + oft_asset_contract_creation t1 + LEFT JOIN oft_asset_base_token t2 + ON t1.tx_hash = t2.tx_hash + AND oft_address = wrap_address +), +oft_sent AS ( + -- bridging transactions + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + contract_address, + event_index, + 'OFTSent' AS event_name, + 'layerzero-v2' AS platform, + oft_address, + underlying_address, + SUBSTR( + topics [1] :: STRING, + 2, + 64 + ) AS guid, + CONCAT('0x', SUBSTR(topics [2] :: STRING, 27, 40)) AS from_address, + regexp_substr_all(SUBSTR(DATA, 3, len(DATA)), '.{64}') AS segmented_data, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [0] :: STRING)) AS dstEid, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [1] :: STRING)) AS amountSentLD, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [2] :: STRING)) AS amountReceivedLD, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + e + INNER JOIN oft_asset + ON oft_address = contract_address + WHERE + topics [0] = '0x85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a' + +{% if is_incremental() %} +AND e.modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} +) +AND e.modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +) +SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + '0x1a44076050125825900e736c501f859c50fe728c' AS bridge_address, + event_index, + event_name, + platform, + from_address AS sender, + from_address AS receiver, + from_address AS destination_chain_receiver, + amountSentLD AS amount, + b.dstEid AS destination_chain_id, + LOWER( + s.chain :: STRING + ) AS destination_chain, + COALESCE( + underlying_address, + oft_address + ) AS token_address, + oft_address, + _log_id, + modified_timestamp +FROM + oft_sent b + INNER JOIN {{ ref('silver_bridge__layerzero_bridge_seed') }} + s + ON b.dstEid :: STRING = s.eid :: STRING diff --git a/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.yml b/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.yml new file mode 100644 index 0000000..239b949 --- /dev/null +++ b/models/silver/defi/bridge/layerzero/silver_bridge__layerzero_bridge_v2.yml @@ -0,0 +1,69 @@ +version: 2 +models: + - name: silver_bridge__layerzero_bridge_v2 + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.sql b/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.sql new file mode 100644 index 0000000..6029954 --- /dev/null +++ b/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.sql @@ -0,0 +1,86 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH bridge_native AS ( + -- for direct native eth transfers + + SELECT + et.block_number, + et.block_timestamp, + et.tx_hash, + tx.from_address AS origin_from_address, + tx.to_address AS origin_to_address, + tx.origin_function_signature, + et.to_address, + et.from_address, + origin_from_address AS depositor, + RIGHT( + amount_precise_raw, + 4 + ) AS destinationChainId, + amount_precise_raw :: INTEGER AS amount_unadj, + origin_from_address AS recipient, + et.to_address AS bridge_address, + trace_index, + native_transfers_id, + et.modified_timestamp + FROM + {{ ref('silver__native_transfers') }} + et + INNER JOIN {{ ref('silver__transactions') }} + tx + ON et.block_number = tx.block_number + AND et.tx_hash = tx.tx_hash + WHERE + et.to_address IN ( + '0xe4edb277e41dc89ab076a1f049f4a3efa700bce8', + '0xee73323912a4e3772b74ed0ca1595a152b0ef282', + '0x80c67432656d59144ceff962e8faf8926599bcf8', + '0x3bdb03ad7363152dfbc185ee23ebc93f0cf93fd1' + ) + +{% if is_incremental() %} +AND et.modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND et.modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +) +SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + trace_index AS event_index, + NULL AS event_name, + to_address, + from_address, + depositor AS sender, + b.destinationChainId AS orbiter_chain_id, + s.chainid AS destination_chain_id, + s.name AS destination_chain, + amount_unadj, + recipient AS receiver, + recipient AS destination_chain_receiver, + bridge_address, + TRUE AS tx_succeeded, + 'orbiter' AS platform, + '0x4300000000000000000000000000000000000004' AS token_address, + --weth contract address + native_transfers_id AS _id, + modified_timestamp +FROM + bridge_native b + LEFT JOIN {{ ref('silver_bridge__orbiter_bridge_seed') }} + s + ON b.destinationChainId :: STRING = s.identificationcode :: STRING diff --git a/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.yml b/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.yml new file mode 100644 index 0000000..38d287a --- /dev/null +++ b/models/silver/defi/bridge/orbiter/silver_bridge__orbiter_bridgerequest.yml @@ -0,0 +1,66 @@ +version: 2 +models: + - name: silver_bridge__orbiter_bridgerequest + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT_UNADJ + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.sql b/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.sql new file mode 100644 index 0000000..ac205f1 --- /dev/null +++ b/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.sql @@ -0,0 +1,593 @@ +-- depends_on: {{ ref('silver__complete_token_prices') }} +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = ['block_number','platform','version'], + cluster_by = ['block_timestamp::DATE','platform'], + post_hook = "ALTER TABLE {{ this }} ADD SEARCH OPTIMIZATION ON EQUALITY(tx_hash, origin_from_address, origin_to_address, origin_function_signature, bridge_address, sender, receiver, destination_chain_receiver, destination_chain_id, destination_chain, token_address, token_symbol), SUBSTRING(origin_function_signature, bridge_address, sender, receiver, destination_chain_receiver, destination_chain, token_address, token_symbol)", + tags = ['curated','reorg','heal'] +) }} + +WITH across_v3 AS ( + + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v3' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + NULL AS destination_chain, + token_address, + NULL AS token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__across_v3fundsdeposited') }} + +{% if is_incremental() and 'across_v3' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +axelar AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v1' AS version, + sender, + receiver, + destination_chain_receiver, + NULL AS destination_chain_id, + destination_chain, + token_address, + token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__axelar_contractcallwithtoken') }} + +{% if is_incremental() and 'axelar' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +hyperlane AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v1' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + NULL AS destination_chain, + token_address, + NULL AS token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__hyperlane_bridge') }} + +{% if is_incremental() and 'hyperlane' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +layerzero_v2 AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v2' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + destination_chain, + token_address, + NULL AS token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__layerzero_bridge_v2') }} + +{% if is_incremental() and 'layerzero_v2' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +orbiter AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v1' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + destination_chain, + token_address, + NULL AS token_symbol, + amount_unadj, + _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__orbiter_bridgerequest') }} + +{% if is_incremental() and 'orbiter' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +symbiosis AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v1' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + NULL AS destination_chain, + token_address, + NULL AS token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__symbiosis_synthesizerequest') }} + +{% if is_incremental() and 'symbiosis' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +synapse AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + 'v1' AS version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id :: STRING AS destination_chain_id, + NULL AS destination_chain, + token_address, + NULL AS token_symbol, + amount AS amount_unadj, + _log_id AS _id, + modified_timestamp AS _inserted_timestamp + FROM + {{ ref('silver_bridge__synapse_tokenredeem') }} + +{% if is_incremental() and 'synapse' not in var('HEAL_MODELS') %} +WHERE + _inserted_timestamp >= ( + SELECT + MAX(_inserted_timestamp) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) +{% endif %} +), +all_protocols AS ( + SELECT + * + FROM + across_v3 + UNION ALL + SELECT + * + FROM + axelar + UNION ALL + SELECT + * + FROM + hyperlane + UNION ALL + SELECT + * + FROM + layerzero_v2 + UNION ALL + SELECT + * + FROM + orbiter + UNION ALL + SELECT + * + FROM + symbiosis + UNION ALL + SELECT + * + FROM + synapse +), +complete_bridge_activity AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + version, + sender, + receiver, + destination_chain_receiver, + CASE + WHEN platform IN ( + 'orbiter', + 'layerzero-v2' + ) THEN destination_chain_id :: STRING + WHEN d.chain_id IS NULL THEN destination_chain_id :: STRING + ELSE d.chain_id :: STRING + END AS destination_chain_id, + CASE + WHEN platform IN ( + 'orbiter', + 'layerzero-v2' + ) THEN LOWER(destination_chain) + WHEN d.chain IS NULL THEN LOWER(destination_chain) + ELSE LOWER( + d.chain + ) + END AS destination_chain, + b.token_address, + CASE + WHEN platform = 'axelar' THEN COALESCE( + C.token_symbol, + b.token_symbol + ) + ELSE C.token_symbol + END AS token_symbol, + C.token_decimals AS token_decimals, + amount_unadj, + CASE + WHEN C.token_decimals IS NOT NULL THEN (amount_unadj / pow(10, C.token_decimals)) + ELSE amount_unadj + END AS amount, + CASE + WHEN C.token_decimals IS NOT NULL THEN ROUND( + amount * p.price, + 2 + ) + ELSE NULL + END AS amount_usd, + _id, + b._inserted_timestamp + FROM + all_protocols b + LEFT JOIN {{ ref('silver__contracts') }} C + ON b.token_address = C.contract_address + LEFT JOIN {{ ref('price__ez_prices_hourly') }} + p + ON b.token_address = p.token_address + AND DATE_TRUNC( + 'hour', + block_timestamp + ) = p.hour + LEFT JOIN {{ source( + 'external_gold_defillama', + 'dim_chains' + ) }} + d + ON d.chain_id :: STRING = b.destination_chain_id :: STRING + OR LOWER( + d.chain + ) = LOWER( + b.destination_chain + ) +), + +{% if is_incremental() and var( + 'HEAL_MODEL' +) %} +heal_model AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id, + destination_chain, + t0.token_address, + C.token_symbol AS token_symbol, + C.token_decimals AS token_decimals, + amount_unadj, + CASE + WHEN C.token_decimals IS NOT NULL THEN (amount_unadj / pow(10, C.token_decimals)) + ELSE amount_unadj + END AS amount_heal, + CASE + WHEN C.token_decimals IS NOT NULL THEN amount_heal * p.price + ELSE NULL + END AS amount_usd_heal, + _id, + t0._inserted_timestamp + FROM + {{ this }} + t0 + LEFT JOIN {{ ref('silver__contracts') }} C + ON t0.token_address = C.contract_address + LEFT JOIN {{ ref('price__ez_prices_hourly') }} + p + ON t0.token_address = p.token_address + AND DATE_TRUNC( + 'hour', + block_timestamp + ) = p.hour + WHERE + CONCAT( + t0.block_number, + '-', + t0.platform, + '-', + t0.version + ) IN ( + SELECT + CONCAT( + t1.block_number, + '-', + t1.platform, + '-', + t1.version + ) + FROM + {{ this }} + t1 + WHERE + t1.token_decimals IS NULL + AND t1._inserted_timestamp < ( + SELECT + MAX( + _inserted_timestamp + ) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) + AND EXISTS ( + SELECT + 1 + FROM + {{ ref('silver__contracts') }} C + WHERE + C._inserted_timestamp > DATEADD('DAY', -14, SYSDATE()) + AND C.token_decimals IS NOT NULL + AND C.contract_address = t1.token_address) + GROUP BY + 1 + ) + OR CONCAT( + t0.block_number, + '-', + t0.platform, + '-', + t0.version + ) IN ( + SELECT + CONCAT( + t2.block_number, + '-', + t2.platform, + '-', + t2.version + ) + FROM + {{ this }} + t2 + WHERE + t2.amount_usd IS NULL + AND t2._inserted_timestamp < ( + SELECT + MAX( + _inserted_timestamp + ) - INTERVAL '{{ var("LOOKBACK", "4 hours") }}' + FROM + {{ this }} + ) + AND EXISTS ( + SELECT + 1 + FROM + {{ ref('silver__complete_token_prices') }} + p + WHERE + p._inserted_timestamp > DATEADD('DAY', -14, SYSDATE()) + AND p.price IS NOT NULL + AND p.token_address = t2.token_address + AND p.hour = DATE_TRUNC( + 'hour', + t2.block_timestamp + ) + ) + GROUP BY + 1 + ) + ), + {% endif %} + + FINAL AS ( + SELECT + * + FROM + complete_bridge_activity + +{% if is_incremental() and var( + 'HEAL_MODEL' +) %} +UNION ALL +SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id, + destination_chain, + token_address, + token_symbol, + token_decimals, + amount_unadj, + amount_heal AS amount, + amount_usd_heal AS amount_usd, + _id, + _inserted_timestamp +FROM + heal_model +{% endif %} +) +SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + bridge_address, + event_name, + platform, + version, + sender, + receiver, + destination_chain_receiver, + destination_chain_id, + destination_chain, + token_address, + token_symbol, + token_decimals, + amount_unadj, + amount, + amount_usd, + _id, + _inserted_timestamp, + {{ dbt_utils.generate_surrogate_key( + ['_id'] + ) }} AS complete_bridge_activity_id, + SYSDATE() AS inserted_timestamp, + SYSDATE() AS modified_timestamp, + '{{ invocation_id }}' AS _invocation_id +FROM + FINAL +WHERE + destination_chain <> 'blast' qualify (ROW_NUMBER() over (PARTITION BY _id +ORDER BY + _inserted_timestamp DESC)) = 1 diff --git a/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.yml b/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.yml new file mode 100644 index 0000000..3bf4aac --- /dev/null +++ b/models/silver/defi/bridge/silver_bridge__complete_bridge_activity.yml @@ -0,0 +1,81 @@ +version: 2 +models: + - name: silver_bridge__complete_bridge_activity + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null: + where: PLATFORM NOT IN ('orbiter') + - name: EVENT_NAME + tests: + - not_null: + where: PLATFORM NOT IN ('orbiter') + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: PLATFORM + - not_null + - name: VERSION + - not_null + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: AMOUNT_UNADJ + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: _INSERTED_TIMESTAMP + tests: + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 diff --git a/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.sql b/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.sql new file mode 100644 index 0000000..a45c7b0 --- /dev/null +++ b/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.sql @@ -0,0 +1,90 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH base_evt AS ( + + SELECT + block_number, + block_timestamp, + tx_hash, + origin_function_signature, + origin_from_address, + origin_to_address, + contract_address, + 'symbiosis' AS NAME, + event_index, + topics [0] :: STRING AS topic_0, + regexp_substr_all(SUBSTR(DATA, 3, len(DATA)), '.{64}') AS segmented_data, + 'SynthesizeRequest' AS event_name, + TRY_TO_NUMBER( + utils.udf_hex_to_int( + segmented_data [2] :: STRING + ) + ) AS amount, + TRY_TO_NUMBER( + utils.udf_hex_to_int( + topics [2] :: STRING + ) + ) AS chainID, + CONCAT('0x', SUBSTR(topics [1] :: STRING, 27, 40)) AS from_address, + segmented_data [0] :: STRING AS id, + CONCAT('0x', SUBSTR(topics [3] :: STRING, 27, 40)) AS revertableAddress, + CONCAT('0x', SUBSTR(segmented_data [1] :: STRING, 25, 40)) AS to_address, + CONCAT('0x', SUBSTR(segmented_data [3] :: STRING, 25, 40)) AS token, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + topics [0] :: STRING = '0x31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab' + AND contract_address = '0x5aa5f7f84ed0e5db0a4a85c3947ea16b53352fd4' + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +) +SELECT + block_number, + block_timestamp, + origin_function_signature, + origin_from_address, + origin_to_address, + tx_hash, + event_index, + topic_0, + event_name, + tx_succeeded, + contract_address AS bridge_address, + NAME AS platform, + from_address AS sender, + to_address AS receiver, + receiver AS destination_chain_receiver, + amount, + chainID AS destination_chain_id, + id, + revertableAddress AS revertable_address, + token AS token_address, + _log_id, + modified_timestamp +FROM + base_evt diff --git a/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.yml b/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.yml new file mode 100644 index 0000000..1bd34c6 --- /dev/null +++ b/models/silver/defi/bridge/symbiosis/silver_bridge__symbiosis_synthesizerequest.yml @@ -0,0 +1,72 @@ +version: 2 +models: + - name: silver_bridge__symbiosis_synthesizerequest + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.sql b/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.sql new file mode 100644 index 0000000..65aa6d4 --- /dev/null +++ b/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.sql @@ -0,0 +1,252 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'delete+insert', + unique_key = "block_number", + cluster_by = ['block_timestamp::DATE'], + tags = ['curated','reorg'] +) }} + +WITH base_evt AS ( + + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + topics, + topics [0] :: STRING AS topic_0, + topics [1] :: STRING AS topic_1, + topics [2] :: STRING AS topic_2, + topics [3] :: STRING AS topic_3, + DATA, + regexp_substr_all(SUBSTR(DATA, 3, len(DATA)), '.{64}') AS segmented_data, + CASE + WHEN tx_status = 'SUCCESS' THEN TRUE + ELSE FALSE + END AS tx_succeeded, + CONCAT( + tx_hash :: STRING, + '-', + event_index :: STRING + ) AS _log_id, + modified_timestamp + FROM + {{ ref('core__fact_event_logs') }} + WHERE + contract_address = '0x55769baf6ec39b3bf4aae948eb890ea33307ef3c' + AND topic_0 IN ( + '0x91f25e9be0134ec851830e0e76dc71e06f9dade75a9b84e9524071dbbc319425', + -- TokenRedeemAndSwap + '0x79c15604b92ef54d3f61f0c40caab8857927ca3d5092367163b4562c1699eb5f', + -- TokenDepositAndSwap + '0x9a7024cde1920aa50cdde09ca396229e8c4d530d5cfdc6233590def70a94408c', + -- TokenRedeemAndRemove + '0xdc5bad4651c5fbe9977a696aadc65996c468cde1448dd468ec0d83bf61c4b57c', + -- TokenRedeem + '0xda5273705dbef4bf1b902a131c2eac086b7e1476a8ab0cb4da08af1fe1bd8e3b', + -- TokenDeposit + '0x8e57e8c5fea426159af69d47eda6c5052c7605c9f70967cf749d4aa55b70b499' -- TokenRedeemV2 (terra specific) + ) + AND tx_succeeded + +{% if is_incremental() %} +AND modified_timestamp >= ( + SELECT + MAX(modified_timestamp) - INTERVAL '12 hours' + FROM + {{ this }} +) +AND modified_timestamp >= SYSDATE() - INTERVAL '7 day' +{% endif %} +), +redeem_swap AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + CASE + WHEN topic_0 = '0x91f25e9be0134ec851830e0e76dc71e06f9dade75a9b84e9524071dbbc319425' THEN 'TokenRedeemAndSwap' + WHEN topic_0 = '0x79c15604b92ef54d3f61f0c40caab8857927ca3d5092367163b4562c1699eb5f' THEN 'TokenDepositAndSwap' + END AS event_name, + CONCAT('0x', SUBSTR(topic_1, 27, 40)) AS to_address, + segmented_data, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [0] :: STRING)) AS chainId, + CONCAT('0x', SUBSTR(segmented_data [1] :: STRING, 25, 40)) AS token, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [2] :: STRING)) AS amount, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [3] :: STRING)) AS tokenIndexFrom, + -- source chain token index + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [4] :: STRING)) AS tokenIndexTo, + -- dst chain token index + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [5] :: STRING)) AS minDy, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [6] :: STRING)) AS deadline, + -- timestamp + tx_succeeded, + _log_id, + modified_timestamp + FROM + base_evt + WHERE + topic_0 IN ( + '0x91f25e9be0134ec851830e0e76dc71e06f9dade75a9b84e9524071dbbc319425', + -- TokenRedeemAndSwap + '0x79c15604b92ef54d3f61f0c40caab8857927ca3d5092367163b4562c1699eb5f' -- TokenDepositAndSwap + ) +), +redeem_remove AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + 'TokenRedeemAndRemove' AS event_name, + CONCAT('0x', SUBSTR(topic_1, 27, 40)) AS to_address, + segmented_data, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [0] :: STRING)) AS chainId, + CONCAT('0x', SUBSTR(segmented_data [1] :: STRING, 25, 40)) AS token, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [2] :: STRING)) AS amount, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [3] :: STRING)) AS swapTokenIndex, + -- dst chain token index + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [4] :: STRING)) AS swapMinAmount, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [5] :: STRING)) AS swapDeadline, + -- timestamp + tx_succeeded, + _log_id, + modified_timestamp + FROM + base_evt + WHERE + topic_0 = '0x9a7024cde1920aa50cdde09ca396229e8c4d530d5cfdc6233590def70a94408c' -- TokenRedeemAndRemove +), +redeem_only AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + CASE + WHEN topic_0 = '0xdc5bad4651c5fbe9977a696aadc65996c468cde1448dd468ec0d83bf61c4b57c' THEN 'TokenRedeem' + WHEN topic_0 = '0xda5273705dbef4bf1b902a131c2eac086b7e1476a8ab0cb4da08af1fe1bd8e3b' THEN 'TokenDeposit' + WHEN topic_0 = '0x8e57e8c5fea426159af69d47eda6c5052c7605c9f70967cf749d4aa55b70b499' THEN 'TokenRedeemV2' + END AS event_name, + CONCAT('0x', SUBSTR(topic_1, 27, 40)) AS to_address, + segmented_data, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [0] :: STRING)) AS chainId, + CONCAT('0x', SUBSTR(segmented_data [1] :: STRING, 25, 40)) AS token, + TRY_TO_NUMBER(utils.udf_hex_to_int(segmented_data [2] :: STRING)) AS amount, + tx_succeeded, + _log_id, + modified_timestamp + FROM + base_evt + WHERE + topic_0 IN ( + '0xdc5bad4651c5fbe9977a696aadc65996c468cde1448dd468ec0d83bf61c4b57c', + -- TokenRedeem + '0xda5273705dbef4bf1b902a131c2eac086b7e1476a8ab0cb4da08af1fe1bd8e3b', + -- TokenDeposit + '0x8e57e8c5fea426159af69d47eda6c5052c7605c9f70967cf749d4aa55b70b499' -- TokenRedeemV2 (terra specific) + ) +), +all_evts AS ( + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + event_name, + to_address, + segmented_data, + chainId, + token, + amount, + tx_succeeded, + _log_id, + modified_timestamp + FROM + redeem_swap + UNION ALL + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + event_name, + to_address, + segmented_data, + chainId, + token, + amount, + tx_succeeded, + _log_id, + modified_timestamp + FROM + redeem_remove + UNION ALL + SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + contract_address, + event_index, + event_name, + to_address, + segmented_data, + chainId, + token, + amount, + tx_succeeded, + _log_id, + modified_timestamp + FROM + redeem_only +) +SELECT + block_number, + block_timestamp, + origin_from_address, + origin_to_address, + origin_function_signature, + tx_hash, + event_index, + event_name, + contract_address AS bridge_address, + origin_from_address AS sender, + to_address AS receiver, + receiver AS destination_chain_receiver, + chainId AS destination_chain_id, + token AS token_address, + amount, + tx_succeeded, + 'synapse' AS platform, + _log_id, + modified_timestamp +FROM + all_evts diff --git a/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.yml b/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.yml new file mode 100644 index 0000000..31996ec --- /dev/null +++ b/models/silver/defi/bridge/synapse/silver_bridge__synapse_tokenredeem.yml @@ -0,0 +1,72 @@ +version: 2 +models: + - name: silver_bridge__synapse_tokenredeem + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - _LOG_ID + columns: + - name: BLOCK_NUMBER + tests: + - not_null + - name: BLOCK_TIMESTAMP + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 3 + - name: ORIGIN_FUNCTION_SIGNATURE + tests: + - not_null + - name: ORIGIN_FROM_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: ORIGIN_TO_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: TX_HASH + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: EVENT_INDEX + tests: + - not_null + - name: EVENT_NAME + tests: + - not_null + - name: BRIDGE_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: SENDER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: RECEIVER + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ + - name: DESTINATION_CHAIN_RECEIVER + tests: + - not_null + - name: AMOUNT + tests: + - not_null + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - DECIMAL + - FLOAT + - NUMBER + - name: TOKEN_ADDRESS + tests: + - not_null + - dbt_expectations.expect_column_values_to_match_regex: + regex: 0[xX][0-9a-fA-F]+ diff --git a/models/silver/protocols/blitz/silver__blitz_money_markets.sql b/models/silver/protocols/blitz/silver__blitz_money_markets.sql new file mode 100644 index 0000000..6af749d --- /dev/null +++ b/models/silver/protocols/blitz/silver__blitz_money_markets.sql @@ -0,0 +1,55 @@ +{{ config( + materialized = 'incremental', + incremental_strategy = 'merge', + unique_key = ['ticker_id','hour'], + cluster_by = ['HOUR::DATE'], + tags = 'curated' +) }} + +WITH apr AS ( + + SELECT + PARSE_JSON( + live.udf_api( + 'https://gateway.blast-prod.vertexprotocol.com/v2/apr' + ) + ) :data AS response +), +flattened AS ( + SELECT + DATE_TRUNC('hour', SYSDATE()) AS HOUR, + CONCAT( + f.value :symbol :: STRING, + '_USDB' + ) AS ticker_id, + f.value :symbol :: STRING AS symbol, + f.value :product_id :: STRING AS product_id, + f.value :deposit_apr :: FLOAT AS deposit_apr, + f.value :borrow_apr :: FLOAT AS borrow_apr, + f.value :tvl :: FLOAT AS tvl + FROM + apr A, + LATERAL FLATTEN( + input => response + ) AS f +) +SELECT + HOUR, + ticker_id, + symbol, + product_id, + deposit_apr, + borrow_apr, + tvl, + SYSDATE() AS inserted_timestamp, + SYSDATE() AS modified_timestamp, + {{ dbt_utils.generate_surrogate_key( + ['ticker_id','hour'] + ) }} AS blitz_money_markets_id, + '{{ invocation_id }}' AS _invocation_id +FROM + flattened +WHERE + product_id NOT IN ('121', '125') qualify(ROW_NUMBER() over(PARTITION BY ticker_id, HOUR +ORDER BY + inserted_timestamp DESC)) = 1 diff --git a/models/silver/protocols/blitz/silver__blitz_money_markets.yml b/models/silver/protocols/blitz/silver__blitz_money_markets.yml new file mode 100644 index 0000000..b80eaf4 --- /dev/null +++ b/models/silver/protocols/blitz/silver__blitz_money_markets.yml @@ -0,0 +1,44 @@ +version: 2 +models: + - name: silver__blitz_money_markets + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - HOUR + - TICKER_ID + columns: + - name: HOUR + tests: + - not_null + - dbt_expectations.expect_row_values_to_have_recent_data: + datepart: day + interval: 1 + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - TIMESTAMP_LTZ + - TIMESTAMP_NTZ + - name: TICKER_ID + tests: + - not_null + - name: SYMBOL + - not_null + - name: PRODUCT_ID + - not_null + - name: DEPOSIT_APR + tests: + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - NUMBER + - FLOAT + - name: BORROW_APR + tests: + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - NUMBER + - FLOAT + - name: TVL + tests: + - dbt_expectations.expect_column_values_to_be_in_type_list: + column_type_list: + - NUMBER + - FLOAT \ No newline at end of file