-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
hh flatten
doesn't support circular dependencies
#1486
Comments
How can one recreate this bug? |
// contracts/Foo.sol
import "./Bar.sol";
contract Foo {} // contracts/Bar.sol
import "./Foo.sol";
contract Bar {}
The solution is probably to get some topological order of the dependency graph and to use that to generate the flattened file, ignoring previously visited files when resolving Edit: this is wrong, check the updated issue description. |
+1 |
4 similar comments
+1 |
+1 |
+1 |
+1 |
I updated this issue explaining why this is more complicated than it seems, and why it may still not work for some usecases. This is something low priority to us, but we may consider doing it once Slang is more mature. |
+1 |
4 similar comments
+1 |
+1 |
+1 |
+1 |
Hardhat
flatten
doesn't support circular dependencies. Some users want this functionality, yet it's not straightforward nor clear that it would work for them. Continue reading to understand why.Hardhat flatten works by creating a topological order of the dependency graph. That is a sequence of files where every file comes after its dependencies. Then it concatenates the files in that order. This ensures that every symbol (e.g. a library, contract, function, etc) is defined before usage. Now, graphs with circular dependencies don't have a topological order, so this algorithm doesn't work.
An alternative is to analyze all the files and create a topological order of top-level definitions (e.g. contract definitions, libraries, etc). This should be possible because Solidity doesn't compile projects if you have cycles in those. The problem is that this is really complex. You need to parse and perform some semantic analyses on top of the sources (use-def analysis), and it should be really precise or it will fail. On top of that, we can't guarantee that the output generated by solidity will be equivalent to the non-flattened task, and this would make it not a good fit for contract verification.
As a general recommendation: avoid circular dependencies. They are harder to reason about, harder to create tooling for, and normally forbidden by many compilers/runtimes. There are multiple refactors that can be applied mechanically to eliminate them.
The text was updated successfully, but these errors were encountered: