#!/usr/bin/env node /** * Verify that WETH9 at 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 on Chain 138 * has the same bytecode as canonical WETH9 on Ethereum mainnet. * Compares keccak256(code); if equal, the contract is canonical WETH9. * Also outputs fingerprint (symbol, name, decimals) for bot/executor startup checks. * See docs/treasury: do not assume canonical WETH9 until this (or verify-weth9-fingerprint.js) passes. */ const ethers = require('ethers'); const WETH9_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; const RPC_138 = 'https://rpc-http-pub.d-bis.org'; const RPC_MAINNET = 'https://eth.llamarpc.com'; async function getCode(rpcUrl) { const res = await fetch(rpcUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'eth_getCode', params: [WETH9_ADDRESS, 'latest'], id: 1, }), }); const data = await res.json(); if (data.error) throw new Error(data.error.message || JSON.stringify(data.error)); return data.result; } async function main() { console.log('Fetching WETH9 bytecode from Chain 138 and Ethereum mainnet...'); const [code138, codeMainnet] = await Promise.all([ getCode(RPC_138), getCode(RPC_MAINNET), ]); const hash = (hex) => ethers.keccak256(hex); const h138 = hash(code138); const hMain = hash(codeMainnet); console.log('Chain 138 bytecode length (bytes):', (code138.length - 2) / 2); console.log('Ethereum main bytecode length (bytes):', (codeMainnet.length - 2) / 2); console.log('Chain 138 keccak256(code):', h138); console.log('Ethereum main keccak256(code):', hMain); console.log(''); if (h138 === hMain) { console.log('Match: YES — Chain 138 has canonical WETH9 bytecode at', WETH9_ADDRESS); process.exit(0); } else { console.log('Match: NO — Chain 138 has WETH-like bytecode at that address, but not canonical WETH9.'); process.exit(1); } } main().catch((err) => { console.error(err); process.exit(1); });