diff --git a/packages/worker/src/transfer/extractHandlers/transfer/default.handler.spec.ts b/packages/worker/src/transfer/extractHandlers/transfer/default.handler.spec.ts index 20c96ec742..579e25ef74 100644 --- a/packages/worker/src/transfer/extractHandlers/transfer/default.handler.spec.ts +++ b/packages/worker/src/transfer/extractHandlers/transfer/default.handler.spec.ts @@ -123,18 +123,32 @@ describe("defaultTransferHandler", () => { expect(result.isFeeOrRefund).toBe(true); }); - it("extracts transfer of refund type if from address is a bootloader address", () => { + it("extracts transfer of refund type if from address is a bootloader address and there are transaction details", () => { + const transactionDetails = mock(); log.topics[1] = "0x0000000000000000000000000000000000000000000000000000000000008001"; - const result = defaultTransferHandler.extract(log, blockDetails); + const result = defaultTransferHandler.extract(log, blockDetails, transactionDetails); expect(result.type).toBe(TransferType.Refund); }); - it("adds isFeeOrRefund as true if from address is a bootloader address", () => { + it("extracts transfer of transfer type if from address is a bootloader address and there are no transaction details", () => { log.topics[1] = "0x0000000000000000000000000000000000000000000000000000000000008001"; const result = defaultTransferHandler.extract(log, blockDetails); + expect(result.type).toBe(TransferType.Transfer); + }); + + it("adds isFeeOrRefund as true if from address is a bootloader address and there are transaction details", () => { + const transactionDetails = mock(); + log.topics[1] = "0x0000000000000000000000000000000000000000000000000000000000008001"; + const result = defaultTransferHandler.extract(log, blockDetails, transactionDetails); expect(result.isFeeOrRefund).toBe(true); }); + it("adds isFeeOrRefund as false if from address is a bootloader address and there are no transaction details", () => { + log.topics[1] = "0x0000000000000000000000000000000000000000000000000000000000008001"; + const result = defaultTransferHandler.extract(log, blockDetails); + expect(result.isFeeOrRefund).toBe(false); + }); + it("extracts transfer of transfer type if neither to address nor from address is a bootload address", () => { const result = defaultTransferHandler.extract(log, blockDetails); expect(result.type).toBe(TransferType.Transfer); diff --git a/packages/worker/src/transfer/extractHandlers/transfer/default.handler.ts b/packages/worker/src/transfer/extractHandlers/transfer/default.handler.ts index e14f386a1c..1762bc2df8 100644 --- a/packages/worker/src/transfer/extractHandlers/transfer/default.handler.ts +++ b/packages/worker/src/transfer/extractHandlers/transfer/default.handler.ts @@ -19,7 +19,10 @@ export const defaultTransferHandler: ExtractTransferHandler = { let transferType: TransferType = TransferType.Transfer; if (parsedLog.args.to === utils.BOOTLOADER_FORMAL_ADDRESS) { transferType = TransferType.Fee; - } else if (parsedLog.args.from === utils.BOOTLOADER_FORMAL_ADDRESS) { + } + // if transactionDetails is null it means that this transfer comes from a block with + // no transactions and it is a reward to an operator address, so it's a transfer and not a refund + else if (parsedLog.args.from === utils.BOOTLOADER_FORMAL_ADDRESS && transactionDetails) { transferType = TransferType.Refund; } diff --git a/packages/worker/src/transfer/transfer.service.spec.ts b/packages/worker/src/transfer/transfer.service.spec.ts index 682e70ad48..fe5bc10411 100644 --- a/packages/worker/src/transfer/transfer.service.spec.ts +++ b/packages/worker/src/transfer/transfer.service.spec.ts @@ -53,6 +53,7 @@ import * as addressOutOfRange from "../../test/transactionReceipts/address-out-o import * as logParsingError from "../../test/transactionReceipts/log-parsing-error.json"; import * as noDepositAfterFee from "../../test/transactionReceipts/no-deposit-after-fee.json"; import * as feeWithNoDeposits from "../../test/transactionReceipts/fee-with-no-deposits.json"; +import * as blockWithNoTxsLogs from "../../test/logs/block-with-no-txs-logs.json"; jest.mock("../logger", () => ({ default: { @@ -2285,5 +2286,35 @@ describe("TransferService", () => { expect(result).toStrictEqual(expectedTransfers); }); }); + + describe("block with no transactions", () => { + it("properly saves transfers", async () => { + const blockDate = new Date(); + blockDetails.timestamp = blockDate.getTime() / 1000; + + const expectedTransfers = [ + { + amount: BigNumber.from("0xf22ec29c9c4980"), + blockNumber: 6711853, + from: "0x0000000000000000000000000000000000008001", + isFeeOrRefund: false, + isInternal: true, + logIndex: 0, + timestamp: blockDate, + to: "0xa9232040bf0e0aea2578a5b2243f2916dbfc0a69", + tokenAddress: "0x000000000000000000000000000000000000800a", + tokenType: "ETH", + transactionHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + transactionIndex: 0, + type: "transfer", + }, + ]; + + const result = await transferService.saveTransfers(blockWithNoTxsLogs, blockDetails); + expect(transferRepositoryMock.addMany).toHaveBeenCalledTimes(1); + expect(transferRepositoryMock.addMany).toHaveBeenCalledWith(expectedTransfers); + expect(result).toStrictEqual(expectedTransfers); + }); + }); }); });