Search code examples
ethereumsoliditysmartcontractsnfthardhat

How do I resolve this Hardhat CompilerError? (Stack too deep when compiling inline assembly)


I'm analyzing the Chainrunners smart contracts, so I went on Etherscan and copied the verified contract source code.

When I tried to compile without solidity optimizer, I got this warning:

thatguyintech@albert chainrunners % npx hardhat compile
Compiling 5 files with 0.8.4
Warning: Unused local variable.
   --> contracts/ChainRunnersBaseRenderer.sol:232:124:
    |
232 |  ... kenPalettes, uint8 numTokenLayers, string[NUM_LAYERS] memory traitTypes) = getTokenData(_dna);
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
  --> contracts/ChainRunnersBaseRenderer.sol:48:1:
   |
48 | contract ChainRunnersBaseRenderer is Ownable, ReentrancyGuard {
   | ^ (Relevant source part starts here and spans across multiple lines).

So I tried to turn on the optimizer according to the Hardhat official documentation: https://hardhat.org/config/

So here is what my Hardhat config hardhat.config.js looks like:

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: {
    version:  "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 2000,
      }
    }
  }
};

So now I am getting this hardhat CompilerError when I try to run npx hardhat compile:

thatguyintech@albert chainrunners % npx hardhat compile
Compiling 5 files with 0.8.4
CompilerError: Stack too deep when compiling inline assembly: Variable value0 is 3 slot(s) too deep inside the stack.

Anyone know how I can resolve this? From a couple of google searches on hardhat-related threads, it seems like turning the optimizer on should be the fix to this issue, so I'm pretty confused.

Here's an example I found on the OpenZeppelin forums that is not working for me: https://forum.openzeppelin.com/t/stack-to-deep-when-compiling-inline-assembly/11391/11


Solution

  • Ah it turns out there's a section in the Etherscan page that shows the exact solidity optimizer set. (h/t @alcuadadro)

    It looks like this:

    enter image description here

    And so I copied that into my hardhat.config.js:

    /**
     * @type import('hardhat/config').HardhatUserConfig
     */
    module.exports = {
      solidity: {
        version:  "0.8.4",
        settings: {
          optimizer: {
            enabled: true,
            runs: 2000,
            details: {
              yul: true,
              yulDetails: {
                stackAllocation: true,
                optimizerSteps: "dhfoDgvulfnTUtnIf"
              }
            }
          }
        },
      },
    };
    

    and that did the trick!

    no idea what the yul stuff is about though