From 8d4db5edf8a545b121705f817e13c8f88b70c357 Mon Sep 17 00:00:00 2001 From: hildobby Date: Tue, 11 Jun 2024 19:57:00 +0200 Subject: [PATCH] Blur & Fantasy trades (#6091) * create fantasy trades * make fantasy.trades view * fix * fix * fix * fix project name * add blur trades * fix * fix --------- Co-authored-by: Alan Ghobadi --- .../chains/blast/nft_blast_base_trades.sql | 51 ++++++++ .../trades/chains/blast/platforms/_schema.yml | 30 +++++ .../platforms/blur_blast_base_trades.sql | 115 ++++++++++++++++++ .../platforms/fantasy_blast_base_trades.sql | 94 ++++++++++++++ models/_sector/nft/trades/nft_base_trades.sql | 1 + models/_sector/nft/trades/nft_trades.sql | 2 +- .../nft/trades/platform_views/_schema.yml | 10 ++ .../platform_views/fantasy_trades_view.sql | 15 +++ models/_sector/nft/trades/schema.yml | 2 +- sources/_sector/nft/trades/blast_sources.yml | 13 ++ 10 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 models/_sector/nft/trades/chains/blast/nft_blast_base_trades.sql create mode 100644 models/_sector/nft/trades/chains/blast/platforms/_schema.yml create mode 100644 models/_sector/nft/trades/chains/blast/platforms/blur_blast_base_trades.sql create mode 100644 models/_sector/nft/trades/chains/blast/platforms/fantasy_blast_base_trades.sql create mode 100644 models/_sector/nft/trades/platform_views/fantasy_trades_view.sql create mode 100644 sources/_sector/nft/trades/blast_sources.yml diff --git a/models/_sector/nft/trades/chains/blast/nft_blast_base_trades.sql b/models/_sector/nft/trades/chains/blast/nft_blast_base_trades.sql new file mode 100644 index 00000000000..a2f658caf11 --- /dev/null +++ b/models/_sector/nft/trades/chains/blast/nft_blast_base_trades.sql @@ -0,0 +1,51 @@ +{{ config( + schema = 'nft_blast', + alias = 'base_trades', + materialized = 'view' + ) +}} + + +{% set nft_models = [ + ref('fantasy_blast_base_trades') + , ref('blur_blast_base_trades') +] %} + + +SELECT * FROM ( +{% for nft_model in nft_models %} + SELECT + blockchain, + project, + project_version, + cast(date_trunc('day', block_time) as date) as block_date, + cast(date_trunc('month', block_time) as date) as block_month, + block_time, + block_number, + tx_hash, + project_contract_address, + trade_category, --buy/sell/swap + trade_type, --primary/secondary + buyer, + seller, + nft_contract_address, + nft_token_id, + nft_amount, -- always 1 for erc721 + price_raw, + currency_contract, + platform_fee_amount_raw, + royalty_fee_amount_raw, + platform_fee_address, -- optional + royalty_fee_address, -- optional + sub_tx_trade_id, + tx_from, + tx_to, + tx_data_marker, + row_number() over (partition by tx_hash, sub_tx_trade_id order by tx_hash) as duplicates_rank -- duplicates protection + FROM {{ nft_model }} + {% if not loop.last %} + UNION ALL + {% endif %} + {% endfor %} + ) +where duplicates_rank = 1 diff --git a/models/_sector/nft/trades/chains/blast/platforms/_schema.yml b/models/_sector/nft/trades/chains/blast/platforms/_schema.yml new file mode 100644 index 00000000000..44a07d83177 --- /dev/null +++ b/models/_sector/nft/trades/chains/blast/platforms/_schema.yml @@ -0,0 +1,30 @@ +version: 2 + +models: + - name: fantasy_blast_base_trades + meta: + blockchain: blast + sector: nft + project: fantasy + contributors: hildobby + config: + tags: ['blast', 'nft', 'trades', 'fantasy'] + description: "Fantasy base trades" + tests: + - check_columns_nft_base_trades + - dbt_utils.unique_combination_of_columns: + combination_of_columns: ['block_number','tx_hash','sub_tx_trade_id'] + + - name: blur_blast_base_trades + meta: + blockchain: blast + sector: nft + project: fantasy + contributors: hildobby + config: + tags: ['blast', 'nft', 'trades', 'blur'] + description: "Blur on blast base trades" + tests: + - check_columns_nft_base_trades + - dbt_utils.unique_combination_of_columns: + combination_of_columns: ['block_number','tx_hash','sub_tx_trade_id'] diff --git a/models/_sector/nft/trades/chains/blast/platforms/blur_blast_base_trades.sql b/models/_sector/nft/trades/chains/blast/platforms/blur_blast_base_trades.sql new file mode 100644 index 00000000000..9b9d78b2555 --- /dev/null +++ b/models/_sector/nft/trades/chains/blast/platforms/blur_blast_base_trades.sql @@ -0,0 +1,115 @@ +{{ config( + schema = 'blur_blast', + alias = 'base_trades', + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} + +{% set blur_blast_start_date = '2024-04-10' %} + +WITH blur_trades AS ( + SELECT evt_tx_hash AS tx_hash + , bytearray_to_uint256(bytearray_substring(cast(collectionPriceSide as varbinary),2,11)) AS price_raw + , evt_block_time AS block_time + , evt_block_number AS block_number + , NULL AS fee_side + , evt_index + , contract_address AS project_contract_address + , bytearray_to_bigint(bytearray_substring(cast(collectionPriceSide as varbinary),1,1)) AS order_type + , bytearray_substring(cast(collectionPriceSide as varbinary),13,20) AS nft_contract_address + , orderHash AS order_hash + , bytearray_to_uint256(bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),1,11)) AS nft_token_id + , bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),13,20) AS trader + , double '0' AS fee + , NULL AS royalty_fee_address + FROM {{ source('blur_blast','BlurExchangeV2_evt_Execution721Packed') }} + {% if is_incremental() %} + WHERE {{incremental_predicate('evt_block_time')}} + {% else %} + WHERE evt_block_time >= TIMESTAMP '{{blur_blast_start_date}}' + {% endif %} + + UNION ALL + + SELECT evt_tx_hash AS tx_hash + , bytearray_to_uint256(bytearray_substring(cast(collectionPriceSide as varbinary),2,11)) AS price_raw + , evt_block_time AS block_time + , evt_block_number AS block_number + , 'maker' AS fee_side + , evt_index + , contract_address AS project_contract_address + , bytearray_to_bigint(bytearray_substring(cast(collectionPriceSide as varbinary),1,1)) AS order_type + , bytearray_substring(cast(collectionPriceSide as varbinary),13,20) AS nft_contract_address + , orderHash AS order_hash + , bytearray_to_uint256(bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),1,11)) AS nft_token_id + , bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),13,20) AS trader + , CAST(bitwise_right_shift(makerFeeRecipientRate, 160) AS double)/10000 AS fee + , bytearray_substring(cast(makerFeeRecipientRate as varbinary),13,20) AS royalty_fee_address + FROM {{ source('blur_blast','BlurExchangeV2_evt_Execution721MakerFeePacked') }} + {% if is_incremental() %} + WHERE {{incremental_predicate('evt_block_time')}} + {% else %} + WHERE evt_block_time >= TIMESTAMP '{{blur_blast_start_date}}' + {% endif %} + + UNION ALL + + SELECT evt_tx_hash AS tx_hash + , bytearray_to_uint256(bytearray_substring(cast(collectionPriceSide as varbinary),2,11)) AS price_raw + , evt_block_time AS block_time + , evt_block_number AS block_number + , 'taker' AS fee_side + , evt_index + , contract_address AS project_contract_address + , bytearray_to_bigint(bytearray_substring(cast(collectionPriceSide as varbinary),1,1)) AS order_type + , bytearray_substring(cast(collectionPriceSide as varbinary),13,20) AS nft_contract_address + , orderHash AS order_hash + , bytearray_to_uint256(bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),1,11)) AS nft_token_id + , bytearray_substring(cast(tokenIdListingIndexTrader as varbinary),13,20) AS trader + , CAST(bitwise_right_shift(takerFeeRecipientRate, 160) AS double)/10000 AS fee + , bytearray_substring(cast(takerFeeRecipientRate as varbinary),13,20) AS royalty_fee_address + FROM {{ source('blur_blast','BlurExchangeV2_evt_Execution721TakerFeePacked') }} + {% if is_incremental() %} + WHERE {{incremental_predicate('evt_block_time')}} + {% else %} + WHERE evt_block_time >= TIMESTAMP '{{blur_blast_start_date}}' + {% endif %} + ) + +, trades_final AS ( + SELECT 'blast' as blockchain + , 'blur' as project + , 'v2' as project_version + , bt.block_time + , bt.block_number + , bt.tx_hash + , bt.evt_index AS sub_tx_trade_id + , CASE WHEN bt.order_type = 1 THEN 'Sell' ELSE 'Buy' END AS trade_category + , 'secondary' AS trade_type + , CASE WHEN bt.order_type = 1 THEN bt.trader ELSE txs."from" END AS buyer + , CASE WHEN bt.order_type = 0 THEN bt.trader ELSE txs."from" END AS seller + , bt.nft_contract_address + , bt.nft_token_id AS nft_token_id + , UINT256 '1' AS nft_amount + , bt.price_raw + , CASE WHEN bt.order_type = 0 THEN 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 ELSE 0x0000000000a39bb272e79075ade125fd351887ac END AS currency_contract + , bt.project_contract_address + , uint256 '0' AS platform_fee_amount_raw + , CAST(NULL AS varbinary) AS platform_fee_address + , CAST(ROUND(bt.price_raw * bt.fee) AS UINT256) AS royalty_fee_amount_raw + , bt.royalty_fee_address + FROM blur_trades bt + -- todo: remove the join on transactions here + INNER JOIN {{ source('blast', 'transactions') }} txs ON txs.block_number=bt.block_number + AND txs.hash=bt.tx_hash + {% if is_incremental() %} + AND {{incremental_predicate('txs.block_time')}} + {% else %} + AND txs.block_time >= TIMESTAMP '{{blur_blast_start_date}}' + {% endif %} + ) + +{{ add_nft_tx_data('trades_final', 'blast') }} \ No newline at end of file diff --git a/models/_sector/nft/trades/chains/blast/platforms/fantasy_blast_base_trades.sql b/models/_sector/nft/trades/chains/blast/platforms/fantasy_blast_base_trades.sql new file mode 100644 index 00000000000..3bfb0c4ba7b --- /dev/null +++ b/models/_sector/nft/trades/chains/blast/platforms/fantasy_blast_base_trades.sql @@ -0,0 +1,94 @@ +{{ config( + schema = 'fantasy_blast', + alias = 'base_trades', + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'] + ) +}} + +{% set project_start_date = '2024-05-01' %} + +WITH trades AS ( + SELECT evt_block_time AS block_time + , evt_block_date AS block_date + , CAST(JSON_EXTRACT_SCALAR(sell, '$.tokenId') AS UINT256) AS nft_token_id + , UINT256 '1' AS nft_amount + , 'Buy' AS trade_category + , from_hex(JSON_EXTRACT_SCALAR(sell, '$.trader')) AS seller + , buyer + , CAST(JSON_EXTRACT_SCALAR(sell, '$.price') AS UINT256) AS price_raw + , from_hex(JSON_EXTRACT_SCALAR(sell, '$.paymentToken')) AS currency_contract + , from_hex(JSON_EXTRACT_SCALAR(sell, '$.collection')) AS nft_contract_address + , evt_tx_hash AS tx_hash + , contract_address AS project_contract_address + , evt_block_number AS block_number + , evt_index AS sub_tx_trade_id + , evt_tx_from AS tx_from + , evt_tx_to AS tx_to + FROM {{ source('fantasy_blast', 'Exchange_evt_Buy')}} + {% if not is_incremental() %} + WHERE evt_block_time >= TIMESTAMP '{{project_start_date}}' + {% endif %} + {% if is_incremental() %} + WHERE {{ incremental_predicate('evt_block_time') }} + {% endif %} + + UNION ALL + + SELECT evt_block_time AS block_time + , evt_block_date AS block_date + , CAST(JSON_EXTRACT_SCALAR(buyOrder, '$.tokenId') AS UINT256) AS nft_token_id + , UINT256 '1' AS nft_amount + , 'Sell' AS trade_category + , seller + , from_hex(JSON_EXTRACT_SCALAR(buyOrder, '$.trader')) AS buyer + , CAST(JSON_EXTRACT_SCALAR(buyOrder, '$.price') AS UINT256) AS price_raw + , from_hex(JSON_EXTRACT_SCALAR(buyOrder, '$.paymentToken')) AS currency_contract + , from_hex(JSON_EXTRACT_SCALAR(buyOrder, '$.collection')) AS nft_contract_address + , evt_tx_hash AS tx_hash + , contract_address AS project_contract_address + , evt_block_number AS block_number + , evt_index AS sub_tx_trade_id + , evt_tx_from AS tx_from + , evt_tx_to AS tx_to + FROM {{ source('fantasy_blast', 'Exchange_evt_Sell')}} + {% if not is_incremental() %} + WHERE evt_block_time >= TIMESTAMP '{{project_start_date}}' + {% endif %} + {% if is_incremental() %} + WHERE {{ incremental_predicate('evt_block_time') }} + {% endif %} + ) + + , trades_final AS ( + SELECT 'blast' AS blockchain + , 'fantasy' AS project + , 'v1' AS project_version + , block_time + , block_date + , date_trunc('month', block_time) AS block_month + , nft_token_id + , 'secondary' AS trade_type + , nft_amount + , trade_category + , seller + , buyer + , price_raw + , currency_contract + , nft_contract_address + , tx_hash + , project_contract_address + , block_number + , sub_tx_trade_id + --, tx_from + --, tx_to + , CAST(0.015*CAST(price_raw AS double) AS UINT256) AS platform_fee_amount_raw + , CAST(0.015*CAST(price_raw AS double) AS UINT256) AS royalty_fee_amount_raw + , CAST(NULL AS VARBINARY) AS royalty_fee_address + , 0x8ab15fe88a00b03724ac91ee4ee1f998064f2e31 AS platform_fee_address + FROM trades + ) + +{{ add_nft_tx_data('trades_final', 'base') }} \ No newline at end of file diff --git a/models/_sector/nft/trades/nft_base_trades.sql b/models/_sector/nft/trades/nft_base_trades.sql index 94cfd80f831..3bef0549b6b 100644 --- a/models/_sector/nft/trades/nft_base_trades.sql +++ b/models/_sector/nft/trades/nft_base_trades.sql @@ -25,6 +25,7 @@ ,ref('nft_avalanche_c_base_trades') ,ref('nft_linea_base_trades') ,ref('nft_zora_base_trades') + ,ref('nft_blast_base_trades') ] %} with base_union as ( diff --git a/models/_sector/nft/trades/nft_trades.sql b/models/_sector/nft/trades/nft_trades.sql index 8c5309e4a52..d060f52e9f5 100644 --- a/models/_sector/nft/trades/nft_trades.sql +++ b/models/_sector/nft/trades/nft_trades.sql @@ -2,7 +2,7 @@ schema = 'nft', alias = 'trades', materialized = 'view', - post_hook='{{ expose_spells(\'["ethereum","solana","bnb","optimism","arbitrum","polygon","zksync"]\', + post_hook='{{ expose_spells(\'["ethereum","solana","bnb","optimism","arbitrum","polygon","zksync", "blast"]\', "sector", "nft", \'["soispoke","0xRob", "hildobby"]\') }}') diff --git a/models/_sector/nft/trades/platform_views/_schema.yml b/models/_sector/nft/trades/platform_views/_schema.yml index 8284bb447e8..b92f13aa9b3 100644 --- a/models/_sector/nft/trades/platform_views/_schema.yml +++ b/models/_sector/nft/trades/platform_views/_schema.yml @@ -251,3 +251,13 @@ models: tags: ['nft', 'trades', 'zora'] description: "NFT trades view for zora" + + - name: fantasy_trades_view + meta: + blockchain: ["blast"] + sector: nft + contributors: hildobby + config: + tags: ['nft', 'trades', 'blast'] + description: "NFT trades view for fantasy" + diff --git a/models/_sector/nft/trades/platform_views/fantasy_trades_view.sql b/models/_sector/nft/trades/platform_views/fantasy_trades_view.sql new file mode 100644 index 00000000000..61afe8ea2e5 --- /dev/null +++ b/models/_sector/nft/trades/platform_views/fantasy_trades_view.sql @@ -0,0 +1,15 @@ + +{{ config( + schema = 'fantasy', + alias = 'trades', + + materialized = 'view', + post_hook='{{ expose_spells(\'["blast"]\', + "project", + "fantasy", + \'["hildobby"]\') }}') +}} + +SELECT * +FROM {{ ref('nft_trades') }} +WHERE project = 'fantasy' diff --git a/models/_sector/nft/trades/schema.yml b/models/_sector/nft/trades/schema.yml index d500d467fd9..1578719454f 100644 --- a/models/_sector/nft/trades/schema.yml +++ b/models/_sector/nft/trades/schema.yml @@ -145,7 +145,7 @@ models: - name: nft_trades meta: - blockchain: ethereum, solana, bnb, optimism, arbitrum, polygon + blockchain: ethereum, solana, bnb, optimism, arbitrum, polygon, blast sector: nft contributors: soispoke, hildobby, ilemi, cat config: diff --git a/sources/_sector/nft/trades/blast_sources.yml b/sources/_sector/nft/trades/blast_sources.yml new file mode 100644 index 00000000000..d596cbc4534 --- /dev/null +++ b/sources/_sector/nft/trades/blast_sources.yml @@ -0,0 +1,13 @@ +version: 2 + +sources: + - name: blur_blast + tables: + - name: BlurExchangeV2_evt_Execution721Packed + - name: BlurExchangeV2_evt_Execution721MakerFeePacked + - name: BlurExchangeV2_evt_Execution721TakerFeePacked + + - name: fantasy_blast + tables: + - name: Exchange_evt_Buy + - name: Exchange_evt_Sell \ No newline at end of file