Skip to content

havoc: potentially missing havoc for unresolved call #98

Description

@intrigus-lgtm

Maybe this is intentional, but I could readily find information about it.

An unresolved regular call havocs the balance map and then incorrectly pins the callee's own balance to its pre-call value, excluding fallbacks that spend or forward funds.

So something like

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

contract Repro {
    function ping(address dst) external {
        (bool ok,) = dst.call("");
        require(ok);
    }
}
rule unresolvedCalleeCannotSpend(address dst) {
    env e;
    require dst != currentContract;
    uint256 before = nativeBalances[dst];
    ping(e, dst);
    // False in reality: dst's fallback can transfer its existing balance away.
    assert nativeBalances[dst] == before;
}

can be verified (not violated) while dst's fallback could transfer its balance.

Reproduce

Unpack repro.tar.gz

certoraRun.py Repro.conf

Actual: Rule is verified.
Expected: Rule should probably be violated?

Version

Self-built 07.07.26 Release

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions