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

[Bug]: ERROR:ContractSolcParsing when using same alias for import #2454

Closed
MarHalborn opened this issue May 7, 2024 · 2 comments
Closed
Labels
bug Something isn't working

Comments

@MarHalborn
Copy link

Describe the issue:

Hello,

At Halborn we were testing slither with some client contracts and encountered the following issue.
Captura de pantalla de 2024-05-07 17-32-18

Of course, those are anonymized contracts but are able to reproduce the issue well.

The problem seems to occur when two contracts import other two different ones with the same alias (in this case Errors) and one inherit from another. Another example that comes to mind, could be for example, if two different Math libraries are imported as Math.

It doesn't stop the execution of slither, but it is indeed not able to generate the IR for the mentioned cases.

Debbuging the issue

Our working contracts are:


import {
    AccessControlErrors as Errors 
} from "../errors/ParentContractErrors.sol";


contract ParentContract {
     
     
    function functionWithAccessControlErrors1(uint256 a, uint256 b) external pure returns (uint256) {
        if (a == b) {
            revert Errors.AccessControlErrors1();
        }
        return a + b;
    }

    function functionWithAccessControlErrors2(uint256 a, uint256 b) external pure returns (uint256) {
        if (a < b) {
            revert Errors.AccessControlErrors2();
        }
        return a - b;
    }

  
 import {
    ParentContract
} from "./ParentContract.sol";

import {
    MainErrors as Errors
} from "./../errors/MainErrors.sol";


contract MainContract is ParentContract {

    
    function functionWithMainError1(uint256 a, uint256 b) external pure returns (uint256) {
        if (a == b) {
            revert Errors.MainError1();
        }

        return a + b;
    }

    function functionWithMainError2(uint256 a, uint256 b) external pure returns (uint256) {
        if (a < b) {
            revert Errors.MainError2();
        }

        return a - b;
    }

    function functionWithMainError3(uint256 a, uint256 b) external pure returns (uint256) {
        if (b == 0) {
            revert Errors.MainError3();
        }

        return a * b;
    }


}

Analyzing and debbuging the code, the issue seems to be in the find_variable.py file and find_variable function, especifically in the following lines of code:
Captura de pantalla de 2024-05-07 18-19-56

Indeed if we see what is happening with a acouple of prints, like this:
Captura de pantalla de 2024-05-07 18-25-53

For call Errors.functionWithAccessControlErrors1 and Errors.functionWithAccessControlErrors1, we obtain the following output:

Parsing find variable  var_name in current_scope.renaming = True
Parsing find variable  original var_name = Errors
Parsing find variable  var_name = MainErrors

Which, makes this section evaluate to true:

Captura de pantalla de 2024-05-07 18-40-44

And return the parsed expression as MainErrors.AccessControlErrors1() and MainErrors.AccessControlErrors2(). Those errors do not exist for that contract, through it fails to generate the IR.

Proposed solution

In order to correctly check where to fix the issue, we can print the underlaying function being call in the find variable contract like this:
Captura de pantalla de 2024-05-07 18-48-25

That returns, for the second one, for example:

Parsing find variable  underlying_func = functionWithAccessControlErrors2

We can see that there seem to be no mention to AccessControlErrors2(), just to the ParentContract's functions. So we cannot really check there if the final function (AccessControlErrors1 or AccessControlErrors2) function is declared in the var_name contract in this part.

However, if we debug the expression parsing file, at the parse_expression function, we can see that it goes to the Identifier branch in order to call find_variable and printing the expression:

Captura de pantalla de 2024-05-07 19-18-50

It returns the following:

Parsing Identifier expression = {'id': 120, 'name': 'Errors', 'nodeType': 'Identifier', 'overloadedDeclarations': [], 'referencedDeclaration': 149, 'src': '543:6:1', 'typeDescriptions': {'typeIdentifier': 't_type$_t_contract$_AccessControlErrors_$149_$', 'typeString': 'type(library AccessControlErrors)'}}

We see there that it is indeed, identifying there the correct library. So a way to solve the issue, could be, after finding the variable, if the variable is a contract and the typeString value is algo a contract, change the var to the contract at the expression, like this:

     pattern = r'\b(\w+)\s*\)'

     type_string = expression["typeDescriptions"]["typeString"]

     type_string_name = re.search(pattern, type_string)

     if type_string_name:
         found_contract = type_string_name.group(1)
         all_contracts_dict = {c.name: c for c in caller_context.compilation_unit.contracts}

         if str(var) in all_contracts_dict.keys() and found_contract in all_contracts_dict.keys():
             if str(var) != found_contract:
                 var = all_contracts_dict[found_contract]

Captura de pantalla de 2024-05-07 19-24-39

Of course, could be other solutions.

We have implemented this at: https://github.com/halbornlabs/slither and will do a pull request.

Code example to reproduce the issue:

https://github.com/MarHalborn/slither-inheritance-issue.git

Version:

0.10.0

Relevant log output:

ERROR:ContractSolcParsing:Impossible to generate IR for MainContract.functionWithAccessControlErrors1 (contracts/core/ParentContract.sol#13-18):
 'NoneType' object has no attribute 'parameters'
ERROR:ContractSolcParsing:Impossible to generate IR for MainContract.functionWithAccessControlErrors2 (contracts/core/ParentContract.sol#20-25):
 'NoneType' object has no attribute 'parameters'
@MarHalborn MarHalborn added the bug-candidate Bugs reports that are not yet confirmed label May 7, 2024
@0xalpharush
Copy link
Member

@MarHalborn Would you upgrade to the latest slither version as the latest release fixed many issues related to aliased imports? Let us know if it is still not working please

@MarHalborn
Copy link
Author

MarHalborn commented May 10, 2024

@0xalpharush I tested with the last version on the master branch of slither and encontoured the issue (it says latest commit was last month, I downloaded it last week )

@0xalpharush 0xalpharush added bug Something isn't working and removed bug-candidate Bugs reports that are not yet confirmed labels May 10, 2024
@0xalpharush 0xalpharush changed the title [Bug-Candidate]: ERROR:ContractSolcParsing when using same alias for import [Bug]: ERROR:ContractSolcParsing when using same alias for import May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants