Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
Unique,
Index,
CreateDateColumn,
DeleteDateColumn,
} from "typeorm";

@Entity({ schema: "evm" })
@Unique("UK_fallback_hyper_evm_flow_completed_chain_block_tx_log", [
"chainId",
"blockNumber",
"transactionHash",
"logIndex",
])
@Index("IX_fallback_hyper_evm_flow_completed_chainId", ["chainId"])
@Index("IX_fallback_hyper_evm_flow_completed_quoteNonce", ["quoteNonce"])
@Index("IX_fallback_hyper_evm_flow_completed_blockNumber", ["blockNumber"])
@Index("IX_fallback_hyper_evm_flow_completed_blockTimeStamp", [
"blockTimestamp",
])
@Index("IX_fallback_hyper_evm_flow_completed_deletedAt", ["deletedAt"])
@Index("IX_fallback_hyper_evm_flow_completed_finalised", ["finalised"])
export class FallbackHyperEVMFlowCompleted {
@PrimaryGeneratedColumn()
id: number;

@Column({ type: "bigint" })
chainId: string;

@Column({ nullable: true })
quoteNonce: string;

@Column({ type: "varchar" })
finalRecipient: string;

@Column({ type: "varchar" })
finalToken: string;

@Column({ type: "numeric" })
evmAmountIn: string;

@Column({ type: "numeric" })
bridgingFeesIncurred: string;

@Column({ type: "numeric" })
evmAmountSponsored: string;

@Column()
blockNumber: number;

@Column()
transactionHash: string;

@Column()
transactionIndex: number;

@Column()
logIndex: number;

@Column("boolean")
finalised: boolean;

@Column()
blockTimestamp: Date;

@CreateDateColumn()
createdAt: Date;

@DeleteDateColumn({ nullable: true })
deletedAt?: Date;
}
1 change: 1 addition & 0 deletions packages/indexer-database/src/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ export * from "./evm/SponsoredOFTSend";
// HyperEVM
export * from "./evm/SimpleTransferFlowCompleted";
export * from "./evm/ArbitraryActionsExecuted";
export * from "./evm/FallbackHyperEVMFlowCompleted";
1 change: 1 addition & 0 deletions packages/indexer-database/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const createDataSource = (config: DatabaseConfig): DataSource => {
// HyperEVM
entities.SimpleTransferFlowCompleted,
entities.ArbitraryActionsExecuted,
entities.FallbackHyperEVMFlowCompleted,
],
migrationsTableName: "_migrations",
migrations: ["migrations/*.ts"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class FallbackHyperEVMFlowCompleted1762818039419
implements MigrationInterface
{
name = "FallbackHyperEVMFlowCompleted1762818039419";

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "evm"."fallback_hyper_evm_flow_completed" (
"id" SERIAL NOT NULL,
"chainId" bigint NOT NULL,
"quoteNonce" character varying,
"finalRecipient" character varying NOT NULL,
"finalToken" character varying NOT NULL,
"evmAmountIn" numeric NOT NULL,
"bridgingFeesIncurred" numeric NOT NULL,
"evmAmountSponsored" numeric NOT NULL,
"blockNumber" integer NOT NULL,
"transactionHash" character varying NOT NULL,
"transactionIndex" integer NOT NULL,
"logIndex" integer NOT NULL,
"finalised" boolean NOT NULL,
"blockTimestamp" TIMESTAMP NOT NULL,
"createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deletedAt" TIMESTAMP,
CONSTRAINT "PK_fallback_hyper_evm_flow_completed" PRIMARY KEY ("id"),
CONSTRAINT "UK_fallback_hyper_evm_flow_completed_chain_block_tx_log" UNIQUE ("chainId", "blockNumber", "transactionHash", "logIndex")
)`,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_chainId" ON "evm"."fallback_hyper_evm_flow_completed" ("chainId") `,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_quoteNonce" ON "evm"."fallback_hyper_evm_flow_completed" ("quoteNonce") `,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_blockNumber" ON "evm"."fallback_hyper_evm_flow_completed" ("blockNumber") `,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_finalised" ON "evm"."fallback_hyper_evm_flow_completed" ("finalised") `,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_blockTimestamp" ON "evm"."fallback_hyper_evm_flow_completed" ("blockTimestamp") `,
);
await queryRunner.query(
`CREATE INDEX "IX_fallback_hyper_evm_flow_completed_deletedAt" ON "evm"."fallback_hyper_evm_flow_completed" ("deletedAt") `,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_deletedAt"`,
);
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_blockTimestamp"`,
);
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_blockNumber"`,
);
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_quoteNonce"`,
);
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_finalised"`,
);
await queryRunner.query(
`DROP INDEX "evm"."IX_fallback_hyper_evm_flow_completed_chainId"`,
);
await queryRunner.query(
`DROP TABLE "evm"."fallback_hyper_evm_flow_completed"`,
);
}
}
19 changes: 10 additions & 9 deletions packages/indexer/src/data-indexing/model/hyperEvmExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ export interface ArbitraryActionsExecutedLog extends providers.Log {
};
}

// Taken from https://testnet.purrsec.com/tx/0x1bf0dc091249341d0e91380b1c1d7dca683ab1b6773f7fb011b71a3d017a8fc9
export const HYPERCORE_FLOW_EXECUTOR_ADDRESS: { [key: number]: string } = {
[CHAIN_IDs.HYPEREVM_TESTNET]: "0x06C61D54958a0772Ee8aF41789466d39FfeaeB13",
};

// Taken from https://hyperevmscan.io/tx/0x869d1df5f1e7b6b91a824d8e2b455ac48d1f26f0b5f2823c96df391eb75dff34#eventlog#8
export const ARBITRARY_EVM_FLOW_EXECUTOR_ADDRESS: { [key: number]: string } = {
[CHAIN_IDs.HYPEREVM]: "0x7B164050BBC8e7ef3253e7db0D74b713Ba3F1c95",
};
export interface FallbackHyperEVMFlowCompletedLog extends providers.Log {
args: {
quoteNonce: string;
finalRecipient: string;
finalToken: string;
evmAmountIn: BigNumber;
bridgingFeesIncurred: BigNumber;
evmAmountSponsored: BigNumber;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { CHAIN_IDs } from "@across-protocol/constants";
import { formatFromAddressToChainFormat, isTestnet } from "../../utils";
import {
BlockRange,
HYPERCORE_FLOW_EXECUTOR_ADDRESS,
SimpleTransferFlowCompletedLog,
ArbitraryActionsExecutedLog,
ARBITRARY_EVM_FLOW_EXECUTOR_ADDRESS,
FallbackHyperEVMFlowCompletedLog,
} from "../model";
import { IndexerDataHandler } from "./IndexerDataHandler";
import { EventDecoder } from "../../web3/EventDecoder";
Expand Down Expand Up @@ -55,6 +54,7 @@ export type FetchEventsResult = {
sponsoredBurnEvents: SponsoredDepositForBurnLog[];
simpleTransferFlowCompletedEvents: SimpleTransferFlowCompletedLog[];
arbitraryActionsExecutedEvents: ArbitraryActionsExecutedLog[];
fallbackHyperEVMFlowCompletedEvents: FallbackHyperEVMFlowCompletedLog[];
blocks: Record<string, providers.Block>;
transactionReceipts: Record<string, providers.TransactionReceipt>;
transactions: Record<string, Transaction>;
Expand All @@ -71,6 +71,7 @@ export type StoreEventsResult = {
savedSponsoredBurnEvents: SaveQueryResult<entities.SponsoredDepositForBurn>[];
savedSimpleTransferFlowCompletedEvents: SaveQueryResult<entities.SimpleTransferFlowCompleted>[];
savedArbitraryActionsExecutedEvents: SaveQueryResult<entities.ArbitraryActionsExecuted>[];
savedFallbackHyperEVMFlowCompletedEvents: SaveQueryResult<entities.FallbackHyperEVMFlowCompleted>[];
};

// Taken from https://developers.circle.com/cctp/evm-smart-contracts
Expand All @@ -85,6 +86,12 @@ const MESSAGE_TRANSMITTER_ADDRESS_MAINNET: string =
const MESSAGE_TRANSMITTER_ADDRESS_TESTNET: string =
"0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275";

// TODO: Update this address once the contract is deployed
const SPONSORED_CCTP_DST_PERIPHERY_ADDRESS: { [key: number]: string } = {
// Taken from https://hyperevmscan.io/address/0x7B164050BBC8e7ef3253e7db0D74b713Ba3F1c95#code
[CHAIN_IDs.HYPEREVM]: "0x7B164050BBC8e7ef3253e7db0D74b713Ba3F1c95",
};

// TODO: Update this address once the contract is deployed
const SPONSORED_CCTP_SRC_PERIPHERY_ADDRESS: { [key: number]: string } = {
[CHAIN_IDs.ARBITRUM_SEPOLIA]: "0x79176E2E91c77b57AC11c6fe2d2Ab2203D87AF85",
Expand Down Expand Up @@ -161,10 +168,8 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
): Promise<FetchEventsResult> {
const sponsoredCCTPSrcPeripheryAddress =
SPONSORED_CCTP_SRC_PERIPHERY_ADDRESS[this.chainId];
const hyperEvmExecutorAddress =
HYPERCORE_FLOW_EXECUTOR_ADDRESS[this.chainId];
const arbitraryEvmFlowExecutorAddress =
ARBITRARY_EVM_FLOW_EXECUTOR_ADDRESS[this.chainId];
const sponsoredCCTPDstPeripheryAddress =
SPONSORED_CCTP_DST_PERIPHERY_ADDRESS[this.chainId];

const tokenMessengerAddress = isTestnet(this.chainId)
? TOKEN_MESSENGER_ADDRESS_TESTNET
Expand Down Expand Up @@ -276,20 +281,26 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {

let simpleTransferFlowCompletedEvents: SimpleTransferFlowCompletedLog[] =
[];
if (hyperEvmExecutorAddress) {
let arbitraryActionsExecutedEvents: ArbitraryActionsExecutedLog[] = [];
let fallbackHyperEVMFlowCompletedEvents: FallbackHyperEVMFlowCompletedLog[] =
[];
if (sponsoredCCTPDstPeripheryAddress) {
simpleTransferFlowCompletedEvents =
this.getSimpleTransferFlowCompletedEventsFromTransactionReceipts(
filteredMessageReceivedTxReceipts,
hyperEvmExecutorAddress,
sponsoredCCTPDstPeripheryAddress,
);
}

let arbitraryActionsExecutedEvents: ArbitraryActionsExecutedLog[] = [];
if (arbitraryEvmFlowExecutorAddress) {
arbitraryActionsExecutedEvents =
this.getArbitraryActionsExecutedEventsFromTransactionReceipts(
filteredMessageReceivedTxReceipts,
arbitraryEvmFlowExecutorAddress,
sponsoredCCTPDstPeripheryAddress,
);

fallbackHyperEVMFlowCompletedEvents =
this.getFallbackHyperEVMFlowCompletedEventsFromTransactionReceipts(
filteredMessageReceivedTxReceipts,
sponsoredCCTPDstPeripheryAddress,
);
}

Expand All @@ -314,6 +325,7 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
sponsoredBurnEvents,
simpleTransferFlowCompletedEvents,
arbitraryActionsExecutedEvents,
fallbackHyperEVMFlowCompletedEvents,
blocks,
transactionReceipts,
transactions: depositForBurnTransactions,
Expand Down Expand Up @@ -540,6 +552,28 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
return events;
}

private getFallbackHyperEVMFlowCompletedEventsFromTransactionReceipts(
transactionReceipts: Record<string, ethers.providers.TransactionReceipt>,
arbitraryEvmFlowExecutorAddress: string,
) {
const events: FallbackHyperEVMFlowCompletedLog[] = [];
for (const txHash of Object.keys(transactionReceipts)) {
const transactionReceipt = transactionReceipts[
txHash
] as providers.TransactionReceipt;
const fallbackHyperEVMFlowCompletedEvents: FallbackHyperEVMFlowCompletedLog[] =
EventDecoder.decodeFallbackHyperEVMFlowCompletedEvents(
transactionReceipt,
arbitraryEvmFlowExecutorAddress,
);
if (fallbackHyperEVMFlowCompletedEvents.length > 0) {
events.push(...fallbackHyperEVMFlowCompletedEvents);
}
}

return events;
}

private async getTransactionsReceipts(uniqueTransactionHashes: string[]) {
const transactionReceipts = await Promise.all(
uniqueTransactionHashes.map(async (txHash) => {
Expand Down Expand Up @@ -597,6 +631,7 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
sponsoredBurnEvents,
simpleTransferFlowCompletedEvents,
arbitraryActionsExecutedEvents,
fallbackHyperEVMFlowCompletedEvents,
blocks,
} = events;
const blocksTimestamps = this.getBlocksTimestamps(blocks);
Expand All @@ -620,6 +655,7 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
savedSponsoredBurnEvents,
savedSimpleTransferFlowCompletedEvents,
savedArbitraryActionsExecutedEvents,
savedFallbackHyperEVMFlowCompletedEvents,
] = await Promise.all([
this.cctpRepository.formatAndSaveBurnEvents(
chainAgnosticBurnEvents,
Expand Down Expand Up @@ -651,6 +687,12 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
this.chainId,
blocksTimestamps,
),
this.cctpRepository.formatAndSaveFallbackHyperEVMFlowCompletedEvents(
fallbackHyperEVMFlowCompletedEvents,
lastFinalisedBlock,
this.chainId,
blocksTimestamps,
),
]);

return {
Expand All @@ -659,6 +701,7 @@ export class CCTPIndexerDataHandler implements IndexerDataHandler {
savedSponsoredBurnEvents,
savedSimpleTransferFlowCompletedEvents,
savedArbitraryActionsExecutedEvents,
savedFallbackHyperEVMFlowCompletedEvents,
};
}

Expand Down
Loading