146 lines
4.7 KiB
Solidity
146 lines
4.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity >=0.7.0 <0.9.0;
|
|
|
|
import "../src/StdAssertions.sol";
|
|
import {Vm} from "../src/Vm.sol";
|
|
|
|
interface VmInternal is Vm {
|
|
function _expectCheatcodeRevert(bytes memory message) external;
|
|
}
|
|
|
|
contract StdAssertionsTest is StdAssertions {
|
|
string constant errorMessage = "User provided message";
|
|
uint256 constant maxDecimals = 77;
|
|
|
|
bool constant SHOULD_REVERT = true;
|
|
bool constant SHOULD_RETURN = false;
|
|
|
|
bool constant STRICT_REVERT_DATA = true;
|
|
bool constant NON_STRICT_REVERT_DATA = false;
|
|
|
|
VmInternal constant vm = VmInternal(address(uint160(uint256(keccak256("hevm cheat code")))));
|
|
|
|
function testFuzz_AssertEqCall_Return_Pass(
|
|
bytes memory callDataA,
|
|
bytes memory callDataB,
|
|
bytes memory returnData,
|
|
bool strictRevertData
|
|
) external {
|
|
address targetA = address(new TestMockCall(returnData, SHOULD_RETURN));
|
|
address targetB = address(new TestMockCall(returnData, SHOULD_RETURN));
|
|
|
|
assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData);
|
|
}
|
|
|
|
function testFuzz_RevertWhenCalled_AssertEqCall_Return_Fail(
|
|
bytes memory callDataA,
|
|
bytes memory callDataB,
|
|
bytes memory returnDataA,
|
|
bytes memory returnDataB,
|
|
bool strictRevertData
|
|
) external {
|
|
vm.assume(keccak256(returnDataA) != keccak256(returnDataB));
|
|
|
|
address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN));
|
|
address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN));
|
|
|
|
vm._expectCheatcodeRevert(
|
|
bytes(
|
|
string.concat(
|
|
"Call return data does not match: ", vm.toString(returnDataA), " != ", vm.toString(returnDataB)
|
|
)
|
|
)
|
|
);
|
|
assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData);
|
|
}
|
|
|
|
function testFuzz_AssertEqCall_Revert_Pass(
|
|
bytes memory callDataA,
|
|
bytes memory callDataB,
|
|
bytes memory revertDataA,
|
|
bytes memory revertDataB
|
|
) external {
|
|
address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT));
|
|
address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT));
|
|
|
|
assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA);
|
|
}
|
|
|
|
function testFuzz_RevertWhenCalled_AssertEqCall_Revert_Fail(
|
|
bytes memory callDataA,
|
|
bytes memory callDataB,
|
|
bytes memory revertDataA,
|
|
bytes memory revertDataB
|
|
) external {
|
|
vm.assume(keccak256(revertDataA) != keccak256(revertDataB));
|
|
|
|
address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT));
|
|
address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT));
|
|
|
|
vm._expectCheatcodeRevert(
|
|
bytes(
|
|
string.concat(
|
|
"Call revert data does not match: ", vm.toString(revertDataA), " != ", vm.toString(revertDataB)
|
|
)
|
|
)
|
|
);
|
|
assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA);
|
|
}
|
|
|
|
function testFuzz_RevertWhenCalled_AssertEqCall_Fail(
|
|
bytes memory callDataA,
|
|
bytes memory callDataB,
|
|
bytes memory returnDataA,
|
|
bytes memory returnDataB,
|
|
bool strictRevertData
|
|
) external {
|
|
address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN));
|
|
address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT));
|
|
|
|
vm.expectRevert(bytes("assertion failed"));
|
|
this.assertEqCallExternal(targetA, callDataA, targetB, callDataB, strictRevertData);
|
|
|
|
vm.expectRevert(bytes("assertion failed"));
|
|
this.assertEqCallExternal(targetB, callDataB, targetA, callDataA, strictRevertData);
|
|
}
|
|
|
|
// Helper function to test outcome of assertEqCall via `expect` cheatcodes
|
|
function assertEqCallExternal(
|
|
address targetA,
|
|
bytes memory callDataA,
|
|
address targetB,
|
|
bytes memory callDataB,
|
|
bool strictRevertData
|
|
) public {
|
|
assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData);
|
|
}
|
|
|
|
function testFailFail() public {
|
|
fail();
|
|
}
|
|
}
|
|
|
|
contract TestMockCall {
|
|
bytes returnData;
|
|
bool shouldRevert;
|
|
|
|
constructor(bytes memory returnData_, bool shouldRevert_) {
|
|
returnData = returnData_;
|
|
shouldRevert = shouldRevert_;
|
|
}
|
|
|
|
fallback() external payable {
|
|
bytes memory returnData_ = returnData;
|
|
|
|
if (shouldRevert) {
|
|
assembly {
|
|
revert(add(returnData_, 0x20), mload(returnData_))
|
|
}
|
|
} else {
|
|
assembly {
|
|
return(add(returnData_, 0x20), mload(returnData_))
|
|
}
|
|
}
|
|
}
|
|
}
|