-
Notifications
You must be signed in to change notification settings - Fork 97
Description
Describe the bug
This code:
import {Test} from "forge-std/Test.sol";
contract MyContract is Test {
mapping (uint => uint) balances;
function setUp() public {
balances[0xfaaaaaffafafafafaaaaa472134] = 50;
}
function prove_keccak_wrong(uint amt) public view {
bytes32 hash = keccak256(abi.encodePacked(amt));
uint balance = balances[uint(hash)];
assert(balance != 50);
}
}
Will find a CEx with latest halmos:
$ halmos --function "prove_keccak_wrong"
[⠒] Compiling...
No files changed, compilation skipped
Running 1 tests for src/contract-keccak.sol:MyContract
Counterexample:
p_amt_uint256_928e027_00 = 0x00
[FAIL] prove_keccak_wrong(uint256) (paths: 2, time: 0.12s, bounds: [])
Symbolic test result: 0 passed; 1 failed; time: 0.13s
The CEx is wrong. The issue is that due to uninterpreted function of Keccak, our systems both imagine that keccak(0) is 0xfaaaaaffafafafafaaaaa472134. It's hard to fix this, and it can unfortunately be triggered in a real-world scenario. If you look at the issue as tracked by us below, it starts with a real-world contract, that actually triggers this issue. The contract I wrote above this text is a minimized version of the problem.
Our issue tracker for this is here: argotorg/hevm#770 (comment)
To Reproduce
Reproducible as per above. I compiled with forge build --ast. Should work as-is. Let me know if it doesn't!
Environment:
- OS: Linux
- Python version: Python 3.13.5
- Halmos and other dependency versions: installed via
uv tool install --python 3.12 halmos, just today.halmos --versionsays:halmos 0.3.0
Additional context
It would be interesting to brainstorm how to solve this issue. It's non-trivial, I think, and it seems like both of our tools fail the same way :S
Let me know what you think! Would be nice to solve it, perhaps together :)