Skip to content

Commit

Permalink
Merge pull request #45 from obatirou/oba-evm-version-option
Browse files Browse the repository at this point in the history
feat: evm allow developers to specify an evm version
  • Loading branch information
Maddiaa0 authored Jul 10, 2023
2 parents e691315 + 8cb4323 commit bcac40d
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 25 deletions.
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ out = 'out'
libs = ['lib']
ffi = true
fuzz_runs = 2_000

solc_version = '0.8.20'
evm_version = 'shanghai'
[fmt]
line_length = 100
28 changes: 24 additions & 4 deletions src/HuffConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ contract HuffConfig {
/// @notice whether to broadcast the deployment tx
bool public should_broadcast;

/// @notice supported evm versions
string public evm_version;

/// @notice constant overrides for the current compilation environment
Constant[] public const_overrides;

Expand Down Expand Up @@ -59,6 +62,12 @@ contract HuffConfig {
return this;
}

/// @notice sets the evm version to compile with
function with_evm_version(string memory _evm_version) public returns (HuffConfig) {
evm_version = _evm_version;
return this;
}

/// @notice sets a constant to a bytes memory value in the current compilation environment
/// @dev The `value` string must contain a valid hex number that is <= 32 bytes
/// i.e. "0x01", "0xa57b", "0x0de0b6b3a7640000", etc.
Expand Down Expand Up @@ -124,6 +133,15 @@ contract HuffConfig {
return string(str);
}

/// @notice Get the evm version string | else return default ("shanghai")
function get_evm_version() public view returns (string memory) {
bytes32 _evm_version = bytes32(bytes(abi.encodePacked(evm_version)));
if (_evm_version == bytes32(0x0)) {
return "shanghai";
}
return evm_version;
}

/// @notice Get the creation bytecode of a contract
function creation_code(string memory file) public payable returns (bytes memory bytecode) {
binary_check();
Expand Down Expand Up @@ -169,21 +187,23 @@ contract HuffConfig {
vm.ffi(append_cmds);

/// Create a list of strings with the commands necessary to compile Huff contracts
string[] memory cmds = new string[](3);
string[] memory cmds = new string[](5);
if (const_overrides.length > 0) {
cmds = new string[](4 + const_overrides.length);
cmds[3] = "-c";
cmds = new string[](6 + const_overrides.length);
cmds[5] = "-c";

Constant memory cur_const;
for (uint256 i; i < const_overrides.length; i++) {
cur_const = const_overrides[i];
cmds[4 + i] = string.concat(cur_const.key, "=", cur_const.value);
cmds[6 + i] = string.concat(cur_const.key, "=", cur_const.value);
}
}

cmds[0] = "huffc";
cmds[1] = string(string.concat("src/", tempFile, ".huff"));
cmds[2] = "-b";
cmds[3] = "-e";
cmds[4] = get_evm_version();

/// @notice compile the Huff contract and return the bytecode
bytecode = vm.ffi(cmds);
Expand Down
5 changes: 5 additions & 0 deletions src/test/HuffConfig.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ contract HuffConfigTest is Test {
bool b = config.should_broadcast();
assertEq(b, broadcast);
}

function testWithEvmVersion() public {
config.with_evm_version("paris");
assertEq(config.evm_version(), "paris");
}
}
58 changes: 51 additions & 7 deletions src/test/HuffDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ contract HuffDeployerTest is Test {
number = INumber(HuffDeployer.deploy("test/contracts/Number"));

// Backwards-compatible Constructor creation
vm.expectEmit(true, true, true, true);
emit ArgumentsUpdated(address(0x420), uint256(0x420));
vm.recordLogs();
structor = IConstructor(
HuffDeployer.deploy_with_args(
"test/contracts/Constructor",
bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420)))
)
);
Vm.Log[] memory entries = vm.getRecordedLogs();

assertEq(entries.length, 1);
assertEq(entries[0].topics.length, 3);
assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)"))));
assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420)))));
assertEq(entries[0].topics[2], bytes32(uint256(0x420)));

}

function testChaining() public {
Expand Down Expand Up @@ -57,14 +64,20 @@ contract HuffDeployerTest is Test {
" log3 // [] \n" "}";

// New pattern
vm.expectEmit(true, true, true, true);
emit ArgumentsUpdated(address(0x420), uint256(0x420));
vm.recordLogs();
IConstructor chained = IConstructor(
HuffDeployer.config().with_args(
bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420)))
).with_code(constructor_macro).deploy("test/contracts/NoConstructor")
);

Vm.Log[] memory entries = vm.getRecordedLogs();
assertEq(entries.length, 1);
assertEq(entries[0].topics.length, 3);
assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)"))));
assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420)))));
assertEq(entries[0].topics[2], bytes32(uint256(0x420)));

assertEq(address(0x420), chained.getArgOne());
assertEq(uint256(0x420), chained.getArgTwo());
}
Expand Down Expand Up @@ -93,13 +106,19 @@ contract HuffDeployerTest is Test {
" log3 // [] \n" "}";

// New pattern
vm.expectEmit(true, true, true, true);
emit ArgumentsUpdated(address(0x420), uint256(0x420));
vm.recordLogs();
IConstructor chained = IConstructor(
HuffDeployer.config_with_create_2(1).with_args(bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420))))
.with_code(constructor_macro).deploy("test/contracts/NoConstructor")
);

Vm.Log[] memory entries = vm.getRecordedLogs();
assertEq(entries.length, 1);
assertEq(entries[0].topics.length, 3);
assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)"))));
assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420)))));
assertEq(entries[0].topics[2], bytes32(uint256(0x420)));

assertEq(address(0x420), chained.getArgOne());
assertEq(uint256(0x420), chained.getArgTwo());
}
Expand All @@ -114,7 +133,7 @@ contract HuffDeployerTest is Test {

function testBytecode() public {
bytes memory b = bytes(
hex"60003560e01c80633fb5c1cb1461001c578063f2c9ecd814610023575b6004356000555b60005460005260206000f3"
hex"5f3560e01c80633fb5c1cb1461001b578063f2c9ecd814610021575b6004355f555b5f545f5260205ff3"
);
assertEq(getCode(address(number)), b);
}
Expand Down Expand Up @@ -229,4 +248,29 @@ contract HuffDeployerTest is Test {
runTestConstructorCaller(address(0));
runTestConstructorCaller(address(uint160(0x1000)));
}

/// @dev test that compilation is different with new evm versions
function testSettingEVMVersion() public {
/// expected bytecode for EVM version "paris"
bytes memory expectedParis = hex"6000";
HuffConfig config = HuffDeployer.config().with_evm_version("paris");
address withParis = config.deploy("test/contracts/EVMVersionCheck");

bytes memory parisBytecode = withParis.code;
assertEq(parisBytecode, expectedParis);

/// expected bytecode for EVM version "shanghai" | default
bytes memory expectedShanghai = hex"5f";
HuffConfig shanghaiConfig = HuffDeployer.config().with_evm_version("shanghai");
address withShanghai = shanghaiConfig.deploy("test/contracts/EVMVersionCheck");
bytes memory shanghaiBytecode = withShanghai.code;
assertEq(shanghaiBytecode, expectedShanghai);

/// Default should be shanghai (latest)
HuffConfig defaultConfig = HuffDeployer.config().with_evm_version("");
address withDefault = defaultConfig.deploy("test/contracts/EVMVersionCheck");

bytes memory defaultBytecode = withDefault.code;
assertEq(defaultBytecode, expectedShanghai);
}
}
37 changes: 24 additions & 13 deletions src/test/Logging.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,34 @@ contract LoggingTest is Test {
);

function testLoggingWithArgs() public {
// Ignore the second topic (address) since the internal HuffConfig is the msg.sender
vm.expectEmit(false, true, true, true);
emit LogOne();
emit LogTwo(address(0));
emit LogThree(address(0), 0);
emit LogFour(address(0), 0, keccak256(abi.encode(1)));
emit Extended(
address(0),
0,
keccak256(abi.encode(1)),
keccak256(abi.encode(2)),
keccak256(abi.encode(3))
);
vm.recordLogs();
HuffDeployer.deploy_with_args(
"test/contracts/LotsOfLogging",
bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420)))
);
Vm.Log[] memory entries = vm.getRecordedLogs();

assertEq(entries.length, 5);
assertEq(entries[0].topics.length, 1);
assertEq(entries[0].topics[0], bytes32(uint256(keccak256("LogOne()"))));
assertEq(entries[1].topics.length, 2);
assertEq(entries[1].topics[0], bytes32(uint256(keccak256("LogTwo(address)"))));
// assertEq(entries[1].topics[1], ?); should be address from deployed config
assertEq(entries[2].topics.length, 3);
assertEq(entries[2].topics[0], bytes32(uint256(keccak256("LogThree(address,uint256)"))));
// assertEq(entries[2].topics[1], ?); should be address from deployed config
assertEq(entries[2].topics[2], bytes32(uint256(0x0)));
assertEq(entries[3].topics.length, 4);
assertEq(entries[3].topics[0], bytes32(uint256(keccak256("LogFour(address,uint256,bytes32)"))));
// assertEq(entries[3].topics[1], ?); should be address from deployed config
assertEq(entries[3].topics[2], bytes32(uint256(0x0)));
assertEq(entries[3].topics[3], bytes32(uint256(keccak256(abi.encode(1)))));
assertEq(entries[4].topics.length, 4);
assertEq(entries[4].topics[0], bytes32(uint256(keccak256("Extended(address,uint256,bytes32,bytes32,bytes32)"))));
// assertEq(entries[4].topics[1], ?); should be address from deployed config
assertEq(entries[4].topics[2], bytes32(uint256(0x0)));
assertEq(entries[4].topics[3], bytes32(uint256(keccak256(abi.encode(1)))));
assertEq(entries[4].data, abi.encode(keccak256(abi.encode(2)), keccak256(abi.encode(3))));
}

function testLoggingWithDeploy() public {
Expand Down
5 changes: 5 additions & 0 deletions src/test/contracts/EVMVersionCheck.huff
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


#define macro MAIN() = {
0x00
}

0 comments on commit bcac40d

Please sign in to comment.