Reputation: 563
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
Upvotes: 2
Views: 5423
Reputation: 3
I encountered a similar issue, and enabling the optimizer during compilation did the trick for me. However, when I attempted coverage tests, I encountered the same "stack too deep" error. To resolve this issue, I added the following code to the optimizer settings, which successfully resolved the stack error for coverage tests as well:
details: {
yul: true,
}
As a result, my configuration now resembles this:
solidity: {
version: "0.8.17",
settings: {
optimizer: {
enabled: true,
runs: 10000,
details: {
yul: true,
},
},
},
},
This addition to the optimizer settings appears to have provided a comprehensive solution to the "stack too deep" error in both compilation and coverage testing scenarios.
Upvotes: 0
Reputation: 49361
there is a size limit for contract to be compiled.
Size cap of contract content is about 24577 bytes. Optimizer decreases the size. Default { enabled : false, runs : 200 }
. runs
can be set to up to 5000. this property helped you to compile the contract
In your case you did not need yul option. It helps you develop smart contracts with Yul and/or Yul+. https://docs.soliditylang.org/en/v0.8.17/yul.html
Upvotes: 1
Reputation: 563
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:
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
Upvotes: 5