Add Halmos support for formal verification (#5034)

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
This commit is contained in:
Ernesto García
2024-05-23 09:01:12 -06:00
committed by GitHub
parent 9de916dd9c
commit f1a69f164e
17 changed files with 197 additions and 38 deletions

View File

@ -3,48 +3,102 @@
pragma solidity ^0.8.20;
import {Test} from "forge-std/Test.sol";
import {SymTest} from "halmos-cheatcodes/SymTest.sol";
import {ShortStrings, ShortString} from "@openzeppelin/contracts/utils/ShortStrings.sol";
contract ShortStringsTest is Test {
contract ShortStringsTest is Test, SymTest {
string _fallback;
function testRoundtripShort(string memory input) external {
vm.assume(_isShort(input));
_assertRoundtripShort(input);
}
function symbolicRoundtripShort() external {
string memory input = svm.createString(31, "RoundtripShortInput");
_assertRoundtripShort(input);
}
function testRoundtripWithFallback(string memory input, string memory fallbackInitial) external {
_assertRoundtripWithFallback(input, fallbackInitial);
}
function symbolicRoundtripWithFallbackLong() external {
string memory input = svm.createString(256, "RoundtripWithFallbackInput");
string memory fallbackInitial = svm.createString(256, "RoundtripWithFallbackFallbackInitial");
_assertRoundtripWithFallback(input, fallbackInitial);
}
function symbolicRoundtripWithFallbackShort() external {
string memory input = svm.createString(31, "RoundtripWithFallbackInput");
string memory fallbackInitial = svm.createString(31, "RoundtripWithFallbackFallbackInitial");
_assertRoundtripWithFallback(input, fallbackInitial);
}
function testRevertLong(string memory input) external {
vm.assume(!_isShort(input));
_assertRevertLong(input);
}
function testLengthShort(string memory input) external {
vm.assume(_isShort(input));
_assertLengthShort(input);
}
function symbolicLengthShort() external {
string memory input = svm.createString(31, "LengthShortInput");
_assertLengthShort(input);
}
function testLengthWithFallback(string memory input, string memory fallbackInitial) external {
_fallback = fallbackInitial;
_assertLengthWithFallback(input);
}
function symbolicLengthWithFallback() external {
uint256 length = 256;
string memory input = svm.createString(length, "LengthWithFallbackInput");
string memory fallbackInitial = svm.createString(length, "LengthWithFallbackFallbackInitial");
_fallback = fallbackInitial;
_assertLengthWithFallback(input);
}
/// Assertions
function _assertRoundtripShort(string memory input) internal {
ShortString short = ShortStrings.toShortString(input);
string memory output = ShortStrings.toString(short);
assertEq(input, output);
}
function testRoundtripWithFallback(string memory input, string memory fallbackInitial) external {
function _assertRoundtripWithFallback(string memory input, string memory fallbackInitial) internal {
_fallback = fallbackInitial; // Make sure that the initial value has no effect
ShortString short = ShortStrings.toShortStringWithFallback(input, _fallback);
string memory output = ShortStrings.toStringWithFallback(short, _fallback);
assertEq(input, output);
}
function testRevertLong(string memory input) external {
vm.assume(!_isShort(input));
function _assertRevertLong(string memory input) internal {
vm.expectRevert(abi.encodeWithSelector(ShortStrings.StringTooLong.selector, input));
this.toShortString(input);
}
function testLengthShort(string memory input) external {
vm.assume(_isShort(input));
uint256 inputLength = bytes(input).length;
function _assertLengthShort(string memory input) internal {
ShortString short = ShortStrings.toShortString(input);
uint256 shortLength = ShortStrings.byteLength(short);
uint256 inputLength = bytes(input).length;
assertEq(inputLength, shortLength);
}
function testLengthWithFallback(string memory input, string memory fallbackInitial) external {
_fallback = fallbackInitial;
function _assertLengthWithFallback(string memory input) internal {
uint256 inputLength = bytes(input).length;
ShortString short = ShortStrings.toShortStringWithFallback(input, _fallback);
uint256 shortLength = ShortStrings.byteLengthWithFallback(short, _fallback);
assertEq(inputLength, shortLength);
}
/// Helpers
function toShortString(string memory input) external pure returns (ShortString) {
return ShortStrings.toShortString(input);
}