diff --git a/src/transformers/ethereum/assetTransfersCryptopunks.spec.ts b/src/transformers/ethereum/assetTransfersCryptopunks.spec.ts index fc1f84d..f7cbcfe 100644 --- a/src/transformers/ethereum/assetTransfersCryptopunks.spec.ts +++ b/src/transformers/ethereum/assetTransfersCryptopunks.spec.ts @@ -129,4 +129,31 @@ describe('transactionAssetTransfersCryptopunks', () => { expect(cryptoPunksTransfers[1].type).toBe('erc721'); } }); + + it('should return asset transfers for CryptoPunks assign transactions', () => { + const cryptoPunksBlock1 = loadBlockFixture('ethereum', '3846659_decoded'); + const cryptoPunksAssetResult1 = + transactionAssetTransfers(cryptoPunksBlock1); + const cryptoPunksResult1 = transform(cryptoPunksAssetResult1); + const cryptoPunksTx1 = cryptoPunksResult1.transactions.find( + (tx) => + tx.hash === + '0xd7eecc44abcea1a4c9dbd7d7749595635f5dcf8d1795beef52ca36356be6201c', + ); + expect(cryptoPunksTx1).toBeDefined(); + if (cryptoPunksTx1) { + const cryptoPunksTransfers = cryptoPunksTx1.assetTransfers; + expect(cryptoPunksTransfers.length).toBe(1); + if ('tokenId' in cryptoPunksTransfers[0]) { + expect(cryptoPunksTransfers[0].tokenId).toBe('5350'); + expect(cryptoPunksTransfers[0].from).toBe( + '0x0000000000000000000000000000000000000000', + ); + expect(cryptoPunksTransfers[0].to).toBe( + '0x5b098b00621eda6a96b7a476220661ad265f083f', + ); + } + expect(cryptoPunksTransfers[0].type).toBe('erc721'); + } + }); }); diff --git a/src/transformers/ethereum/assetTransfersCryptopunks.ts b/src/transformers/ethereum/assetTransfersCryptopunks.ts index 91031c4..b3da910 100644 --- a/src/transformers/ethereum/assetTransfersCryptopunks.ts +++ b/src/transformers/ethereum/assetTransfersCryptopunks.ts @@ -5,7 +5,10 @@ import { type RawBlock, type RawTransaction, } from '../../types'; -import { CRYPTO_PUNKS_ADDRESSES } from '../../helpers/constants'; +import { + CRYPTO_PUNKS_ADDRESSES, + KNOWN_ADDRESSES, +} from '../../helpers/constants'; const TRANSFER_SIGNATURES = { // event PunkTransfer(address indexed from, address indexed to, uint256 punkIndex) @@ -14,6 +17,9 @@ const TRANSFER_SIGNATURES = { // event PunkBought(uint indexed punkIndex, uint value, address indexed fromAddress, address indexed toAddress) CRYPTO_PUNKS_ERC721_BUY: '0x58e5d5a525e3b40bc15abaa38b5882678db1ee68befd2f60bafe3a7fd06db9e3', + // Assign (index_topic_1 address to, uint256 punkIndex) + CRYPTO_PUNKS_ERC721_ASSIGN: + '0x8a0e37b73a0d9c82e205d4d1a3ff3d0b57ce5f4d7bccf6bac03336dc101cb7ba', }; function updateTokenTransfers(tx: RawTransaction) { @@ -45,17 +51,30 @@ function updateTokenTransfers(tx: RawTransaction) { type: AssetType.ERC721, }); break; + case TRANSFER_SIGNATURES.CRYPTO_PUNKS_ERC721_ASSIGN: + if (log.address === KNOWN_ADDRESSES.CryptoPunksOld) { + cryptopunksTransfers.push({ + asset: log.address, + from: KNOWN_ADDRESSES.NULL, + to: decodeEVMAddress(log.topics[1]), + tokenId: BigInt(log.data).toString(), + type: AssetType.ERC721, + }); + } + break; default: break; } } // filter old asset transfers from previous asset transfers - const nonOldAssetTransfers = tx.assetTransfers.filter( - (assetTransfer) => - assetTransfer.type !== AssetType.ETH && - !CRYPTO_PUNKS_ADDRESSES.includes(assetTransfer.asset), - ); + const nonOldAssetTransfers = tx.assetTransfers + ? tx.assetTransfers.filter( + (assetTransfer) => + assetTransfer.type !== AssetType.ETH && + !CRYPTO_PUNKS_ADDRESSES.includes(assetTransfer.asset), + ) + : []; const assetTransfers = [...nonOldAssetTransfers, ...cryptopunksTransfers]; return assetTransfers; @@ -63,11 +82,11 @@ function updateTokenTransfers(tx: RawTransaction) { export function transform(block: RawBlock): RawBlock { block.transactions = block.transactions.map((tx) => { - const hasCryptopunksTransfer = tx.assetTransfers?.some( - (assetTransfer) => - assetTransfer.type !== AssetType.ETH && - CRYPTO_PUNKS_ADDRESSES.includes(assetTransfer.asset), + const logs = tx.receipt.logs; + const hasCryptopunksTransfer = logs?.some((log) => + CRYPTO_PUNKS_ADDRESSES.includes(log.address), ); + if (hasCryptopunksTransfer) { tx.assetTransfers = updateTokenTransfers(tx); }