Skip to content

vm.canRevert(): allow tests to revert in expected cases #4090

Closed
@0xPhaze

Description

Component

Forge

Describe the feature you would like

Often it's desirable to check properties of results, such as a new price of an AMM. However, these functions can contain error-checks and revert on certain inputs. And sometimes I want to make sure a property holds only if I actually get a result from a call and ignore the reverting cases.

An example of what this could look like is:

    function test_getPrice_invariant(uint256 x, uint256 dx) public {
        dx = bound(dx, 0, type(uint256).max - x);

        vm.canRevert(Overflow.selector);
        uint256 y1 = amm.getPrice(x);

        vm.canRevert(Overflow.selector);
        uint256 y2 = amm.getPrice(x + dx);
        
        assertGte(y2, y1);
    }

A current workaround is to use low-level calls or try ... catch ..., but these have to be set up for each function manually.

    function getPrice_canRevert(uint256 x, bytes4 selector) internal returns (uint256) {
        try amm.getPrice(x) returns (uint256 price) {
            return price;
        } catch (bytes memory reason) {
            require(bytes4(reason) == selector, "unexpected revert");
        }
    }

An implementation of vm.canRevert/vm.allowRevert could add to the counter of vm.assume checks to make sure that one isn't rejecting all calls.

Additional context

No response

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions