From fdabd3bad7bd630692e528788bafa70fbb24b7c3 Mon Sep 17 00:00:00 2001 From: KSS Date: Wed, 7 Jan 2026 14:15:48 +0100 Subject: [PATCH 1/2] feat: scripts to analyse 7683 logs --- .../script/test/7683/analyselogs/.gitignore | 34 +++++++ .../script/test/7683/analyselogs/README.md | 14 +++ .../test/7683/analyselogs/arb-to-base.ts | 89 +++++++++++++++++++ .../test/7683/analyselogs/base-to-arb.ts | 88 ++++++++++++++++++ .../script/test/7683/analyselogs/bun.lock | 47 ++++++++++ .../script/test/7683/analyselogs/index.ts | 1 + .../script/test/7683/analyselogs/package.json | 15 ++++ .../test/7683/analyselogs/tsconfig.json | 29 ++++++ 8 files changed, 317 insertions(+) create mode 100644 contracts/script/test/7683/analyselogs/.gitignore create mode 100644 contracts/script/test/7683/analyselogs/README.md create mode 100644 contracts/script/test/7683/analyselogs/arb-to-base.ts create mode 100644 contracts/script/test/7683/analyselogs/base-to-arb.ts create mode 100644 contracts/script/test/7683/analyselogs/bun.lock create mode 100644 contracts/script/test/7683/analyselogs/index.ts create mode 100644 contracts/script/test/7683/analyselogs/package.json create mode 100644 contracts/script/test/7683/analyselogs/tsconfig.json diff --git a/contracts/script/test/7683/analyselogs/.gitignore b/contracts/script/test/7683/analyselogs/.gitignore new file mode 100644 index 00000000..a14702c4 --- /dev/null +++ b/contracts/script/test/7683/analyselogs/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/contracts/script/test/7683/analyselogs/README.md b/contracts/script/test/7683/analyselogs/README.md new file mode 100644 index 00000000..b2ad5744 --- /dev/null +++ b/contracts/script/test/7683/analyselogs/README.md @@ -0,0 +1,14 @@ +# analyselogs + +Analyses on-chain logs for source and target ERC7683 deployments and figures out which intents in a given block range were not filled. Provides useful debug data such as txHash and orderId. + +```bash +bun install +``` + +To run: + +```bash +bun arb-to-base.ts +bun base-to-arb.ts +``` diff --git a/contracts/script/test/7683/analyselogs/arb-to-base.ts b/contracts/script/test/7683/analyselogs/arb-to-base.ts new file mode 100644 index 00000000..5621a81a --- /dev/null +++ b/contracts/script/test/7683/analyselogs/arb-to-base.ts @@ -0,0 +1,89 @@ +import { ethers } from "ethers"; +import T1ERC7683 from "../../../../artifacts/src/T1ERC7683.sol/T1ERC7683.json"; + +// -------------------- Config -------------------- +const arbProvider = new ethers.JsonRpcProvider("https://arb1.arbitrum.io/rpc"); +const arbErc7683Address = "0x996f3583bd967bba19694733aa7a7623e6d780eb"; + +const baseProvider = new ethers.JsonRpcProvider("https://base-rpc.publicnode.com"); +const baseErc7683Address = "0xdbA711a6c1b187479e9a5b33020E5217D0BD5A1f"; + +const arbFromBlock = 418241010; +const arbLatest = 418842847; +// const arbLatest = await arbProvider.getBlockNumber(); + +const baseFromBlock = 40423900; +const baseLatest = 40499026; +// const baseLatest = await baseProvider.getBlockNumber(); + +const step = 10_000; + +const iface = new ethers.Interface(T1ERC7683.abi); + +// Topics +const openTopic0 = iface.getEvent("Open")!.topicHash; +const filledTopic0 = iface.getEvent("Filled")!.topicHash; + +const norm = (x: string) => x.toLowerCase(); + +// -------------------- 1) Collect Opens on Arbitrum -------------------- +const openedByOrderId = new Map(); // orderId -> { orderId, blockNumber, txHash, logIndex, args? } + +for (let start = arbFromBlock; start <= arbLatest; start += step + 1) { + const end = Math.min(arbLatest, start + step); + + const logs = await arbProvider.getLogs({ + address: arbErc7683Address, + fromBlock: start, + toBlock: end, + topics: [openTopic0], + }); + + for (const log of logs) { + const orderId = norm(log.topics[1]!); // indexed orderId + + // Dedup by orderId (keep first seen) + if (!openedByOrderId.has(orderId)) { + openedByOrderId.set(orderId, { + orderId, + blockNumber: log.blockNumber, + txHash: log.transactionHash, + logIndex: log.index, + }); + } + } +} + +console.log(`Searched in Arbitrum blocks from ${arbFromBlock} to ${arbLatest} and found...`); +console.log("Opened unique orderIds on Arbitrum:", openedByOrderId.size); + +// -------------------- 2) Collect Fills on Base -------------------- +const filledOrderIds = new Set(); + +for (let start = baseFromBlock; start <= baseLatest; start += step + 1) { + const end = Math.min(baseLatest, start + step); + + const logs = await baseProvider.getLogs({ + address: baseErc7683Address, + fromBlock: start, + toBlock: end, + topics: [filledTopic0], + }); + + for (const log of logs) { + const orderId = norm(log.topics[1]!); // indexed orderId + filledOrderIds.add(orderId); + } +} + +console.log(`Searched in Base blocks from ${baseFromBlock} to ${baseLatest} and found...`); +console.log("Filled unique orderIds on Base:", filledOrderIds.size); + +// -------------------- 3) Diff: Opened on Arb but NOT Filled on Base -------------------- +const unfilledOpenEvents = []; +for (const [orderId, openEvent] of openedByOrderId.entries()) { + if (!filledOrderIds.has(orderId)) unfilledOpenEvents.push(openEvent); +} + +console.log("Unfilled count:", unfilledOpenEvents.length); +console.log("Unfilled orders:", JSON.stringify(unfilledOpenEvents, null, 2)); diff --git a/contracts/script/test/7683/analyselogs/base-to-arb.ts b/contracts/script/test/7683/analyselogs/base-to-arb.ts new file mode 100644 index 00000000..0effc291 --- /dev/null +++ b/contracts/script/test/7683/analyselogs/base-to-arb.ts @@ -0,0 +1,88 @@ +import { ethers } from "ethers"; +import T1ERC7683 from "../../../../artifacts/src/T1ERC7683.sol/T1ERC7683.json"; + +// -------------------- Config -------------------- +const baseProvider = new ethers.JsonRpcProvider("https://base-rpc.publicnode.com"); +const baseErc7683Address = "0xdbA711a6c1b187479e9a5b33020E5217D0BD5A1f"; + +const arbProvider = new ethers.JsonRpcProvider("https://arb1.arbitrum.io/rpc"); +const arbErc7683Address = "0x996f3583bd967bba19694733aa7a7623e6d780eb"; + +// Your ranges (edit as needed) +const baseFromBlock = 40423900; +const baseLatest = 40499026; +// const baseLatest = await baseProvider.getBlockNumber(); + +const arbFromBlock = 418241010; +const arbLatest = 418842847; +// const arbLatest = await arbProvider.getBlockNumber(); + +const step = 10_000; + +const iface = new ethers.Interface(T1ERC7683.abi); + +const openTopic0 = iface.getEvent("Open")!.topicHash; +const filledTopic0 = iface.getEvent("Filled")!.topicHash; + +const norm = (x: string) => x.toLowerCase(); + +// -------------------- 1) Collect Opens on Base -------------------- +const openedByOrderId = new Map(); // orderId -> { orderId, blockNumber, txHash, logIndex } + +for (let start = baseFromBlock; start <= baseLatest; start += step + 1) { + const end = Math.min(baseLatest, start + step); + + const logs = await baseProvider.getLogs({ + address: baseErc7683Address, + fromBlock: start, + toBlock: end, + topics: [openTopic0], + }); + + for (const log of logs) { + const orderId = norm(log.topics[1]!); // indexed orderId + + if (!openedByOrderId.has(orderId)) { + openedByOrderId.set(orderId, { + orderId, + blockNumber: log.blockNumber, + txHash: log.transactionHash, + logIndex: log.index, + }); + } + } +} + +console.log(`Searched in Base blocks from ${baseFromBlock} to ${baseLatest} and found...`); +console.log("Opened unique orderIds on Base:", openedByOrderId.size); + +// -------------------- 2) Collect Fills on Arbitrum -------------------- +const filledOrderIds = new Set(); + +for (let start = arbFromBlock; start <= arbLatest; start += step + 1) { + const end = Math.min(arbLatest, start + step); + + const logs = await arbProvider.getLogs({ + address: arbErc7683Address, + fromBlock: start, + toBlock: end, + topics: [filledTopic0], + }); + + for (const log of logs) { + const orderId = norm(log.topics[1]!); // indexed orderId + filledOrderIds.add(orderId); + } +} + +console.log(`Searched in Arbitrum blocks from ${arbFromBlock} to ${arbLatest} and found...`); +console.log("Filled unique orderIds on Arbitrum:", filledOrderIds.size); + +// -------------------- 3) Diff: Opened on Base but NOT Filled on Arbitrum -------------------- +const unfilledOpenEvents = []; +for (const [orderId, openEvent] of openedByOrderId.entries()) { + if (!filledOrderIds.has(orderId)) unfilledOpenEvents.push(openEvent); +} + +console.log("Unfilled count:", unfilledOpenEvents.length); +console.log("Unfilled orders:", JSON.stringify(unfilledOpenEvents, null, 2)); diff --git a/contracts/script/test/7683/analyselogs/bun.lock b/contracts/script/test/7683/analyselogs/bun.lock new file mode 100644 index 00000000..e3ac4a68 --- /dev/null +++ b/contracts/script/test/7683/analyselogs/bun.lock @@ -0,0 +1,47 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "analyselogs", + "dependencies": { + "ethers": "^6.16.0", + }, + "devDependencies": { + "@types/bun": "latest", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.10.1", "", {}, "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw=="], + + "@noble/curves": ["@noble/curves@1.2.0", "", { "dependencies": { "@noble/hashes": "1.3.2" } }, "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw=="], + + "@noble/hashes": ["@noble/hashes@1.3.2", "", {}, "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="], + + "@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="], + + "@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], + + "aes-js": ["aes-js@4.0.0-beta.5", "", {}, "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q=="], + + "bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="], + + "ethers": ["ethers@6.16.0", "", { "dependencies": { "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", "ws": "8.17.1" } }, "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A=="], + + "tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + + "ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], + + "bun-types/@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="], + + "bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + } +} diff --git a/contracts/script/test/7683/analyselogs/index.ts b/contracts/script/test/7683/analyselogs/index.ts new file mode 100644 index 00000000..f67b2c64 --- /dev/null +++ b/contracts/script/test/7683/analyselogs/index.ts @@ -0,0 +1 @@ +console.log("Hello via Bun!"); \ No newline at end of file diff --git a/contracts/script/test/7683/analyselogs/package.json b/contracts/script/test/7683/analyselogs/package.json new file mode 100644 index 00000000..b1d8a81f --- /dev/null +++ b/contracts/script/test/7683/analyselogs/package.json @@ -0,0 +1,15 @@ +{ + "name": "analyselogs", + "module": "index.ts", + "type": "module", + "private": true, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5" + }, + "dependencies": { + "ethers": "^6.16.0" + } +} diff --git a/contracts/script/test/7683/analyselogs/tsconfig.json b/contracts/script/test/7683/analyselogs/tsconfig.json new file mode 100644 index 00000000..bfa0fead --- /dev/null +++ b/contracts/script/test/7683/analyselogs/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} From 5f5546d1fef4d26a77db6de819727c9478796d5b Mon Sep 17 00:00:00 2001 From: KSS Date: Wed, 7 Jan 2026 17:58:42 +0100 Subject: [PATCH 2/2] chore: lint README.md --- contracts/script/test/7683/analyselogs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/script/test/7683/analyselogs/README.md b/contracts/script/test/7683/analyselogs/README.md index b2ad5744..c869f565 100644 --- a/contracts/script/test/7683/analyselogs/README.md +++ b/contracts/script/test/7683/analyselogs/README.md @@ -1,6 +1,7 @@ # analyselogs -Analyses on-chain logs for source and target ERC7683 deployments and figures out which intents in a given block range were not filled. Provides useful debug data such as txHash and orderId. +Analyses on-chain logs for source and target ERC7683 deployments and figures out which intents in a given block range +were not filled. Provides useful debug data such as txHash and orderId. ```bash bun install