From f68e658b39c881f8087482ea1a6dfa982b43025f Mon Sep 17 00:00:00 2001 From: 0xRob <83790096+0xRobin@users.noreply.github.com> Date: Wed, 17 May 2023 21:22:45 +0200 Subject: [PATCH] NFT Restructuring (#3357) * Restructure Cryptopunks to new NFT trades setup (#3286) * cryptopunks restructuring * add to trades_beta * fix join logic * fix call reference * fix bid pricing * fix bid buyer * syntax * fix * allow 0.1% error and fix seed value * Restructure Sudoswap to new NFT trades setup (#3329) * sudoswap restructuring * syntax fix * add seed test * Restructure collectionswap to new NFT trades setup (#3330) * restructure collectionswap * syntax fix * bugfix * use price_raw * add test seed * check-seed * Restructure looksrare to new NFT trades setup (#3332) * restructure looksrare * bugfix * bugfix * bugfix * add seed tests * fix seed * seed schema * cleanup * lr seed schema * NFT trades backwards compatibility layer (#3350) * compatibility layer * typo * test passes with no results * fix setup * fix * add fee percentages * nest test * move from string to varchar * allow the ignore of 1 punk sale in the rowcount test * allow the ignore of 1 punk sale in the rowcount test * allow the ignore of 1 punk sale in the rowcount test --- macros/models/_sector/nft/enrich_trades.sql | 2 + .../models/_sector/nft/port_to_old_schema.sql | 44 +++ models/_sector/nft/trades/MIGRATION.md | 2 +- .../nft/trades/ethereum/platforms/_schema.yml | 145 ++++++++++ .../trades/ethereum/platforms/_sources.yml | 3 + .../collectionswap_ethereum_base_trades.sql | 115 ++++++++ .../cryptopunks_ethereum_base_trades.sql | 62 ++++ .../looksrare_v1_ethereum_base_trades.sql | 122 ++++++++ .../looksrare_v2_ethereum_base_trades.sql | 86 ++++++ .../sudoswap_ethereum_base_trades.sql | 270 ++++++++++++++++++ .../nft/trades/nft_ethereum_trades_beta.sql | 5 + .../nft_ethereum_trades_beta_ported.sql | 8 + models/_sector/nft/trades/schema.yml | 10 + seeds/_sector/nft/_schema.yml | 25 +- ...llectionswap_ethereum_base_trades_seed.csv | 5 + .../cryptopunks_ethereum_base_trades_seed.csv | 5 + ...looksrare_v1_ethereum_base_trades_seed.csv | 5 + ...looksrare_v2_ethereum_base_trades_seed.csv | 5 + .../sudoswap_ethereum_base_trades_seed.csv | 7 + tests/_sector/nft/check_backport_columns.sql | 90 ++++++ .../nft/check_nft_migrations_ethereum.sql | 6 +- 21 files changed, 1017 insertions(+), 5 deletions(-) create mode 100644 macros/models/_sector/nft/port_to_old_schema.sql create mode 100644 models/_sector/nft/trades/ethereum/platforms/collectionswap_ethereum_base_trades.sql create mode 100644 models/_sector/nft/trades/ethereum/platforms/cryptopunks_ethereum_base_trades.sql create mode 100644 models/_sector/nft/trades/ethereum/platforms/looksrare_v1_ethereum_base_trades.sql create mode 100644 models/_sector/nft/trades/ethereum/platforms/looksrare_v2_ethereum_base_trades.sql create mode 100644 models/_sector/nft/trades/ethereum/platforms/sudoswap_ethereum_base_trades.sql create mode 100644 models/_sector/nft/trades/nft_ethereum_trades_beta_ported.sql create mode 100644 seeds/_sector/nft/collectionswap_ethereum_base_trades_seed.csv create mode 100644 seeds/_sector/nft/cryptopunks_ethereum_base_trades_seed.csv create mode 100644 seeds/_sector/nft/looksrare_v1_ethereum_base_trades_seed.csv create mode 100644 seeds/_sector/nft/looksrare_v2_ethereum_base_trades_seed.csv create mode 100644 seeds/_sector/nft/sudoswap_ethereum_base_trades_seed.csv create mode 100644 tests/_sector/nft/check_backport_columns.sql diff --git a/macros/models/_sector/nft/enrich_trades.sql b/macros/models/_sector/nft/enrich_trades.sql index 7c4cc372916..7f373c0eca4 100644 --- a/macros/models/_sector/nft/enrich_trades.sql +++ b/macros/models/_sector/nft/enrich_trades.sql @@ -78,6 +78,8 @@ SELECT base.price_raw/pow(10,coalesce(erc20.decimals,18))*p.price as price_usd, base.platform_fee_amount_raw/pow(10,coalesce(erc20.decimals,18))*p.price as platform_fee_amount_usd, base.royalty_fee_amount_raw/pow(10,coalesce(erc20.decimals,18))*p.price as royalty_fee_amount_usd, + coalesce(cast(100*base.platform_fee_amount_raw/base.price_raw as double),cast(0.0 as double)) as platform_fee_percentage, + coalesce(cast(100*base.royalty_fee_amount_raw/base.price_raw as double),cast(0.0 as double)) as royalty_fee_percentage, coalesce(agg1.contract_address,agg2.contract_address) as aggregator_address, {% if aggregator_markers != null %} coalesce(agg_mark.aggregator_name, agg1.name, agg2.name) as aggregator_name diff --git a/macros/models/_sector/nft/port_to_old_schema.sql b/macros/models/_sector/nft/port_to_old_schema.sql new file mode 100644 index 00000000000..9b3bc2e76fc --- /dev/null +++ b/macros/models/_sector/nft/port_to_old_schema.sql @@ -0,0 +1,44 @@ +{% macro port_to_old_schema(model) %} + +SELECT + blockchain, + project, + project_version as version, + block_date, + block_time, + nft_token_id as token_id, + nft_collection as collection, + price_usd as amount_usd, + nft_standard as token_standard, + trade_type, + nft_amount as number_of_items, + trade_category, + 'Trade' as evt_type, + seller, + buyer, + price as amount_original, + price_raw as amount_raw, + currency_symbol, + currency_contract, + nft_contract_address, + project_contract_address, + aggregator_name, + aggregator_address, + tx_hash, + block_number, + tx_from, + tx_to, + platform_fee_amount_raw, + platform_fee_amount, + platform_fee_amount_usd, + platform_fee_percentage, + royalty_fee_address as royalty_fee_receive_address, + currency_symbol as royalty_fee_currency_symbol, + royalty_fee_amount_raw, + royalty_fee_amount, + royalty_fee_amount_usd, + royalty_fee_percentage, + concat(cast(block_number as varchar(10)),'-',cast(tx_hash as varchar(42)),'-',cast(sub_tx_trade_id as varchar(10))) as unique_trade_id +FROM {{ model }} + +{% endmacro %} diff --git a/models/_sector/nft/trades/MIGRATION.md b/models/_sector/nft/trades/MIGRATION.md index a3e77de4f8c..76adb2a6100 100644 --- a/models/_sector/nft/trades/MIGRATION.md +++ b/models/_sector/nft/trades/MIGRATION.md @@ -130,7 +130,7 @@ The migration for each protocol consists of 3 parts. |-------------|:-------:|-------------------:|:--------:|:---------:|:------:| | archipelago | v1 | 561 | [x] | [x] | | | blur | v1 | 3,067,180 | [x] | [x] | | -| cryptopunks | v1 | 23,054 | | | | +| cryptopunks | v1 | 23,054 | [x] | [x] | | | element | v1 | 106,654 | | | | | foundation | v1 | 137,246 | [x] | [x] | | | looksrare | v1 | 401,647 | | | | diff --git a/models/_sector/nft/trades/ethereum/platforms/_schema.yml b/models/_sector/nft/trades/ethereum/platforms/_schema.yml index 75207976dd9..7f74e93ff93 100644 --- a/models/_sector/nft/trades/ethereum/platforms/_schema.yml +++ b/models/_sector/nft/trades/ethereum/platforms/_schema.yml @@ -93,6 +93,37 @@ models: - platform_fee_amount_raw - royalty_fee_amount_raw + - name: cryptopunks_ethereum_base_trades + meta: + blockchain: ethereum + sector: nft + project: cyptopunks + contributors: [ 'cat', '0xRob' ] + config: + tags: [ 'ethereum', 'nft', 'trades', 'cyptopunks' ] + description: "cyptopunks base trades" + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: [ 'block_number','tx_hash','sub_tx_trade_id' ] + - equal_rowcount_with_sources: + error_if: ">1" + evt_sources: + - source('cryptopunks_ethereum','CryptoPunksMarket_evt_PunkBought') + - check_seed: + seed_file: ref('cryptopunks_ethereum_base_trades_seed') + match_columns: + - block_number + - tx_hash + - sub_tx_trade_id + check_columns: + - buyer + - seller + - nft_contract_address + - nft_token_id + - price_raw + - platform_fee_amount_raw + - royalty_fee_amount_raw + - name: blur_ethereum_base_trades meta: blockchain: ethereum @@ -183,6 +214,67 @@ models: - platform_fee_amount_raw - royalty_fee_amount_raw + - name: looksrare_v1_ethereum_base_trades + meta: + blockchain: ethereum + sector: nft + project: looksrare + contributors: [ '0xRob','soispoke', 'hildobby', 'denze' ] + config: + tags: [ 'ethereum', 'nft', 'trades', 'looksrare' ] + description: "looksrare v1 base trades" + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: [ 'block_number','tx_hash','sub_tx_trade_id' ] + - equal_rowcount_with_sources: + evt_sources: + - source('looksrare_ethereum','LooksRareExchange_evt_TakerAsk') + - source('looksrare_ethereum','LooksRareExchange_evt_TakerBid') + - check_seed: + seed_file: ref('looksrare_v1_ethereum_base_trades_seed') + match_columns: + - block_number + - tx_hash + - sub_tx_trade_id + check_columns: + - buyer + - seller + - nft_contract_address + - nft_token_id + - price_raw + - platform_fee_amount_raw + - royalty_fee_amount_raw + + - name: looksrare_v2_ethereum_base_trades + meta: + blockchain: ethereum + sector: nft + project: looksrare + contributors: [ '0xRob','soispoke', 'hildobby', 'denze' ] + config: + tags: [ 'ethereum', 'nft', 'trades', 'looksrare' ] + description: "looksrare v2 base trades" + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: [ 'block_number','tx_hash','sub_tx_trade_id' ] + - equal_rowcount_with_sources: + evt_sources: + - source('looksrare_v2_ethereum','LooksRareProtocol_evt_TakerAsk') + - source('looksrare_v2_ethereum','LooksRareProtocol_evt_TakerBid') + - check_seed: + seed_file: ref('looksrare_v2_ethereum_base_trades_seed') + match_columns: + - block_number + - tx_hash + - sub_tx_trade_id + check_columns: + - buyer + - seller + - nft_contract_address + - nft_token_id + - price_raw + - platform_fee_amount_raw + - royalty_fee_amount_raw - name: zora_v1_ethereum_base_trades meta: blockchain: ethereum @@ -280,3 +372,56 @@ models: - platform_fee_amount_raw - royalty_fee_amount_raw + - name: sudoswap_ethereum_base_trades + meta: + blockchain: ethereum + sector: nft + project: sudoswap + contributors: [ '0xRob','ilemi' ] + config: + tags: [ 'ethereum', 'nft', 'trades', 'sudoswap' ] + description: "sudoswap base trades" + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: [ 'block_number','tx_hash','sub_tx_trade_id' ] + - check_seed: + seed_file: ref('sudoswap_ethereum_base_trades_seed') + match_columns: + - block_number + - tx_hash + - sub_tx_trade_id + check_columns: + - buyer + - seller + - nft_contract_address + - nft_token_id + - price_raw + - platform_fee_amount_raw + - royalty_fee_amount_raw + + - name: collectionswap_ethereum_base_trades + meta: + blockchain: ethereum + sector: nft + project: collectionswap + contributors: [ '0xRob' ] + config: + tags: [ 'ethereum', 'nft', 'trades', 'collectionswap' ] + description: "collectionswap base trades" + tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: [ 'block_number','tx_hash','sub_tx_trade_id' ] + - check_seed: + seed_file: ref('collectionswap_ethereum_base_trades_seed') + match_columns: + - block_number + - tx_hash + - sub_tx_trade_id + check_columns: + - buyer + - seller + - nft_contract_address + - nft_token_id + - price_raw + - platform_fee_amount_raw + - royalty_fee_amount_raw diff --git a/models/_sector/nft/trades/ethereum/platforms/_sources.yml b/models/_sector/nft/trades/ethereum/platforms/_sources.yml index 2d2a66e69b9..6a21d260cff 100644 --- a/models/_sector/nft/trades/ethereum/platforms/_sources.yml +++ b/models/_sector/nft/trades/ethereum/platforms/_sources.yml @@ -3,4 +3,7 @@ version: 2 sources: - name: archipelago_ethereum - name: superrare_ethereum + - name: cryptopunks_ethereum + tables: + - name: CryptoPunksMarket_call_acceptBidForPunk # sources are already defined in the "older" directories and can't be defined twice. In the end we should migrate them to here. diff --git a/models/_sector/nft/trades/ethereum/platforms/collectionswap_ethereum_base_trades.sql b/models/_sector/nft/trades/ethereum/platforms/collectionswap_ethereum_base_trades.sql new file mode 100644 index 00000000000..f4d93bf591b --- /dev/null +++ b/models/_sector/nft/trades/ethereum/platforms/collectionswap_ethereum_base_trades.sql @@ -0,0 +1,115 @@ +{{ config( + schema = 'collectionswap_ethereum', + alias ='base_trades', + partition_by = ['block_date'], + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} + +{%- set project_start_date = '2023-03-29' %} + +WITH +raw_trades as ( + select * + , row_number() over (partition by tx_hash order by evt_index asc, sub_order_id asc) as sub_tx_trade_id + from( + select + block_number, block_time, evt_index, tx_hash, buyer, seller, + posexplode(nft_id_array) as (sub_order_id, nft_token_id), + cast(1 as int) as nft_amount, + price_raw/number_of_items as price_raw, + platform_fee_amount_raw/number_of_items as platform_fee_amount_raw, + royalty_fee_amount_raw/number_of_items as royalty_fee_amount_raw, + trade_fee_amount_raw/number_of_items as trade_fee_amount_raw, + royalty_fee_address, + project_contract_address, + number_of_items, + 'secondary' as trade_type, + trade_category + from( + select + evt_block_number as block_number + ,evt_block_time as block_time + ,evt_index + ,evt_tx_hash as tx_hash + ,null as buyer + ,contract_address as seller + ,'Buy' as trade_category + ,nftIds as nft_id_array + ,cardinality(nftIds) as number_of_items + ,cast(outputAmount as decimal(38)) as price_raw + ,cast(protocolFee as decimal(38)) as platform_fee_amount_raw + ,get_json_object(royaltyDue[0], '$.amount') as royalty_fee_amount_raw + ,get_json_object(royaltyDue[0], '$.recipient') as royalty_fee_address + ,cast(tradeFee as decimal(38)) as trade_fee_amount_raw + ,contract_address as project_contract_address + from {{ source('collectionswap_ethereum','CollectionPool_evt_SwapNFTOutPool') }} e + {% if is_incremental() %} + WHERE evt_block_time >= date_trunc("day", now() - interval '1 week') + {% else %} + WHERE evt_block_time >= '{{project_start_date}}' + {% endif %} + union all + select + evt_block_number as block_number + ,evt_block_time as block_time + ,evt_index + ,evt_tx_hash as tx_hash + ,contract_address as buyer + ,null as seller + ,'Sell' as trade_category + ,nftIds as nft_id_array + ,cardinality(nftIds) as number_of_items + ,cast(inputAmount + protocolFee + cast(get_json_object(royaltyDue[0], '$.amount') as decimal(38)) as decimal(38)) as price_raw + ,cast(protocolFee as decimal(38)) as platform_fee_amount_raw + ,get_json_object(royaltyDue[0], '$.amount') as royalty_fee_amount_raw + ,get_json_object(royaltyDue[0], '$.recipient') as royalty_fee_address + ,cast(tradeFee as decimal(38)) as trade_fee_amount_raw + ,contract_address as project_contract_address + from {{ source('collectionswap_ethereum','CollectionPool_evt_SwapNFTInPool') }} e + {% if is_incremental() %} + WHERE evt_block_time >= date_trunc("day", now() - interval '1 week') + {% else %} + WHERE evt_block_time >= '{{project_start_date}}' + {% endif %} + ) + ) +), + +base_trades as ( + select + t.*, + p.nft_contract_address, + p.token_address as currency_contract + from raw_trades t + left join {{ ref('collectionswap_ethereum_pools') }} p + on t.project_contract_address = p.pool_address +) + +-- results +SELECT + date_trunc('day',block_time ) as block_date +, block_time +, block_number +, tx_hash +, project_contract_address +, buyer +, seller +, nft_contract_address +, nft_token_id +, nft_amount +, trade_type +, trade_category +, currency_contract +, cast(price_raw as decimal(38)) as price_raw +, cast(platform_fee_amount_raw as decimal(38)) as platform_fee_amount_raw +, cast(royalty_fee_amount_raw as decimal(38)) as royalty_fee_amount_raw +, cast(null as varchar(1)) as platform_fee_address +, royalty_fee_address +, sub_tx_trade_id +FROM base_trades + + diff --git a/models/_sector/nft/trades/ethereum/platforms/cryptopunks_ethereum_base_trades.sql b/models/_sector/nft/trades/ethereum/platforms/cryptopunks_ethereum_base_trades.sql new file mode 100644 index 00000000000..fef1beb1847 --- /dev/null +++ b/models/_sector/nft/trades/ethereum/platforms/cryptopunks_ethereum_base_trades.sql @@ -0,0 +1,62 @@ +{{ config( + schema = 'cryptopunks_ethereum', + alias ='base_trades', + partition_by = ['block_date'], + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} + + +with accepted_bid_prices as ( + select + call_block_number + ,call_tx_hash + ,call.punkIndex + ,max_by(bid.value, evt_block_number) as latest_bid + ,max_by(bid.fromAddress, evt_block_number) as latest_bidder + from {{ source('cryptopunks_ethereum','CryptoPunksMarket_call_acceptBidForPunk')}} call + left join {{ source('cryptopunks_ethereum','CryptoPunksMarket_evt_PunkBidEntered') }} bid + on call_success + and call.call_block_number >= bid.evt_block_number + and call.punkIndex = bid.punkIndex + WHERE call_success + {% if is_incremental() %} + AND call.call_block_time >= date_trunc("day", now() - interval '1 week') + {% endif %} + group by 1,2,3 +) + +select date_trunc('day',evt.evt_block_time) as block_date + , evt.evt_block_time as block_time + , evt.evt_block_number as block_number + , evt.evt_tx_hash as tx_hash + , evt.contract_address as project_contract_address + , evt.evt_index as sub_tx_trade_id + , case when call.latest_bid is null + then 'Buy' + else 'Bid accepted' end as trade_category + , 'secondary' as trade_type + , coalesce(call.latest_bidder,evt.toAddress) as buyer + , evt.fromAddress as seller + , evt.punkIndex as nft_token_id + , 1 as nft_amount + , evt.contract_address as nft_contract_address + , cast(coalesce(call.latest_bid, evt.value) as DECIMAL(38)) as price_raw + , '{{ var("ETH_ERC20_ADDRESS") }}' AS currency_contract -- all trades are in ETH + , cast(0 as DECIMAL(38)) as platform_fee_amount_raw + , cast(0 as DECIMAL(38)) as royalty_fee_amount_raw + , cast(null as VARCHAR(1)) as platform_fee_address + , cast(null as VARCHAR(1)) as royalty_fee_address +from {{ source('cryptopunks_ethereum','CryptoPunksMarket_evt_PunkBought') }} evt +left join accepted_bid_prices call +on evt.evt_block_number = call.call_block_number + and evt.evt_tx_hash = call.call_tx_hash + and evt.punkIndex = call.punkIndex +where evt.evt_tx_hash not in ('0x92488a00dfa0746c300c66a716e6cc11ba9c0f9d40d8c58e792cc7fcebf432d0' -- flash loan https://twitter.com/cryptopunksnfts/status/1453903818308083720 + ) +{% if is_incremental() %} +and evt.evt_block_time >= date_trunc("day", now() - interval '1 week') +{% endif %} diff --git a/models/_sector/nft/trades/ethereum/platforms/looksrare_v1_ethereum_base_trades.sql b/models/_sector/nft/trades/ethereum/platforms/looksrare_v1_ethereum_base_trades.sql new file mode 100644 index 00000000000..cb2c50a31c0 --- /dev/null +++ b/models/_sector/nft/trades/ethereum/platforms/looksrare_v1_ethereum_base_trades.sql @@ -0,0 +1,122 @@ +{{ config( + schema = 'looksrare_v1_ethereum', + alias ='base_trades', + partition_by = ['block_date'], + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} + +WITH looksrare_trades AS ( + SELECT * + , ROW_NUMBER() OVER (PARTITION BY tx_hash, nft_contract_address, nft_token_id ORDER BY evt_index ASC) AS id + FROM ( + SELECT ta.evt_block_time AS block_time + , ta.tokenId AS nft_token_id + , ta.amount AS nft_amount + , CASE WHEN ta.strategy='0x58d83536d3efedb9f7f2a1ec3bdaad2b1a4dd98c' THEN 'Private Sale' ELSE 'Buy' END AS trade_category + , ta.maker AS seller + , ta.taker AS buyer + , ta.price AS price_raw + , ta.currency AS currency_contract + , ta.collection AS nft_contract_address + , ta.contract_address AS project_contract_address + , ta.evt_tx_hash AS tx_hash + , ta.evt_block_number AS block_number + , ta.evt_index + , ta.strategy + FROM {{ source('looksrare_ethereum','LooksRareExchange_evt_TakerAsk') }} ta + {% if is_incremental() %} + WHERE ta.evt_block_time >= date_trunc("day", NOW() - interval '1 week') + {% endif %} + + UNION ALL + + SELECT tb.evt_block_time AS block_time + , tb.tokenId AS nft_token_id + , tb.amount AS nft_amount + , CASE WHEN tb.strategy='0x58d83536d3efedb9f7f2a1ec3bdaad2b1a4dd98c' THEN 'Private Sale' ELSE 'Offer Accepted' END AS trade_category + , tb.maker AS seller + , tb.taker AS buyer + , tb.price AS price_raw + , tb.currency AS currency_contract + , tb.collection AS nft_contract_address + , tb.contract_address AS project_contract_address + , tb.evt_tx_hash AS tx_hash + , tb.evt_block_number AS block_number + , tb.evt_index + , tb.strategy + FROM {{ source('looksrare_ethereum','LooksRareExchange_evt_TakerBid') }} tb + {% if is_incremental() %} + WHERE tb.evt_block_time >= date_trunc("day", NOW() - interval '1 week') + {% endif %} + ) + ) + +, royalties AS ( + SELECT evt_block_time AS block_time + , evt_tx_hash AS tx_hash + , evt_index + , collection AS nft_contract_address + , tokenId AS nft_token_id + , amount + , royaltyRecipient + , ROW_NUMBER() OVER (PARTITION BY evt_tx_hash, collection, tokenId ORDER BY evt_index ASC) AS id + FROM {{ source('looksrare_ethereum','LooksRareExchange_evt_RoyaltyPayment') }} + {% if is_incremental() %} + WHERE evt_block_time >= date_trunc("day", NOW() - interval '1 week') + {% endif %} + ) + +, platform_fees AS ( + SELECT distinct contract_address + , output_0/100 AS fee_percentage + FROM {{ source('looksrare_ethereum','StrategyStandardSaleForFixedPrice_call_viewProtocolFee') }} + UNION ALL + SELECT distinct contract_address + , output_0/100 AS fee_percentage + FROM {{ source('looksrare_ethereum','StrategyAnyItemFromCollectionForFixedPrice_call_viewProtocolFee') }} + UNION ALL + SELECT distinct contract_address + , output_0/100 AS fee_percentage + FROM {{ source('looksrare_ethereum','StrategyPrivateSale_call_viewProtocolFee') }} + UNION ALL + SELECT distinct contract_address + , output_0/100 AS fee_percentage + FROM {{ source('looksrare_ethereum','StrategyStandardSaleForFixedPriceV1B_call_viewProtocolFee') }} + UNION ALL + SELECT distinct contract_address + , output_0/100 AS fee_percentage + FROM {{ source('looksrare_ethereum','StrategyAnyItemFromCollectionForFixedPriceV1B_call_viewProtocolFee') }} + ) + + +SELECT + date_trunc('day', lr.block_time) AS block_date +, lr.block_time +, lr.block_number +, lr.tx_hash +, lr.project_contract_address +, lr.trade_category +, 'secondary' as trade_type +, lr.nft_contract_address +, lr.nft_token_id +, lr.nft_amount +, lr.buyer +, lr.seller +, lr.currency_contract +, CAST(lr.price_raw AS DECIMAL(38,0)) AS price_raw +, CAST(COALESCE((pf.fee_percentage/100)*lr.price_raw, 0) as DECIMAL(38,0)) AS platform_fee_amount_raw +, CAST(COALESCE(roy.amount, 0) AS DECIMAL(38,0)) AS royalty_fee_amount_raw +, cast(null as varchar(1)) as platform_fee_address +, roy.royaltyRecipient AS royalty_fee_address +, lr.evt_index AS sub_tx_trade_id +FROM looksrare_trades lr +LEFT JOIN royalties roy ON roy.block_time=lr.block_time + AND roy.tx_hash=lr.tx_hash + AND roy.nft_contract_address=lr.nft_contract_address + AND roy.nft_token_id=lr.nft_token_id + AND roy.id = lr.id +LEFT JOIN platform_fees pf ON pf.contract_address=lr.strategy diff --git a/models/_sector/nft/trades/ethereum/platforms/looksrare_v2_ethereum_base_trades.sql b/models/_sector/nft/trades/ethereum/platforms/looksrare_v2_ethereum_base_trades.sql new file mode 100644 index 00000000000..4c419cbf258 --- /dev/null +++ b/models/_sector/nft/trades/ethereum/platforms/looksrare_v2_ethereum_base_trades.sql @@ -0,0 +1,86 @@ +{{ config( + schema = 'looksrare_v2_ethereum', + alias ='base_trades', + partition_by = ['block_date'], + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} + +{% set looksrare_v2_start_date = '2023-04-01' %} + +WITH looksrare_v2_trades AS ( + SELECT l.evt_block_time AS block_time + , l.evt_block_number AS block_number + , 'Offer Accepted' AS trade_category + , l.feeAmounts[0]+l.feeAmounts[1]+l.feeAmounts[2] AS price_raw + , l.askUser AS seller + , l.bidUser AS buyer + , l.collection AS nft_contract_address + , element_at(l.amounts, 1) AS nft_amount + , l.currency + , l.itemIds[0] AS nft_token_id + , l.contract_address AS project_contract_address + , l.evt_tx_hash AS tx_hash + , l.evt_index + , l.feeAmounts[1] AS royalty_fee_amount_raw + , l.feeAmounts[2] AS platform_fee_amount_raw + , CASE WHEN l.feeRecipients[1]!='0x0000000000000000000000000000000000000000' THEN l.feeRecipients[1] END AS royalty_fee_address + , get_json_object(l.nonceInvalidationParameters, '$.orderHash') AS order_hash + FROM {{ source('looksrare_v2_ethereum','LooksRareProtocol_evt_TakerAsk') }} l + {% if is_incremental() %} + WHERE l.evt_block_time >= date_trunc("day", now() - interval '1 week') + {% else %} + WHERE l.evt_block_time >= '{{looksrare_v2_start_date}}' + {% endif %} + + UNION ALL + + SELECT l.evt_block_time AS block_time + , l.evt_block_number AS block_number + , 'Buy' AS trade_category + , l.feeAmounts[0]+l.feeAmounts[1]+l.feeAmounts[2] AS price_raw + , l.feeRecipients[0] AS seller + , l.bidUser AS buyer + , l.collection AS nft_contract_address + , element_at(l.amounts, 1) AS nft_amount + , l.currency + , l.itemIds[0] AS nft_token_id + , l.contract_address AS project_contract_address + , l.evt_tx_hash AS tx_hash + , l.evt_index + , l.feeAmounts[1] AS royalty_fee_amount_raw + , l.feeAmounts[2] AS platform_fee_amount_raw + , CASE WHEN l.feeRecipients[1]!='0x0000000000000000000000000000000000000000' THEN l.feeRecipients[1] END AS royalty_fee_address + , get_json_object(l.nonceInvalidationParameters, '$.orderHash') AS order_hash + FROM {{ source('looksrare_v2_ethereum','LooksRareProtocol_evt_TakerBid') }} l + {% if is_incremental() %} + WHERE l.evt_block_time >= date_trunc("day", now() - interval '1 week') + {% else %} + WHERE l.evt_block_time >= '{{looksrare_v2_start_date}}' + {% endif %} + ) + +SELECT + date_trunc('day', block_time) AS block_date +, block_time +, block_number +, tx_hash +, project_contract_address +, nft_contract_address +, nft_token_id +, nft_amount +, trade_category +, 'secondary' AS trade_type +, buyer +, seller +, currency AS currency_contract +, CAST(price_raw as DECIMAL(38,0)) as price_raw +, CAST(platform_fee_amount_raw as DECIMAL(38,0)) as platform_fee_amount_raw +, CAST(royalty_fee_amount_raw as DECIMAL(38,0)) as royalty_fee_amount_raw +, royalty_fee_address +, CAST(null as VARCHAR(1)) as platform_fee_address +, evt_index as sub_tx_trade_id +FROM looksrare_v2_trades diff --git a/models/_sector/nft/trades/ethereum/platforms/sudoswap_ethereum_base_trades.sql b/models/_sector/nft/trades/ethereum/platforms/sudoswap_ethereum_base_trades.sql new file mode 100644 index 00000000000..3358e25e2a1 --- /dev/null +++ b/models/_sector/nft/trades/ethereum/platforms/sudoswap_ethereum_base_trades.sql @@ -0,0 +1,270 @@ +{{ config( + schema = 'sudoswap_ethereum', + alias ='base_trades', + partition_by = ['block_date'], + materialized = 'incremental', + file_format = 'delta', + incremental_strategy = 'merge', + unique_key = ['block_number','tx_hash','sub_tx_trade_id'], + ) +}} +--base table CTEs +WITH + pairs_created as ( + SELECT + _nft as nftcontractaddress + , _initialNFTIDs as nft_ids + , _fee as initialfee + , _assetRecipient as asset_recip + , output_pair as pair_address + , call_block_time as block_time + , contract_address as protocolfee_recipient -- the factory used to create the pair is the protocol fee recipient + FROM {{ source('sudo_amm_ethereum','LSSVMPairFactory_call_createPairETH') }} + WHERE call_success + ) + + , swaps as ( + SELECT + * + FROM ( + SELECT + contract_address + , call_tx_hash + , call_trace_address + , call_block_time + , call_block_number + , call_success + , tokenRecipient as trade_recipient + , 'Sell' as trade_category + , isRouter as called_from_router + , routerCaller as router_caller + FROM {{ source('sudo_amm_ethereum','LSSVMPair_general_call_swapNFTsForToken') }} + WHERE call_success = true + {% if is_incremental() %} + -- this filter will only be applied on an incremental run. We only want to update with new swaps. + AND call_block_time >= date_trunc("day", now() - interval '1 week') + {% endif %} + + UNION ALL + SELECT + contract_address + , call_tx_hash + , call_trace_address + , call_block_time + , call_block_number + , call_success + , nftRecipient as trade_recipient + , 'Buy' as trade_category + , isRouter as called_from_router + , routerCaller as router_caller + FROM {{ source('sudo_amm_ethereum','LSSVMPair_general_call_swapTokenForAnyNFTs') }} + WHERE call_success = true + {% if is_incremental() %} + -- this filter will only be applied on an incremental run. We only want to update with new swaps. + AND call_block_time >= date_trunc("day", now() - interval '1 week') + {% endif %} + + UNION ALL + SELECT + contract_address + , call_tx_hash + , call_trace_address + , call_block_time + , call_block_number + , call_success + , nftRecipient as trade_recipient + , 'Buy' as trade_category + , isRouter as called_from_router + , routerCaller as router_caller + FROM {{ source('sudo_amm_ethereum','LSSVMPair_general_call_swapTokenForSpecificNFTs') }} + WHERE call_success = true + {% if is_incremental() %} + -- this filter will only be applied on an incremental run. We only want to update with new swaps. + AND call_block_time >= date_trunc("day", now() - interval '1 week') + {% endif %} + ) s + ) + + -- this join should be removed in the future when more call trace info is added to the _call_ tables, we need the call_from field to track down the eth traces. + , swaps_with_calldata as ( + select s.* + , tr.from as call_from + , CASE WHEN called_from_router = true THEN tr.from ELSE tr.to END as project_contract_address -- either the router or the pool if called directly + from swaps s + inner join {{ source('ethereum', 'traces') }} tr + ON tr.success and s.call_block_number = tr.block_number and s.call_tx_hash = tr.tx_hash and s.call_trace_address = tr.trace_address + {% if is_incremental() %} + -- this filter will only be applied on an incremental run. We only want to update with new swaps. + AND tr.block_time >= date_trunc("day", now() - interval '1 week') + {% else %} + AND tr.block_time >= '2022-4-1' + {% endif %} + ) + + + ,pool_fee_update as ( + SELECT + * + FROM {{ source('sudo_amm_ethereum','LSSVMPair_general_evt_FeeUpdate') }} + ) + + ,protocol_fee_update as ( + SELECT + * + FROM {{ source('sudo_amm_ethereum','LSSVMPairFactory_evt_ProtocolFeeMultiplierUpdate') }} + ) + + ,asset_recipient_update as ( + SELECT + * + FROM {{ source('sudo_amm_ethereum','LSSVMPair_general_evt_AssetRecipientChange') }} + ) + +--logic CTEs + ,swaps_w_fees as ( + SELECT + * + FROM ( + SELECT + call_tx_hash + , call_block_time + , call_block_number + , contract_address as pair_address + , call_trace_address + , call_from + , router_caller + , pool_fee + , protocolfee + , protocolfee_recipient + , trade_category + , nftcontractaddress + , asset_recip + , trade_recipient + , project_contract_address + , row_number() OVER (partition by call_tx_hash, contract_address, call_trace_address order by fee_update_time desc, protocolfee_update_time desc, asset_recip_update_time desc) as ordering + FROM ( + SELECT + swaps.* + , COALESCE(fu.newfee, pc.initialfee)/1e18 as pool_fee --most recent pool_fee, depends on bonding curve to implement it correctly. See explanation in fee table schema. + , COALESCE(fu.evt_block_time, pc.block_time) as fee_update_time + , pfu.newMultiplier/1e18 as protocolfee --most recent protocolfee, depends on bonding curve to implement it correctly. See explanation in fee table schema. + , pfu.evt_block_time as protocolfee_update_time + , pc.protocolfee_recipient + , pc.nftcontractaddress + , coalesce(aru.a, pc.asset_recip) as asset_recip + , coalesce(aru.evt_block_time, pc.block_time) as asset_recip_update_time + FROM swaps_with_calldata swaps + JOIN pairs_created pc ON pc.pair_address = contract_address --remember swaps from other NFT addresses won't appear! + -- we might need to do these joins separately since we're exploding into a lot of rows.. + -- should not matter a lot since # of changes per pool should be small + LEFT JOIN pool_fee_update fu ON swaps.call_block_time >= fu.evt_block_time AND swaps.contract_address = fu.contract_address + LEFT JOIN protocol_fee_update pfu ON swaps.call_block_time >= pfu.evt_block_time + LEFT JOIN asset_recipient_update aru on swaps.call_block_time >= aru.evt_block_time AND swaps.contract_address = aru.contract_address + ) a + ) b + WHERE ordering = 1 --we want to keep the most recent pool_fee and protocol fee for each individual call (trade) + ) + + ,swaps_w_traces as ( + -- we traces to get NFT and ETH transfer data because sudoswap doesn't emit any data in events for swaps, so we have to piece it together manually based on trace_address. + SELECT + sb.call_block_time + , sb.call_block_number + , sb.trade_category + , SUM( + CASE WHEN sb.trade_category = 'Buy' -- caller buys, AMM sells + THEN ( + CASE WHEN tr.from = sb.call_from THEN value -- amount of ETH payed + WHEN (tr.to = sb.call_from AND sb.call_from != sb.asset_recip) THEN -value --refunds unless the caller is also the asset recipient, no way to discriminate there. + ELSE 0 END) + ELSE ( -- caller sells, AMM buys + CASE WHEN tr.from = sb.pair_address THEN value -- all ETH leaving the pool, nothing should be coming in on a sell. + ELSE 0 END) + END ) as trade_price -- what the buyer paid (incl all fees) + , SUM( + CASE WHEN (tr.to = sb.protocolfee_recipient) THEN value + ELSE 0 END + ) as protocol_fee_amount -- what the buyer paid + , ARRAY_AGG(distinct CASE WHEN substring(input,1,10)='0x42842e0e' THEN bytea2numeric_v3(substring(input,139,64)) END) + as nft_token_id + , sb.call_tx_hash + , sb.trade_recipient + , sb.pair_address + , sb.nftcontractaddress + , sb.pool_fee + , sb.protocolfee + , sb.protocolfee_recipient + , project_contract_address + -- these 2 are used for matching the aggregator address, dropped later + , router_caller + , call_from + FROM swaps_w_fees sb + INNER JOIN {{ source('ethereum', 'traces') }} tr + ON tr.type = 'call' + AND tr.call_type = 'call' + AND success + AND tr.block_number = sb.call_block_number + AND tr.tx_hash = sb.call_tx_hash + AND ( + (cardinality(call_trace_address) != 0 AND call_trace_address = slice(tr.trace_address,1,cardinality(call_trace_address))) --either a normal tx where trace address helps us narrow down which subtraces to look at for ETH transfers or NFT transfers. + OR cardinality(call_trace_address) = 0 -- In this case the swap function was called directly, all traces are thus subtraces of that call (like 0x34a52a94fce15c090cc16adbd6824948c731ecb19a39350633590a9cd163658b). + ) + {% if is_incremental() %} + AND tr.block_time >= date_trunc("day", now() - interval '1 week') + {% endif %} + {% if not is_incremental() %} + AND tr.block_time >= '2022-4-1' + {% endif %} + GROUP BY 1,2,3,7,8,9,10,11,12,13,14,15,16 + ) + + ,swaps_cleaned as ( + SELECT + date_trunc('DAY', call_block_time) AS block_date + , call_block_time as block_time + , call_block_number as block_number + , nft_token_id + , cardinality(nft_token_id) as number_of_items + , 'secondary' as trade_type + , trade_category + , CASE WHEN trade_category = 'Buy' THEN pair_address --AMM is selling if an NFT is being bought + ELSE trade_recipient + END as seller + , CASE WHEN trade_category = 'Sell' THEN pair_address --AMM is buying if an NFT is being sold + ELSE trade_recipient + END as buyer + , trade_price as price_raw + , '{{ var("ETH_ERC20_ADDRESS") }}' as currency_contract --ETH + , nftcontractaddress as nft_contract_address + , project_contract_address -- This is either the router or the pool address if called directly + , call_tx_hash as tx_hash + , protocol_fee_amount as platform_fee_amount_raw + , protocolfee_recipient + -- trade_price = baseprice + (baseprice*pool_fee) + (baseprice*protocolfee) + , (trade_price-protocol_fee_amount)/(1+pool_fee)*pool_fee as pool_fee_amount_raw + FROM swaps_w_traces + ) + +SELECT + block_date + , block_time + , block_number + , tx_hash + , project_contract_address + , buyer + , seller + , nft_contract_address + , explode(nft_token_id) as nft_token_id --nft.trades prefers each token id be its own row + , cast(1 as int) as nft_amount + , trade_type + , trade_category + , currency_contract + , cast(price_raw/number_of_items as DECIMAL(38,0)) as price_raw + , cast(platform_fee_amount_raw/number_of_items as decimal(38)) as platform_fee_amount_raw + , cast(0 as decimal(38)) as royalty_fee_amount_raw + , cast(pool_fee_amount_raw/number_of_items as decimal(38)) as pool_fee_amount_raw + , cast(protocolfee_recipient as VARCHAR(42)) as platform_fee_address + , cast(null as varchar(1)) as royalty_fee_address + , row_number() over (partition by tx_hash order by nft_token_id) as sub_tx_trade_id +FROM swaps_cleaned + diff --git a/models/_sector/nft/trades/nft_ethereum_trades_beta.sql b/models/_sector/nft/trades/nft_ethereum_trades_beta.sql index 58c51cac1dc..095e47c5081 100644 --- a/models/_sector/nft/trades/nft_ethereum_trades_beta.sql +++ b/models/_sector/nft/trades/nft_ethereum_trades_beta.sql @@ -19,6 +19,11 @@ ,('zora', 'v1', ref('zora_v1_ethereum_base_trades')) ,('zora', 'v2', ref('zora_v2_ethereum_base_trades')) ,('zora', 'v3', ref('zora_v3_ethereum_base_trades')) + ,('cryptopunks', 'v1', ref('cryptopunks_ethereum_base_trades')) + ,('sudoswap', 'v1', ref('sudoswap_ethereum_base_trades')) + ,('collectionswap', 'v1', ref('collectionswap_ethereum_base_trades')) + ,('looksrare', 'v1', ref('looksrare_v1_ethereum_base_trades')) + ,('looksrare', 'v2', ref('looksrare_v2_ethereum_base_trades')) ] %} -- We should remove this CTE and include ETH into the general prices table once everything is migrated diff --git a/models/_sector/nft/trades/nft_ethereum_trades_beta_ported.sql b/models/_sector/nft/trades/nft_ethereum_trades_beta_ported.sql new file mode 100644 index 00000000000..ab12091c558 --- /dev/null +++ b/models/_sector/nft/trades/nft_ethereum_trades_beta_ported.sql @@ -0,0 +1,8 @@ +{{ config( + schema = 'nft_ethereum', + alias ='trades_beta_ported', + materialized = 'view' + ) +}} + +{{ port_to_old_schema(ref('nft_ethereum_trades_beta')) }} diff --git a/models/_sector/nft/trades/schema.yml b/models/_sector/nft/trades/schema.yml index aaeeadc612b..2e0b58332c5 100644 --- a/models/_sector/nft/trades/schema.yml +++ b/models/_sector/nft/trades/schema.yml @@ -1,4 +1,5 @@ version: 2 + models: - name: nft_ethereum_trades_beta meta: @@ -275,3 +276,12 @@ models: - *tx_from - *tx_to - *unique_trade_id + + - name: nft_ethereum_trades_beta_ported + meta: + blockchain: ethereum + sector: nft + contributors: 0xRob + config: + tags: ['ethereum', 'nft', 'trades', 'beta'] + description: "backport of the new nft trades model" diff --git a/seeds/_sector/nft/_schema.yml b/seeds/_sector/nft/_schema.yml index 7245be2a600..da3146b5411 100644 --- a/seeds/_sector/nft/_schema.yml +++ b/seeds/_sector/nft/_schema.yml @@ -28,7 +28,7 @@ seeds: price_raw: decimal(38) platform_fee_amount_raw: decimal(38) royalty_fee_amount_raw: decimal(38) - + - name: element_ethereum_base_trades_seed config: column_types: @@ -64,3 +64,26 @@ seeds: platform_fee_amount_raw: decimal(38) royalty_fee_amount_raw: decimal(38) + - name: cryptopunks_ethereum_base_trades_seed + config: + column_types: + price_raw: decimal(38) + platform_fee_amount_raw: decimal(38) + royalty_fee_amount_raw: decimal(38) + + - name: looksrare_v1_ethereum_base_trades_seed + config: + column_types: + price_raw: decimal(38) + platform_fee_amount_raw: decimal(38) + royalty_fee_amount_raw: decimal(38) + nft_token_id: string + + - name: looksrare_v2_ethereum_base_trades_seed + config: + column_types: + price_raw: decimal(38) + platform_fee_amount_raw: decimal(38) + royalty_fee_amount_raw: decimal(38) + nft_token_id: string + diff --git a/seeds/_sector/nft/collectionswap_ethereum_base_trades_seed.csv b/seeds/_sector/nft/collectionswap_ethereum_base_trades_seed.csv new file mode 100644 index 00000000000..8ea9b1a7785 --- /dev/null +++ b/seeds/_sector/nft/collectionswap_ethereum_base_trades_seed.csv @@ -0,0 +1,5 @@ +block_number,tx_hash,sub_tx_trade_id,buyer,seller,nft_contract_address,nft_token_id,price_raw,platform_fee_amount_raw,royalty_fee_amount_raw,description +17061239,0xc686fee30a034f7b877978a020ad410b78a2e51f356593be9d3dbab6936b7497,1,,0xec04a3b0f3a900ea5f24a3374caff08226f16bda,0x32973908faee0bf825a343000fe412ebe56f802a,1388,837400000000000000,0,39500000000000000,SwapNFTOutPool +17062578,0x96792d636025ef3f8062f7a9578991ea9dc7ae8bae1863b48a7228dd8ad00cfd,1,,0xec04a3b0f3a900ea5f24a3374caff08226f16bda,0x32973908faee0bf825a343000fe412ebe56f802a,257,1208400000000000000,0,57000000000000000,SwapNFTOutPool +17062510,0xc343f2b5cdc4375f1cacd1a39279115d4c36f27fd587a3ab8ebbb40fca48f7e7,1,0xe753123d2128508471953fa3cfb833795a7b678d,,0x809d8f2b12454fc07408d2479cf6dc701ecd5a9f,2465,193050000000000000,0,14625000000000000,SwapNFTInPool +17062807,0x964d9aebd63299402a7fa49c19be34ae28c9b61310cb49975285542d97dcc524,1,0xe753123d2128508471953fa3cfb833795a7b678d,,0x809d8f2b12454fc07408d2479cf6dc701ecd5a9f,1063,183150000000000000,0,13875000000000000,SwapNFTInPool diff --git a/seeds/_sector/nft/cryptopunks_ethereum_base_trades_seed.csv b/seeds/_sector/nft/cryptopunks_ethereum_base_trades_seed.csv new file mode 100644 index 00000000000..fd0c3672b68 --- /dev/null +++ b/seeds/_sector/nft/cryptopunks_ethereum_base_trades_seed.csv @@ -0,0 +1,5 @@ +block_number,tx_hash,sub_tx_trade_id,buyer,seller,nft_contract_address,nft_token_id,price_raw,platform_fee_amount_raw,royalty_fee_amount_raw,description +8317762,0xa0c7ee23239ab22f7d555fe42b5e52eec33d03c0960f2497a5e9d079423bf65c,90,0x382681f262e3ab062c89298609372b6ae9d8e52a,0x00d7c902fbbcd3c9db2da80a439c94486c50eb81,0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb,9354,300000000000000000,0,0,"acceptBidForPunk" +14495157,0x7b52628762176e9d578b314ef7cbac807c1744207435196ab64dc201ce6db6ea,100,0x1919db36ca2fa2e15f9000fd9cdc2edcf863e685,0xaaa3f05f25eed87ee3a268f4582ec914e6245577,0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb,6161,67500000000000100001,0,0,"acceptBidForPunk" +16129023,0x8065c3c44b025a71da270253089bcc262db2b810d2a0a3533c983ea420dbf6a0,137,0xbbaec56b725a0b9501a655d7d1b48555af637b70,0x2a193336b79d9462bb36215210d44e9d60878c65,0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb,7294,90000000000000000000,0,0,"buyPunk" +8270569,0x3727ce4fe9d3229339570a5098b70974f76d4d83d4389b075a4389d7854a2ee7,43,0x78f0269f5b1ca914c8c58993f41181f89e212b27,0x53ede7cae3eb6a7d11429fe589c0278c9acbe21a,0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb,2210,520000000000000000,0,0,"buyPunk" diff --git a/seeds/_sector/nft/looksrare_v1_ethereum_base_trades_seed.csv b/seeds/_sector/nft/looksrare_v1_ethereum_base_trades_seed.csv new file mode 100644 index 00000000000..fe64931e2bd --- /dev/null +++ b/seeds/_sector/nft/looksrare_v1_ethereum_base_trades_seed.csv @@ -0,0 +1,5 @@ +block_number,tx_hash,sub_tx_trade_id,buyer,seller,nft_contract_address,nft_token_id,price_raw,platform_fee_amount_raw,royalty_fee_amount_raw,description +16198365,0x4b064cc0e51472995c848c00a2904eb2269ec185b7f4993daa935369981326cd,96,0x7eccb4140751336f85dfc4846347f26b5a8cb84d,0xf8238a3dd9a67b8419412ede613a06d73ffc2d93,0x77dd30fd9471818aebba24bed6d4474190ecad9b,7,10000000000000000,150000000000000,0,TakerAsk +16195833,0xdfeb619c236a623a2f9f7b3ea8085e1f103b74eba96c6400aa1a5fb0c04bdce1,88,0xecef1d16395b731740898ca2c0c5da3a51beae30,0xe9f157f18848fa600bd003e4a81ff98349c9c55c,0xc36cf0cfcb5d905b8b513860db0cfe63f6cf9f5c,24160048051386630905899597127655543013376,180000000000000,2700000000000,900000000000,TakerAsk +16193938,0x75d83af8bcaa34883395698f00799a55952ec3843a8d86fcfdf1d9a8bb2b825b,122,0x882973334aaa97093d6a094c8e59991317e3aee9,0x7d2add1e3bc76a7a40ae52a50b751ec1a83d63a3,0xf1f3ca6268f330fda08418db12171c3173ee39c9,1,2990030000000000,44850450000000,0,TakerBid +16194001,0x5d1ab79efe09cdc5a1dfeab12e6b484930b76acd8229bd332cdc0143c984c01e,231,0x0d148287befe306d11c6da1aa664f5692c9b1273,0x51986993cd20ea3aac47aa46bfeb5b162f9de78f,0xabb3738f04dc2ec20f4ae4462c3d069d02ae045b,22891000,1000000000000000,15000000000000,5000000000000,TakerBid diff --git a/seeds/_sector/nft/looksrare_v2_ethereum_base_trades_seed.csv b/seeds/_sector/nft/looksrare_v2_ethereum_base_trades_seed.csv new file mode 100644 index 00000000000..c50139a37d8 --- /dev/null +++ b/seeds/_sector/nft/looksrare_v2_ethereum_base_trades_seed.csv @@ -0,0 +1,5 @@ +block_number,tx_hash,sub_tx_trade_id,buyer,seller,nft_contract_address,nft_token_id,price_raw,platform_fee_amount_raw,royalty_fee_amount_raw,description +17227718,0x1edb4639e02f97533ae1cf8553ecfb5b0176945df3bc2e2d2b5920490644500b,277,0x5888700be02f52c8adf85890886ef84a6b8a7829,0x317ca097b4546bf40e066df7d74d27c60e7077fa,0xfc2068c3d47b575a60f6a4a7bf60dea0ac368e01,8491,410000000000000000,2050000000000000,0,TakerAsk +17228048,0xc53da549c54d543c0bea77d3acb6521aa4bcf70068194229ed78943f4ef9e413,333,0x81c6686fbe1594d599ac86a0d8e81d84a2f9bcf2,0x06d51314d152ca4f88d691f87b40cf3bf453df7c,0x4ba0be4d8d83b5ca9935d0e0284f707e8f2dd6d1,1,32000000000000000000,160000000000000000,0,TakerAsk +17230836,0x197fbcfc35b4e97423ef5bc5665592b27daa07860c053b1b6879fd98ec31ea5e,77,0x5888700be02f52c8adf85890886ef84a6b8a7829,0x0000008682fa8c3aa14b11894e90e3dcbbff715b,0xfc2068c3d47b575a60f6a4a7bf60dea0ac368e01,7126,410000000000000000,2050000000000000,0,TakerBid +17227260,0xb3b9be3c05ee38485cf877773962fb2e7e9798943a91513b6113830cd25ab132,499,0xa854772db43b52d7b456c2b5a40bd41627b316c2,0xc935aaa23734fce35843829d2a39c3920172a0d6,0x595a8974c1473717c4b5d456350cd594d9bda687,11755,275000000000000000000,1375000000000000000,0,TakerBid diff --git a/seeds/_sector/nft/sudoswap_ethereum_base_trades_seed.csv b/seeds/_sector/nft/sudoswap_ethereum_base_trades_seed.csv new file mode 100644 index 00000000000..7fb35d6ea82 --- /dev/null +++ b/seeds/_sector/nft/sudoswap_ethereum_base_trades_seed.csv @@ -0,0 +1,7 @@ +block_number,tx_hash,sub_tx_trade_id,buyer,seller,nft_contract_address,nft_token_id,price_raw,platform_fee_amount_raw,royalty_fee_amount_raw,description +15354581,0x03b4168904dc5d25d3f35be9653c5f459d5a0c829469cf806bf44377991b2df7,1,0x4bfee8eb04d1df1ef8509a92b211436000e5950c,0xf7bcafade91139b428acd9494767a972ebab2e69,0xf10a71e53398bf4e3cf5e2a0cad3c529ad19b834,199,67600000000000000,338000000000000,0,swapNFTsForToken +15349124,0x044e30a995a3e05ec113450321942e71d6bbd017969bc4a4768c0b69ac29ddb5,1,0x1a4fbd328ed410720f7a53cd26aef307ccf5e0e4,0xbede55bdded9c808c1d0e791abe269e61f20cd84,0x881c822cba3325a8692c37c470d2f9654454df84,3935,5519309296786866,29048996298878,0,swapNFTsForToken +15349608,0x7f34d65b0d65198f3c59796c2691bcd73857b5ec6feeb75369c66982a8454895,1,0xc22630f6e3124eccc8156648973461c30b2f84d1,0x8fb854f52e1773edbd07041195e37c1688996c0e,0x8a3590348d1dae26b38676bc07e26f0d024af368,1670,12859658176722586,63978398889167,0,swapTokenForAnyNFTs +15349608,0x7f34d65b0d65198f3c59796c2691bcd73857b5ec6feeb75369c66982a8454895,2,0xc22630f6e3124eccc8156648973461c30b2f84d1,0x8fb854f52e1773edbd07041195e37c1688996c0e,0x8a3590348d1dae26b38676bc07e26f0d024af368,1669,12859658176722586,63978398889167,0,swapTokenForAnyNFTs +15351515,0x01c9a24ac9e47f00d905bc30aa5c4b912be2839e9005553e9171d69d2b0db4c6,1,0xc6257136f3d07716a2d2027b386b5957e79463ee,0x328a54df862cfb6233277be8666c32f2a2d10235,0xb2df5bde8432c83a8a1919cc610fa9aef5e53348,4611,12607499999999956,59190140845070,0,swapTokenForSpecificNFTs +15354961,0x0dbd29b3695e099047dd83e6f2fbc4775c0df35c13747be1e210c3898924cc75,1,0x34cae1d9e2d014b7b9e6295c66c554d7e79713d3,0xed837564e8b67f55a05c0b91cce1509cf09bc592,0xb5455326c6d00aa75d426f8be044d4efaa201e1a,68,9673800000000000,48128358208955,0,swapTokenForSpecificNFTs diff --git a/tests/_sector/nft/check_backport_columns.sql b/tests/_sector/nft/check_backport_columns.sql new file mode 100644 index 00000000000..8110303a21e --- /dev/null +++ b/tests/_sector/nft/check_backport_columns.sql @@ -0,0 +1,90 @@ +SELECT * FROM ( +SELECT * FROM ( +SELECT + blockchain, + project, + version, + block_date, + block_time, + token_id, + collection, + amount_usd, + token_standard, + trade_type, + number_of_items, + trade_category, + evt_type, + seller, + buyer, + amount_original, + amount_raw, + currency_symbol, + currency_contract, + nft_contract_address, + project_contract_address, + aggregator_name, + aggregator_address, + tx_hash, + block_number, + tx_from, + tx_to, + platform_fee_amount_raw, + platform_fee_amount, + platform_fee_amount_usd, + platform_fee_percentage, + royalty_fee_receive_address, + royalty_fee_currency_symbol, + royalty_fee_amount_raw, + royalty_fee_amount, + royalty_fee_amount_usd, + royalty_fee_percentage, + unique_trade_id +from {{ ref('nft_events') }} +limit 1 +) +union all +SELECT * FROM ( +SELECT + blockchain, + project, + version, + block_date, + block_time, + token_id, + collection, + amount_usd, + token_standard, + trade_type, + number_of_items, + trade_category, + evt_type, + seller, + buyer, + amount_original, + amount_raw, + currency_symbol, + currency_contract, + nft_contract_address, + project_contract_address, + aggregator_name, + aggregator_address, + tx_hash, + block_number, + tx_from, + tx_to, + platform_fee_amount_raw, + platform_fee_amount, + platform_fee_amount_usd, + platform_fee_percentage, + royalty_fee_receive_address, + royalty_fee_currency_symbol, + royalty_fee_amount_raw, + royalty_fee_amount, + royalty_fee_amount_usd, + royalty_fee_percentage, + unique_trade_id +from {{ ref('nft_ethereum_trades_beta_ported') }} +limit 1 +) +) +WHERE 1=0 diff --git a/tests/_sector/nft/check_nft_migrations_ethereum.sql b/tests/_sector/nft/check_nft_migrations_ethereum.sql index c7d85c1618d..bf28d8df07d 100644 --- a/tests/_sector/nft/check_nft_migrations_ethereum.sql +++ b/tests/_sector/nft/check_nft_migrations_ethereum.sql @@ -32,15 +32,15 @@ WITH migrated as ( ,mig_total_amount ,ref_total_amount - ,abs((mig_total_amount - ref_total_amount)/ref_total_amount) < 0.0005 as check_amount + ,abs((mig_total_amount - ref_total_amount)/ref_total_amount) < 0.001 as check_amount ,mig_total_platform_amount ,ref_total_platform_amount - ,abs((mig_total_platform_amount - ref_total_platform_amount)/ref_total_platform_amount) < 0.0005 as check_platform_amount + ,abs((mig_total_platform_amount - ref_total_platform_amount)/ref_total_platform_amount) < 0.001 as check_platform_amount ,mig_total_royalty_amount ,ref_total_royalty_amount - ,abs((mig_total_royalty_amount - ref_total_royalty_amount)/ref_total_royalty_amount) < 0.0005 as check_royalty_amount + ,abs((mig_total_royalty_amount - ref_total_royalty_amount)/ref_total_royalty_amount) < 0.001 as check_royalty_amount from migrated mig inner join reference ref on mig.project = ref.project and mig.project_version = ref.project_version