// CI-portable config for `npx hardhat coverage`. // // This is a SEPARATE config on purpose. The production `hardhat.config.js` is // never read by the coverage run and is never modified by it, so a coverage // run cannot change the bytecode that gets compiled, tested or deployed. // // Difference from the internal config it is derived from: every path here is // RELATIVE. The internal one hardcoded an absolute developer scratch directory, // which meant it could not run on a CI runner at all. Relative paths are what // make this file reproducible on a stranger's machine. // // COMPILER STRATEGY (this is the non-obvious part, documented so it is not // "fixed" back into a broken state): // // * The GLOBAL compiler stays production-like: solc 0.8.23, optimizer ON // runs:1, viaIR:true. Optimizer ON is what lets the deep, // optimizer-dependent contracts (for example AerePaymentChannels // .closeWithState) compile at all. // // * Do NOT "just disable viaIR for coverage". That is the intuitive lever and // it is the wrong one. solidity-coverage's own plugin source // (plugins/hardhat.plugin.js) contains: // // if (!settings.viaIR || irMinimum) settings.optimizer.enabled = false; // // so turning viaIR off, or setting irMinimum, forces the optimizer OFF for // EVERY compilation job in the tree. That breaks the optimizer-dependent // contracts and produces stack-too-deep on strictly MORE files, not fewer. // Per-file overrides work precisely because the global job keeps viaIR true, // which leaves the plugin's optimizer setting alone. // // * If a contract overflows the Yul stack ONLY once instrumented, give it a // per-file STACK_ALLOC_OVERRIDE below. Same mechanics as the plugin's // `irMinimum`, applied per file instead of globally. require("@nomicfoundation/hardhat-toolbox"); // pulls in solidity-coverage // optimizer OFF + Yul stack allocation: makes an INSTRUMENTED deep contract fit // the 16-slot stack, without disabling the optimizer for the whole tree. // eslint-disable-next-line no-unused-vars const STACK_ALLOC_OVERRIDE = { version: "0.8.23", settings: { optimizer: { enabled: false, details: { yul: true, yulDetails: { stackAllocation: true, optimizerSteps: "" } }, }, viaIR: true, }, }; module.exports = { solidity: { compilers: [ { version: "0.8.23", settings: { optimizer: { enabled: true, runs: 1 }, viaIR: true, }, }, ], overrides: { // Cancun canary keeps its production override (0.8.24 / cancun / runs:200). "contracts/AereCancunCanary.sol": { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 }, evmVersion: "cancun", }, }, // NOTE: the internal tree also overrides three contracts/corebook/*.sol // files here. Those contracts are held private (see EXCLUDED-FILES.txt) // and are not present in this repository, so their overrides are omitted. // If you add a contract that fails to compile ONLY under coverage with a // "stack too deep" YulException, add it here as STACK_ALLOC_OVERRIDE. }, }, networks: { hardhat: { chainId: 31337, hardfork: "cancun", blockGasLimit: 2_000_000_000, allowUnlimitedContractSize: true, mining: { auto: true }, accounts: { // Public, well-known Hardhat test mnemonic. It is deliberately the // standard throwaway. It holds nothing, on any network, ever. mnemonic: "test test test test test test test test test test test junk", count: 20, accountsBalance: "10000000000000000000000", }, }, }, mocha: { timeout: 240000 }, paths: { sources: "./contracts", tests: "./test", // Relative, and separate from ./cache and ./artifacts, so the instrumented // build never pollutes the production build outputs. cache: "./cache-coverage", artifacts: "./artifacts-coverage", }, };