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

slither-check-upgradeability: support complex datatypes #1535

Merged

Conversation

webthethird
Copy link
Contributor

@webthethird webthethird commented Dec 28, 2022

Addresses #185, an old one, but still an issue!

Resolves false positives when comparing storage layouts that use structure types (test contracts and updated CI test included).

Currently only addresses structures, but I can add more here to resolve comparisons between other complex types, i.e., contract types and enums. (edit: Contract types also supported, at least on a superficial level, i.e., using the current Contract.__eq__() method which only works when comparing a contract object to another contract's name)

@webthethird webthethird changed the base branch from master to dev December 28, 2022 17:57
@webthethird
Copy link
Contributor Author

@montyly @0xalpharush got any advice re: how to fix these failing checks? It seems like the pip-audit may be unrelated to the content of this PR, since I'm suddenly getting the same issue on #1506 (this check was passing before). As for the Features and Printers tests, it's not immediately clear to me why these are failing, though they seem to be possibly related to recursively nested structures. I just don't understand how the __eq__() method I implemented would affect those, when there's no equality comparison being done.

to avoid infinite loops from recursive structs
@webthethird
Copy link
Contributor Author

Alright, my last commit resolved the infinite loop issue with recursively nested structures, but I still don't get why the printers test is failing. I tried commenting out my __eq__() implementation entirely and running ci_test_printers.sh without it, but the test still fails with the following error message:

Printer failed
functioncall-0.5.3.sol-0.5.17-compact.zip

@webthethird
Copy link
Contributor Author

@0xalpharush @montyly my latest commit resolved the printer test issue (which was related to the human-summary printer and one of the detectors failing to hash a Structure object). This time the slither-read-storage test inexplicably failed to install Ganache, and of course pip-audit is still failing, though I saw that there's a separate issue now to fix the latter. Anyway, I'm pretty confident that all issues related to my code additions have been resolved.

return False
for idx, elem in enumerate(self.elems_ordered):
other_elem = other.elems_ordered[idx]
if str(other_elem.type) != str(elem.type) or other_elem.name != elem.name:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might create issue where two types share the same name

For example in

struct St{
	uint a;
}

contract A{

	St s;

}
import {A} from "test.sol";

struct St{
	uint b;
}

contract B is A{
	St s2;
}

Maybe we should create a canonical_name for type that would include the source mapping definition? (cc @smonicas @0xalpharush)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like canonical_name would be a good idea. But in the example you gave, wouldn't it be correct to say that the two St structs are not equal? In the highlighted code, while enumerating the elements of the two structs, the other_elem.name != elem.name would cause my __eq__() implementation to return False, which seems correct at a glance. Granted, comparing canonical names would probably be better still.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose if you renamed St.b in the second code block to uint a, then the resulting equality might be considered a false positive, since it would see that both structs have the same name, and their elements have the same types and names, therefore returning true. But that seems quite picky, since the two structs would be identical except for where they are defined in Solidity.

@montyly montyly merged commit 1d52aea into crytic:dev Feb 15, 2023
@webthethird webthethird deleted the slither/dev-upgradeability-complex-datatype branch March 15, 2023 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants