Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to override compiler options for contracts in node_modules #6090

Closed
theonekeyg opened this issue Dec 27, 2024 · 5 comments
Closed

Unable to override compiler options for contracts in node_modules #6090

theonekeyg opened this issue Dec 27, 2024 · 5 comments
Assignees

Comments

@theonekeyg
Copy link

theonekeyg commented Dec 27, 2024

Version of Hardhat

1.22.17

What happened?

I have a set of smart contracts that use npm package for some contract dependencies. One of the smart contracts in the npm package is failing the optimizer, therefore if I want to have optimizer enabled for my contracts, I have to somehow disable optimizer for failing contracts (because fails on optimizer revert the whole compilation).

I created a very simplistic repo showcasing the error, there I put exact setup that I face, I import the contract that does not suffer from optimization failures from the package that contains a contract that does fail. The result is that the whole optimization (and therefore compilation) step is failing, even thought I don't import the failing contract directly.

I try to use solidity.overrides to disable optimizer for the problematic contract, but it does not seem to produce any effect, the compilation still fails.

Here's my hardhat.config.ts

 const config: HardhatUserConfig = {
  solidity: {
    compilers: [
      {
        version: "0.8.28",
        settings: {
          optimizer: {
            enabled: true,
            runs: 200,
          },
          viaIR: true,
        },
      }
    ],
    overrides: {
      "node_modules/@entangle_protocol/oracle-sdk/contracts/EndPoint.sol": {
        version: "0.8.27",
        settings: {
          optimizer: {
            enabled: false,
          },
        },
      },
    },
  },
};

Like I said this does not produce any effect, even in logs with --verbose it shows that it does not use compiler from overrides.

hardhat:core:compilation-job File '/home/keyg/tmp/hardhat-overrides-bug/node_modules/@entangle_protocol/oracle-sdk/contracts/EndPoint.sol' will be compiled with version '0.8.28'

Minimal reproduction steps

Clone the repo https://github.com/theonekeyg/hardhat-overrides-bug and run:

  1. yarn install
  2. yarn hardhat compile
  3. Observe error of failing Yul optimizer
YulException: Cannot swap Variable expr_1156_offset with Variable _3: too deep in the stack by 1 slots in [ value_5 var_transmitterSigs_length RET var_transmitterSigs_offset expr_1156_offset var_opData_offset value_3 value_2 value _2 _1 value_2 value_1 value var_opData_offset value_3 value_5 value_4 expr_1158_length expr_1158_offset expr_length _3 ]
No memoryguard was present. Consider using memory-safe assembly only and annotating it via 'assembly ("memory-safe") { ... }'.
   --> @entangle_protocol/oracle-sdk/contracts/EndPoint.sol:404:17:
    |
404 |                 opData.params,
    |                 ^^^^^^^^^^^^^


Error HH600: Compilation failed

For more info go to https://hardhat.org/HH600 or run Hardhat with --show-stack-traces
error Command failed with exit code 1.

Search terms

No response

@github-project-automation github-project-automation bot moved this to Backlog in Hardhat Dec 27, 2024
@theonekeyg theonekeyg changed the title Unable to specify compiler options for contracts in node_modules Unable to override compiler options for contracts in node_modules Dec 27, 2024
@theonekeyg
Copy link
Author

theonekeyg commented Jan 15, 2025

Hi again. Please have a look, it's been a big issue for us
cc @fvictorio @ChristopherDedominici

@fvictorio
Copy link
Member

@theonekeyg you have to use the source name in the override, not the relative path. The source name in this case is what you'd use to import that module in one of your contracts, so @entangle_protocol/oracle-sdk/contracts/EndPoint.sol, without the node_modules.

Tentatively closing because I think that should do it, but let us know if it still doesn't work.

@fvictorio fvictorio closed this as not planned Won't fix, can't repro, duplicate, stale Jan 20, 2025
@github-project-automation github-project-automation bot moved this from Backlog to Done in Hardhat Jan 20, 2025
@theonekeyg
Copy link
Author

theonekeyg commented Jan 22, 2025

@fvictorio Hi. I tried using source name to declare a contract override (@entangle_protocol/oracle-sdk/contracts/EndPoint.sol) as you advised. This appears to work to change compiler version (I see 0.8.27 being used in verbose mode), but not for settings to disable the optimizer, as I still get the same error. Compilation works only if I disable the optimizer in main compiler.

I pushed the branch for easy reproduction - https://github.com/theonekeyg/hardhat-overrides-bug/tree/try-with-source-name.

Is there anything else I can try?

@fvictorio
Copy link
Member

The reason for that is that you have other contracts that import that contract, and those use the main compilation setting. The compilation unit for those contracts will use that setting, even if there is an override.

For example, let's say you have a file A.sol that imports B.sol and you configure Hardhat to compile with 0.8.0 but use an override to compile B.sol with 0.8.1. This doesn't mean that A and B will be compiled independently with different versions; that's just not possible to do, because A imports B and so it needs to be compiled along with it. What happens in this case is that a compilation unit of A and B will be compiled with 0.8.0, and another compilation unit with just B will be compiled with 0.8.1. Then the artifact for B (the bytecode you'll deploy if you deploy B) will be the one generated with 0.8.1. But if, say, A does new B() in its code, that bytecode will be the one generated with 0.8.0.

tl;dr this is complex, and the best solution for your case will depend a lot on your project and what you are trying to achieve.

@theonekeyg
Copy link
Author

You are correct, indeed the failing contract was imported by chain of imports. For my case, it'll be sufficient to make an interface of dependency and import that in main contracts instead. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

3 participants