brownie icon indicating copy to clipboard operation
brownie copied to clipboard

Using lib for * breaks compiler

Open illuzen opened this issue 3 years ago • 12 comments

Environment information

  • brownie Version: 1.16.3
  • ganache-cli Version: N/A
  • solc Version: 0.7.4
  • Python Version: 3.9.1
  • OS: linux

What was wrong?

when using a library in a solidity contract i used the syntax

using MerkleLib for *;

which throws the following confusing error:

Generating build data... File "brownie/_cli/main.py", line 64, in main importlib.import_module(f"brownie._cli.{cmd}").main() File "brownie/_cli/compile.py", line 50, in main proj = project.load() File "brownie/project/main.py", line 745, in load return Project(name, project_path) File "brownie/project/main.py", line 180, in init self.load() File "brownie/project/main.py", line 235, in load self._compile(changed, self._compiler_config, False) File "brownie/project/main.py", line 92, in _compile build_json = compiler.compile_and_format( File "brownie/project/compiler/init.py", line 142, in compile_and_format build_json.update(generate_build_json(input_json, output_json, compiler_data, silent)) File "brownie/project/compiler/init.py", line 287, in generate_build_json source_nodes, statement_nodes, branch_nodes = solidity._get_nodes(output_json) File "brownie/project/compiler/solidity.py", line 606, in _get_nodes source_nodes = solcast.from_standard_output(output_json) File "solcast/main.py", line 33, in from_standard_output source_nodes = set_dependencies(source_nodes) File "solcast/dependencies.py", line 18, in set_dependencies contract.libraries = dict( File "solcast/dependencies.py", line 19, in (_get_type_name(i.typeName), i.libraryName.name) AttributeError: 'UsingForDirective' object has no attribute 'typeName'

If I change it to

using MerkleLib for bytes32;

it works. I'm pretty sure the * syntax is valid, because truffle accepts it, but it's probably better to be explicit in my contracts. But yeah probably the * syntax is being misinterpreted.

illuzen avatar Sep 21 '21 07:09 illuzen

It's valid syntax right now but I'd recommend against using it if you don't have to. It's likely going to be deprecated in one of the future releases of the compiler: https://github.com/ethereum/solidity/issues/11882.

cameel avatar Sep 25 '21 20:09 cameel

Ok, fair enough. It would probably be good to have a clear error message if you're not going to support it, tho

illuzen avatar Oct 10 '21 07:10 illuzen

Having the same problem, is quite annoying actually.

ImportNN avatar Dec 03 '21 18:12 ImportNN

I think I hit this when trying to load 0x153CdDD727e407Cb951f728F24bEB9A5FaaA8512:

>>> Contract("0x153CdDD727e407Cb951f728F24bEB9A5FaaA8512")
Fetching source of 0x153CdDD727e407Cb951f728F24bEB9A5FaaA8512 from api.etherscan.io...
  File "<console>", line 1, in <module>
  File "/home/ski/code/brownie/brownie/network/contract.py", line 898, in __init__
    contract = self.from_explorer(
  File "/home/ski/code/brownie/brownie/network/contract.py", line 1193, in from_explorer
    build_json = compiler.compile_and_format(
  File "/home/ski/code/brownie/brownie/project/compiler/__init__.py", line 142, in compile_and_format
    build_json.update(generate_build_json(input_json, output_json, compiler_data, silent))
  File "/home/ski/code/brownie/brownie/project/compiler/__init__.py", line 287, in generate_build_json
    source_nodes, statement_nodes, branch_nodes = solidity._get_nodes(output_json)
  File "/home/ski/code/brownie/brownie/project/compiler/solidity.py", line 606, in _get_nodes
    source_nodes = solcast.from_standard_output(output_json)
  File "solcast/main.py", line 33, in from_standard_output
    source_nodes = set_dependencies(source_nodes)
  File "solcast/dependencies.py", line 18, in set_dependencies
    contract.libraries = dict(
  File "solcast/dependencies.py", line 19, in <genexpr>
    (_get_type_name(i.typeName), i.libraryName.name)
AttributeError: 'UsingForDirective' object has no attribute 'typeName'

BlinkyStitt avatar Apr 09 '22 21:04 BlinkyStitt

Having the same issue with brownie & openzeppelin.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol

Has a using ShortStrings for *;

Which breaks the compiler

jhiver avatar Jun 07 '23 11:06 jhiver

If this is valid Solidity syntax, I believe it should be supported by Brownie. Has anyone identified the cause?

frangio avatar Jun 07 '23 21:06 frangio

in site-packages/solcast/dependencies.py there is this code:

    # add immediate dependencies
    for contract in contract_list:
        contract.dependencies = set()
        contract.libraries = dict(
            (_get_type_name(i.typeName), i.libraryName.name)
            for i in contract.nodes
            if i.nodeType == "UsingForDirective"
        )

In the case of using SomeLib for *;, the nodeType is UsingForDirective, but i.typeName does not exist, which triggers the crash.

jhiver avatar Jun 07 '23 22:06 jhiver

I also reported the issue on OpenZeppelin side, https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4322#issuecomment-1581557506, but arguably, it's more a brownie bug than an OpenZeppelin bug since it's valid solidity syntax.

jhiver avatar Jun 07 '23 22:06 jhiver

is there a quick and dirty way to fix this?

RomanHiden avatar Aug 21 '23 17:08 RomanHiden

looks like the problem is somewhere in https://github.com/iamdefinitelyahuman/py-solc-ast specifically grammar definitions https://github.com/iamdefinitelyahuman/py-solc-ast/blob/master/solcast/grammar.py UsingForDirective instead of UsingForDeclaration

RomanHiden avatar Aug 21 '23 17:08 RomanHiden

looks like the problem is somewhere in https://github.com/iamdefinitelyahuman/py-solc-ast specifically grammar definitions https://github.com/iamdefinitelyahuman/py-solc-ast/blob/master/solcast/grammar.py UsingForDirective instead of UsingForDeclaration

this is wrong

RomanHiden avatar Aug 21 '23 19:08 RomanHiden

in the ERC20Permit.sol (v4.9.3 of OpenZeppelin), there is the following statement: using Counters for Counters.Counter;

which causes the same error AttributeError: 'UsingForDirective' object has no attribute 'typeName'

is it the same issue or should I open a separate one?

trx314 avatar Sep 05 '23 14:09 trx314