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

Issue with casting and verifier functions #146

Open
dddejan opened this issue Jun 16, 2020 · 5 comments
Open

Issue with casting and verifier functions #146

dddejan opened this issue Jun 16, 2020 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@dddejan
Copy link
Member

dddejan commented Jun 16, 2020

pragma solidity >=0.5.0;

contract FunctionArgs {

  uint8 x;
  uint y;

  /// postcondition x == __verifier_old_uint(x)
  function noop() public view returns (bool ok) {
    assert(x == y);
    return true;
  }
}

Gives

$ solc-verify.py FunctionArgs.sol --arith bv --output .
Error while running verifier, details:
Parsing ./FunctionArgs.sol.bpl
./FunctionArgs.sol.bpl(23,172): Error: invalid argument types (bv256 and bv8) to binary operator ==
1 type checking errors detected in ./FunctionArgs.sol.bpl

The culprit is the old expression bvzeroext_8_to_256(x#3[__this]) == old(x#3[__this]).

@dddejan dddejan added the bug Something isn't working label Jun 16, 2020
@hajduakos
Copy link
Member

#85 is also related

@hajduakos
Copy link
Member

A straightforward solution would be of course to have __verifier_old_uintN for N=8, ..., 256. But if I remember correctly, our plan was to rather support some kind of polymorphism.

@dddejan
Copy link
Member Author

dddejan commented Jun 16, 2020

This happens because in the case of VERIFIER_* functions there is an if statement when converting arguments that skips temp variables for arguments. I guess this is a hack to prevent side-effects. We need a more pragmatic way to deal with functions that can be used in specification. I am trying to figure out, e.g., how to use keccak in specification and I'm running into similar issues.

@hajduakos
Copy link
Member

Incorporating those temp variables could make this example work, because it would translate to bvzeroext_8_to_256(x#3[__this]) == old(bvzeroext_8_to_256(x#3[__this])). However, this would not work for #85. What we'd really like to have here is x#3[__this] == old(x#3[__this]), i.e., no casts at all. For this, we would need the Solidity AST for the spec expression to have the old expression return type uint8. Then the operator == will see that both of its arguments are uint8 and no casting is needed.

@hajduakos
Copy link
Member

Of course there might be some special functions where the casting is needed, e.g., if keccak takes uint256 then the temp variables should be included because those will do the cast. But for old, there should be no casting.

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