require("@nomicfoundation/hardhat-toolbox"); require("dotenv").config(); // Helper function to format private key function formatPrivateKey(key) { if (!key) return undefined; // Remove 0x prefix if present let cleanKey = key.startsWith('0x') ? key.slice(2) : key; // Ensure it's exactly 64 characters (32 bytes) if (cleanKey.length !== 64) { console.error(`Invalid private key length: ${cleanKey.length}, expected 64 characters`); return undefined; } return cleanKey; } const privateKey = formatPrivateKey(process.env.PRIVATE_KEY); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: { compilers: [ { version: "0.8.23", settings: { optimizer: { enabled: true, runs: 1, // R5: prioritize size — AereCoreBookV0 + sAERE drip pushed contract to ~25KB }, viaIR: true, // Enable intermediate representation for better optimization }, }, ], // Per-file overrides ONLY. The global compiler stays 0.8.23 (shanghai // default) so the bytecode of every other contract is untouched. Cancun // opcode contracts opt in file by file: solc 0.8.23 cannot target cancun // (0.8.24 is the first release that can), so an override must also pin // the newer compiler version. overrides: { // Cancun EVM canary: TSTORE/TLOAD (EIP-1153), MCOPY (EIP-5656), // PUSH0 (EIP-3855), BLOBHASH/BLOBBASEFEE (EIP-4844/7516). "contracts/AereCancunCanary.sol": { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 }, evmVersion: "cancun", }, }, }, }, networks: { // AERE Network Mainnet - Production Ready aere: { url: process.env.AERE_RPC_URL || "https://rpc.aere.network", chainId: 2800, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", // Automatic gas price detection gasMultiplier: 1.2, // 20% buffer for gas estimation timeout: 60000, // 60 second timeout confirmations: 2, // Wait for 2 confirmations }, // AERE Network Testnet - Enhanced for Testing aereTestnet: { url: process.env.AERE_TESTNET_RPC_URL || "https://testnet-rpc.aere.network", chainId: 2801, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", gasMultiplier: 1.5, // Higher buffer for testnet timeout: 120000, // Longer timeout for testnet confirmations: 1, // Faster confirmations for testing }, // Local development with Hardhat node. // accounts: "remote" = use the node's own 20 unlocked, pre-funded signers // (the env PRIVATE_KEY account holds no ETH on a fresh hardhat node, and // local harnesses like run-local-corebook.js need 3 funded signers). localhost: { url: "http://127.0.0.1:8545", chainId: 31337, accounts: "remote", gasPrice: 20000000000, // 20 gwei gasMultiplier: 1.1, }, // Hardhat network for testing hardhat: { chainId: 31337, // AERE mainnet has an effectively unlimited block gas limit; the heavy // on-chain Falcon-1024 verifier needs > 30M gas per call, so raise the // LOCAL test ceiling. This affects local testing only (not the aere // network config, which uses gasPrice/estimation against the live chain). // hardfork "cancun" avoids the EIP-7825 (Fusaka) 2^24 per-tx gas cap that // newer hardhat defaults enforce, which is far below a Falcon-1024 verify. hardfork: "cancun", blockGasLimit: 2_000_000_000, allowUnlimitedContractSize: false, // R6 FIX: removed `interval: 2000` — spontaneous auto-mining between // RPC reads caused fuzz snapshots to span multiple block timestamps, // creating phantom drift on time-dependent views (sAERE undist, etc). // Tests that need block time advance use evm_increaseTime + evm_mine // explicitly. mining: { auto: true, }, accounts: { mnemonic: process.env.MNEMONIC || "test test test test test test test test test test test junk", count: 20, accountsBalance: "10000000000000000000000" } }, // Polygon testnet for cross-chain testing mumbai: { url: process.env.MUMBAI_RPC_URL || "https://rpc-mumbai.maticvigil.com", chainId: 80001, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", }, // Ethereum Sepolia testnet for interoperability testing sepolia: { url: process.env.SEPOLIA_RPC_URL || "https://rpc.sepolia.org", chainId: 11155111, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", }, // ── L1 / L2 counterparty chains for the USDC.e Warp Route L1 leg. ── // INERT until the founder picks a chain, sets its RPC + a funded PRIVATE_KEY, // and explicitly runs scripts/stablecoins/deploy-l1-warp-collateral.js against // it. Defining a network deploys nothing. See docs/WARP_ROUTE_L1_LEG_*.md. ethereum: { url: process.env.ETHEREUM_RPC_URL || "https://ethereum-rpc.publicnode.com", chainId: 1, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", }, base: { url: process.env.BASE_RPC_URL || "https://mainnet.base.org", chainId: 8453, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", }, arbitrum: { url: process.env.ARBITRUM_RPC_URL || "https://arb1.arbitrum.io/rpc", chainId: 42161, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", }, optimism: { url: process.env.OPTIMISM_RPC_URL || "https://mainnet.optimism.io", chainId: 10, accounts: privateKey ? [privateKey] : [], gasPrice: "auto", } }, // Enhanced Etherscan configuration for verification etherscan: { apiKey: { aere: process.env.AERE_EXPLORER_API_KEY || "your-api-key-here", aereTestnet: process.env.AERE_TESTNET_EXPLORER_API_KEY || "your-testnet-api-key-here", polygon: process.env.POLYGONSCAN_API_KEY || "", polygonMumbai: process.env.POLYGONSCAN_API_KEY || "", sepolia: process.env.ETHERSCAN_API_KEY || "", // L1 Warp Route counterparty chains (optional contract verification). // Etherscan V2 uses one multichain key across all four; set ETHERSCAN_API_KEY. mainnet: process.env.ETHERSCAN_API_KEY || "", ethereum: process.env.ETHERSCAN_API_KEY || "", base: process.env.ETHERSCAN_API_KEY || process.env.BASESCAN_API_KEY || "", arbitrum: process.env.ETHERSCAN_API_KEY || process.env.ARBISCAN_API_KEY || "", optimism: process.env.ETHERSCAN_API_KEY || process.env.OPTIMISM_API_KEY || "" }, customChains: [ { network: "aere", chainId: 2800, urls: { apiURL: process.env.AERE_EXPLORER_API_URL || "https://explorer.aere.network/api", browserURL: process.env.AERE_EXPLORER_URL || "https://explorer.aere.network" } }, { network: "aereTestnet", chainId: 2801, urls: { apiURL: process.env.AERE_TESTNET_EXPLORER_API_URL || "https://testnet-explorer.aere.network/api", browserURL: process.env.AERE_TESTNET_EXPLORER_URL || "https://testnet-explorer.aere.network" } } ] }, // Gas reporting for cost optimization gasReporter: { enabled: process.env.REPORT_GAS !== undefined, currency: "USD", gasPrice: 20, // 20 gwei coinmarketcap: process.env.COINMARKETCAP_API_KEY, showTimeSpent: true, showMethodSig: true, maxMethodDiff: 10, }, // Contract size reporting contractSizer: { alphaSort: true, runOnCompile: true, disambiguatePaths: false, }, // Mocha test configuration mocha: { timeout: 120000, // 2 minutes for complex tests reporter: process.env.CI ? "json" : "spec", }, // Deployment paths paths: { sources: "./contracts", tests: "./test", cache: "./cache", artifacts: "./artifacts", deploy: "./deploy", deployments: "./deployments", }, // Compiler settings for different environments dependencyCompiler: { paths: [ "@openzeppelin/contracts/token/ERC20/ERC20.sol", "@openzeppelin/contracts/access/Ownable.sol", "@openzeppelin/contracts/security/ReentrancyGuard.sol", ], }, };