#!/usr/bin/env node /** * Calculate CREATE address given deployer and nonce * * CREATE formula: * address = keccak256(RLP(deployer_address, nonce))[12:] * * RLP encoding: * - For nonce = 0: RLP([deployer_address]) * - For nonce > 0: RLP([deployer_address, nonce]) */ const { ethers } = require("ethers"); const RLP = require("rlp"); // Target addresses from genesis.json const TARGET_WETH9 = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; const TARGET_WETH10 = "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F"; // Potential deployers const DEPLOYERS = [ "0x0742D35CC6634c0532925A3b844bc9E7595f0Beb", "0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882", "0x4a666f96fc8764181194447a7dfdb7d471b301c8", ]; /** * Calculate CREATE address using RLP encoding */ function calculateCreateAddress(deployer, nonce) { const deployerBytes = Buffer.from(deployer.slice(2), 'hex'); let rlpEncoded; if (nonce === 0) { // RLP([deployer_address]) rlpEncoded = RLP.encode([deployerBytes]); } else { // RLP([deployer_address, nonce]) const nonceHex = nonce.toString(16); const nonceBytes = Buffer.from(nonceHex.padStart(nonceHex.length + (nonceHex.length % 2), '0'), 'hex'); rlpEncoded = RLP.encode([deployerBytes, nonceBytes]); } const hash = ethers.keccak256(rlpEncoded); const address = '0x' + hash.slice(-40); return ethers.getAddress(address); } /** * Find nonce that produces target address */ function findNonceForTarget(targetAddress, deployer, maxNonce = 10000) { console.log(`Finding nonce for deployer ${deployer} to produce ${targetAddress}...`); for (let nonce = 0; nonce < maxNonce; nonce++) { const computed = calculateCreateAddress(deployer, nonce); if (nonce % 1000 === 0 && nonce > 0) { process.stdout.write(`\rChecked ${nonce} nonces...`); } if (computed.toLowerCase() === targetAddress.toLowerCase()) { console.log(`\n✅ Found nonce: ${nonce}`); console.log(` Deployer: ${deployer}`); console.log(` Computed: ${computed}`); return nonce; } } console.log(`\n❌ Could not find nonce after ${maxNonce} attempts`); return null; } async function main() { const args = process.argv.slice(2); if (args.length < 1) { console.log("Usage: node calculate-create-address.js [deployer-address] [max-nonce]"); console.log(""); console.log("Examples:"); console.log(" node calculate-create-address.js 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); console.log(" node calculate-create-address.js 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 0x0742D35CC6634c0532925A3b844bc9E7595f0Beb"); process.exit(1); } const targetAddress = ethers.getAddress(args[0]); const deployer = args[1] ? ethers.getAddress(args[1]) : DEPLOYERS[0]; const maxNonce = args[2] ? parseInt(args[2]) : 10000; console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); console.log("Calculate CREATE Address"); console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); console.log(""); console.log(`Target Address: ${targetAddress}`); console.log(`Deployer: ${deployer}`); console.log(`Max Nonce: ${maxNonce}`); console.log(""); // Try all deployers if not specified const deployersToTry = args[1] ? [deployer] : DEPLOYERS; for (const deployerAddr of deployersToTry) { const nonce = findNonceForTarget(targetAddress, deployerAddr, maxNonce); if (nonce !== null) { console.log(""); console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); console.log("✅ CREATE Parameters Found"); console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); console.log(`Target Address: ${targetAddress}`); console.log(`Deployer: ${deployerAddr}`); console.log(`Nonce: ${nonce}`); console.log(""); console.log("Use these parameters in your deployment script:"); console.log(` vm.startBroadcast(${deployerAddr});`); console.log(` // Ensure nonce is ${nonce}`); console.log(` WETH weth = new WETH();`); console.log(""); process.exit(0); } } console.log(""); console.log("❌ Could not find CREATE parameters for any deployer"); console.log("You may need to:"); console.log(" 1. Try different deployers"); console.log(" 2. Increase max-nonce"); console.log(" 3. Check if address was deployed with different method"); process.exit(1); } if (require.main === module) { main().catch(console.error); } module.exports = { calculateCreateAddress, findNonceForTarget };