Sitelet https://web.archive.org/web/20201113050405/https://github.com/ethereum/solidity/pull/8916
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

[SMTChecker] Support array push/pop #8916

Merged
merged 5 commits into from May 19, 2020
Merged

[SMTChecker] Support array push/pop #8916

merged 5 commits into from May 19, 2020

Conversation

@leonardoalt
Copy link
Member

@leonardoalt leonardoalt commented May 12, 2020 •

Fixes #6048
Depends on #8848

  • Needs more tests
  • push: add implicit require that array.length < 2^256 - 1 before the push (as a real world assumption)
  • document the assumption above
  • pop: add underflow verification target on length - 1 and do not wrap
@leonardoalt leonardoalt mentioned this pull request May 12, 2020
0 of 3 tasks complete
@elenadimitrova elenadimitrova added this to In progress in Solidity via automation May 14, 2020
@leonardoalt leonardoalt mentioned this pull request May 15, 2020
3 of 3 tasks complete
@leonardoalt leonardoalt force-pushed the smt_array_push_pop branch from dc0c66b to 9d82a54 May 15, 2020
@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 15, 2020

Rebased

Copy link
Member

@ekpyron ekpyron left a comment

This looks good, but as you said: it needs tests.

Do you see a better solution for the edge cases where the length overflows? The current behaviour is silently wrap around, right? There probably shouldn't be an overflow warning for that, because it can never really happen in practice... However, what about something like the following:

contract C {
  uint256[] x;
  constructor() public { x.push(42); }
  function f() public {
    x.push(23);
    assert(x[0] == 42);
  }
}

in practice this assertion should always hold (in CHC), but in your encoding it will break, because you can call f 2^256 times and have x[0] == 23, right?
Is this a problem :-)?

Similarly maybe something like:

contract C {
  uint256[] x;
  function f(uint256 l) public {
    require(x.length == 0);
    x.push(42);
    x.push(84);
    for(uint256 i = 0; i < l; ++i)
      x.push(23);
    assert(x[0] == 42);
  }
}

when calling f with sufficiently large l...

I just looked at our codegen, in fact it will silently wrap around in those cases... still a bit weird to have such assertions as in the examples break because of that, because in practice there can never be such an overflow...

libsolidity/formal/SMTEncoder.cpp Outdated Show resolved Hide resolved
@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 15, 2020

Well, I think your examples should work just as you described. In practice this would all run out of gas I suppose, but the semantics of the language are exactly as you described, so I think the SMTChecker should do the same (currently implementation).

@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 15, 2020 •

@ekpyron

in practice this assertion should always hold (in CHC), but in your encoding it will break, because you can call f 2^256 times and have x[0] == 23, right?

I think this assertion should break, for the reasons you described

@ekpyron
Copy link
Member

@ekpyron ekpyron commented May 15, 2020

Ok... I'm just wondering if we didn't get more natural results, if we considered an imaginary require(x.length < 2^256-1) before any x.push... but this is a slippery slope...

@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 15, 2020

We could also do that, but then we'll report some false negatives for cases where the overflow actually happens...
Do we have any limit like that in the code generator?

@leonardoalt leonardoalt force-pushed the smt_array_push_pop branch from 0d3c184 to c4f5d6a May 18, 2020
@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 18, 2020

Ready for review

@leonardoalt leonardoalt force-pushed the smt_array_push_pop branch from c4f5d6a to 317476c May 18, 2020
@leonardoalt leonardoalt force-pushed the smt_array_push_pop branch from 317476c to 5d6dd68 May 18, 2020
@leonardoalt
Copy link
Member Author

@leonardoalt leonardoalt commented May 19, 2020

@chriseth updated

@chriseth chriseth merged commit 3b27b43 into develop May 19, 2020
34 checks passed
34 checks passed
ci/circleci: b_archlinux Your tests passed on CircleCI!
Details
ci/circleci: b_docs Your tests passed on CircleCI!
Details
ci/circleci: b_ems Your tests passed on CircleCI!
Details
ci/circleci: b_osx Your tests passed on CircleCI!
Details
ci/circleci: b_ubu Your tests passed on CircleCI!
Details
ci/circleci: b_ubu18 Your tests passed on CircleCI!
Details
ci/circleci: b_ubu_asan Your tests passed on CircleCI!
Details
ci/circleci: b_ubu_clang Your tests passed on CircleCI!
Details
ci/circleci: b_ubu_cxx20 Your tests passed on CircleCI!
Details
ci/circleci: b_ubu_ossfuzz Your tests passed on CircleCI!
Details
ci/circleci: b_ubu_release Your tests passed on CircleCI!
Details
ci/circleci: chk_antlr_grammar Your tests passed on CircleCI!
Details
ci/circleci: chk_buglist Your tests passed on CircleCI!
Details
ci/circleci: chk_coding_style Your tests passed on CircleCI!
Details
ci/circleci: chk_docs_pragma_min_version Your tests passed on CircleCI!
Details
ci/circleci: chk_proofs Your tests passed on CircleCI!
Details
ci/circleci: chk_pylint Your tests passed on CircleCI!
Details
ci/circleci: chk_spelling Your tests passed on CircleCI!
Details
ci/circleci: t_ems_compile_ext_colony Your tests passed on CircleCI!
Details
ci/circleci: t_ems_compile_ext_gnosis Your tests passed on CircleCI!
Details
ci/circleci: t_ems_compile_ext_zeppelin Your tests passed on CircleCI!
Details
ci/circleci: t_ems_solcjs Your tests passed on CircleCI!
Details
ci/circleci: t_osx_cli Your tests passed on CircleCI!
Details
ci/circleci: t_osx_soltest Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_asan_cli Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_asan_constantinople Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_clang_soltest Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_cli Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_release_cli Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_release_soltest Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_soltest Your tests passed on CircleCI!
Details
ci/circleci: t_ubu_soltest_enforce_yul Your tests passed on CircleCI!
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
Solidity automation moved this from In progress to Done May 19, 2020
@chriseth chriseth deleted the smt_array_push_pop branch May 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Solidity
  
Done
Linked issues

Successfully merging this pull request may close these issues.

3 participants
You can’t perform that action at this time.