diff --git a/test/libsolidity/semanticTests/builtinFunctions/eof/keccak256_packed_complex_types.sol b/test/libsolidity/semanticTests/builtinFunctions/eof/keccak256_packed_complex_types.sol new file mode 100644 index 000000000000..c10faadfb291 --- /dev/null +++ b/test/libsolidity/semanticTests/builtinFunctions/eof/keccak256_packed_complex_types.sol @@ -0,0 +1,16 @@ +contract C { + uint120[3] x; + function f() public returns (bytes32 hash1, bytes32 hash2, bool hash3NonZero) { + uint120[] memory y = new uint120[](3); + x[0] = y[0] = uint120(type(uint).max - 1); + x[1] = y[1] = uint120(type(uint).max - 2); + x[2] = y[2] = uint120(type(uint).max - 3); + hash1 = keccak256(abi.encodePacked(x)); + hash2 = keccak256(abi.encodePacked(y)); + hash3NonZero = bytes32(0) != keccak256(abi.encodePacked(this.f)); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, true diff --git a/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol b/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol index ea6d781898f0..eab624dc3f2e 100644 --- a/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol +++ b/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol @@ -7,8 +7,10 @@ contract C { x[2] = y[2] = uint120(type(uint).max - 3); hash1 = keccak256(abi.encodePacked(x)); hash2 = keccak256(abi.encodePacked(y)); - hash3 = keccak256(abi.encodePacked(this.f)); + hash3 = keccak256(abi.encodePacked(C(address(0x1234)))); } } +// ==== +// bytecodeFormat: legacy // ---- -// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec +// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xe7490fade3a8e31113ecb6c0d2635e28a6f5ca8359a57afe914827f41ddf0848 diff --git a/test/libsolidity/semanticTests/constructor/callvalue_check.sol b/test/libsolidity/semanticTests/constructor/callvalue_check.sol index f45fbed925ad..10086886a622 100644 --- a/test/libsolidity/semanticTests/constructor/callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/callvalue_check.sol @@ -11,6 +11,7 @@ contract B4 { constructor() {} } contract C { function createWithValue(bytes memory c, uint256 value) public payable returns (bool) { uint256 y = 0; + // TODO: This test is hard to recreate for EOF as for now eofcreate is disallowed in inline assembly. assembly { y := create(value, add(c, 0x20), mload(c)) } return y != 0; } @@ -29,6 +30,7 @@ contract C { } // ==== // EVMVersion: >homestead +// bytecodeFormat: legacy // ---- // f(uint256), 2000 ether: 0 -> true // f(uint256), 2000 ether: 100 -> false diff --git a/test/libsolidity/semanticTests/constructor/eof/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/eof/no_callvalue_check.sol new file mode 100644 index 000000000000..8afab858bb7f --- /dev/null +++ b/test/libsolidity/semanticTests/constructor/eof/no_callvalue_check.sol @@ -0,0 +1,21 @@ +contract A1 {} +contract B1 is A1 { constructor() payable {} } + +contract A2 { constructor() {} } +contract B2 is A2 { constructor() payable {} } + +contract B3 { constructor() payable {} } + +contract C { + function f() public payable returns (bool) { + // Make sure none of these revert. + new B1{value: 10, salt: hex"00"}(); + new B2{value: 10, salt: hex"01"}(); + new B3{value: 10, salt: hex"02"}(); + return true; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(), 2000 ether -> true diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index 583f1ca37b3f..f067bb403e34 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -9,17 +9,19 @@ contract B3 { constructor() payable {} } contract C { function f() public payable returns (bool) { // Make sure none of these revert. - new B1{value: 10}(); - new B2{value: 10}(); - new B3{value: 10}(); + new B1{value: 10, salt: hex"00"}(); + new B2{value: 10, salt: hex"01"}(); + new B3{value: 10, salt: hex"02"}(); return true; } } +// ==== +// bytecodeFormat: legacy // ---- // f(), 2000 ether -> true -// gas irOptimized: 117623 +// gas irOptimized: 117688 // gas irOptimized code: 1800 -// gas legacy: 117821 +// gas legacy: 117889 // gas legacy code: 4800 -// gas legacyOptimized: 117690 +// gas legacyOptimized: 117761 // gas legacyOptimized code: 4800 diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol index 64b80422c352..69a4bd65b1d9 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. function longdata(S memory) pure returns (bytes memory) { return "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" @@ -36,5 +37,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol index 931109199649..28843b25d19d 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. library L { function longdata() pure internal returns (bytes memory) { return @@ -30,5 +31,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol index 018d410557b0..8e075654f313 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. ==== Source: mod.sol ==== function longdata() pure returns (bytes memory) { return @@ -32,5 +33,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol index 0f9b023b08d9..255e99e82489 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal pure returns (bytes memory) { return @@ -31,5 +32,7 @@ contract C is S { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol index b6ae85b838d8..4425475695a1 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. contract A { function longdata() pure external returns (bytes memory) { return @@ -37,5 +38,7 @@ contract C { x < 2 * type(A).creationCode.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol index 9accc54a2b05..17aabdf83832 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal pure returns (bytes memory) { return @@ -31,5 +32,7 @@ contract C is S { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol index 866fe9dfc452..322de3c84435 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal virtual pure returns (bytes memory); } @@ -35,5 +36,7 @@ contract C is X { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/eof/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/eof/interface_inheritance_conversions.sol new file mode 100644 index 000000000000..d69337fc0cca --- /dev/null +++ b/test/libsolidity/semanticTests/eof/interface_inheritance_conversions.sol @@ -0,0 +1,47 @@ +interface Parent { + function parentFun() external returns (uint256); +} + +interface SubA is Parent { + function subAFun() external returns (uint256); +} + +interface SubB is Parent { + function subBFun() external returns (uint256); +} + +contract Impl is SubA, SubB { + function parentFun() override external returns (uint256) { return 1; } + function subAFun() override external returns (uint256) { return 2; } + function subBFun() override external returns (uint256) { return 3; } +} + +contract C { + function convertParent() public returns (uint256) { + Parent p = new Impl(); + return p.parentFun(); + } + + function convertSubA() public returns (uint256, uint256) { + bytes32 s = 0x0000000000000000000000000000000000000000000000000000000000000001; + SubA sa = new Impl{salt: s}(); + return (sa.parentFun(), sa.subAFun()); + } + + function convertSubB() public returns (uint256, uint256) { + bytes32 s = 0x0000000000000000000000000000000000000000000000000000000000000002; + SubB sb = new Impl{salt: s}(); + return (sb.parentFun(), sb.subBFun()); + } +} +// ==== +// bytecodeFormat: legacy +// ---- +// convertParent() -> 1 +// gas irOptimized: 85524 +// convertSubA() -> 1, 2 +// gas irOptimized: 86155 +// gas legacy: 99047 +// convertSubB() -> 1, 3 +// gas irOptimized: 86098 +// gas legacy: 98981 diff --git a/test/libsolidity/semanticTests/errors/eof/errors_by_parameter_type.sol b/test/libsolidity/semanticTests/errors/eof/errors_by_parameter_type.sol new file mode 100644 index 000000000000..6b91c9bca189 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/eof/errors_by_parameter_type.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +struct S { + uint256 a; + bool b; + string s; +} + +error E(); +error E1(uint256); +error E2(string); +error E3(S); +error E4(address); +error E5(function() external pure); + +contract C { + function a() external pure { + require(false, E()); + } + function b() external pure { + require(false, E1(1)); + } + function c() external pure { + require(false, E2("string literal")); + } + function d() external pure { + require(false, E3(S(1, true, "string literal"))); + } + function e() external view { + require(false, E4(address(0x6AfCA7D4Df015A0Ba25dA0d02D175603a5fB40E6))); + } + function f(function() external pure x) external view { + require(false, E5(x)); + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// a() -> FAILURE, hex"92bbf6e8" +// b() -> FAILURE, hex"47e26897", hex"0000000000000000000000000000000000000000000000000000000000000001" +// c() -> FAILURE, hex"8f372c34", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// d() -> FAILURE, hex"5717173e", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// e() -> FAILURE, hex"7efef9ea", hex"0000000000000000000000006afca7d4df015a0ba25da0d02d175603a5fb40e6" +// f(function): left(0x6afca7d4df015a0ba25da0d02d175603a5fb40e60dbe671f0000000000000000) -> FAILURE, hex"0c3f12eb", hex"6afca7d4df015a0ba25da0d02d175603a5fb40e60dbe671f0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/eof/require_error_function_pointer_parameter.sol b/test/libsolidity/semanticTests/errors/eof/require_error_function_pointer_parameter.sol new file mode 100644 index 000000000000..973f453edddb --- /dev/null +++ b/test/libsolidity/semanticTests/errors/eof/require_error_function_pointer_parameter.sol @@ -0,0 +1,15 @@ +error CustomError(function(uint256) external pure returns (uint256)); + +contract C +{ + function f(function(uint256) external pure returns (uint256) x) external view + { + // more than one stack slot + require(false, CustomError(x)); + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(function): left(0xa4dc3b5fce39438ce512c732ccb22e3212856bb6f37cdc8e0000000000000000) -> FAILURE, hex"271b1dfa", hex"a4dc3b5fce39438ce512c732ccb22e3212856bb6f37cdc8e0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol index bc70b5bef757..d2b02332eb8f 100644 --- a/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol +++ b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol @@ -27,19 +27,20 @@ contract C { require(false, E3(S(1, true, "string literal"))); } function e() external view { - require(false, E4(address(this))); + require(false, E4(address(0x1234))); } function f() external view { - require(false, E5(this.a)); + require(false, E5(C(address(0x1234)).a)); } } // ==== // compileViaYul: true +// bytecodeFormat: legacy // ---- // a() -> FAILURE, hex"92bbf6e8" // b() -> FAILURE, hex"47e26897", hex"0000000000000000000000000000000000000000000000000000000000000001" // c() -> FAILURE, hex"8f372c34", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" // d() -> FAILURE, hex"5717173e", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" -// e() -> FAILURE, hex"7efef9ea", hex"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e" -// f() -> FAILURE, hex"0c3f12eb", hex"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000" +// e() -> FAILURE, hex"7efef9ea", hex"0000000000000000000000000000000000000000000000000000000000001234" +// f() -> FAILURE, hex"0c3f12eb", hex"00000000000000000000000000000000000012340dbe671f0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol index 3af19ca64fbf..7658ceec0add 100644 --- a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol +++ b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol @@ -10,9 +10,11 @@ contract C function f() external view { // more than one stack slot - require(false, CustomError(this.e)); + require(false, CustomError(C(address(0x1234)).e)); } } +// ==== +// bytecodeFormat: legacy // ---- -// f() -> FAILURE, hex"271b1dfa", hex"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000" +// f() -> FAILURE, hex"271b1dfa", hex"0000000000000000000000000000000000001234f37cdc8e0000000000000000" diff --git a/test/libsolidity/semanticTests/events/eof/event_indexed_function.sol b/test/libsolidity/semanticTests/events/eof/event_indexed_function.sol new file mode 100644 index 000000000000..f242efb39795 --- /dev/null +++ b/test/libsolidity/semanticTests/events/eof/event_indexed_function.sol @@ -0,0 +1,11 @@ +contract C { + event Test(function() external indexed); + function f(function() external x) public { + emit Test(x); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(function): left(0x8f8cc95dcbe7358c1cf1409d3a7ad079e89576bb26121ff00000000000000000) -> +// ~ emit Test(function): #0x8f8cc95dcbe7358c1cf1409d3a7ad079e89576bb26121ff00000000000000000 diff --git a/test/libsolidity/semanticTests/events/eof/event_indexed_function2.sol b/test/libsolidity/semanticTests/events/eof/event_indexed_function2.sol new file mode 100644 index 000000000000..9d51f175073a --- /dev/null +++ b/test/libsolidity/semanticTests/events/eof/event_indexed_function2.sol @@ -0,0 +1,17 @@ +contract C { + event TestA(function() external indexed); + event TestB(function(uint256) external indexed); + function f1(function() external x) public { + emit TestA(x); + } + function f2(function(uint256) external x) public { + emit TestB(x); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f1(function): left(0x347eaa94e3f63220b1f27af5888d33325ddbd4dec27fc3050000000000000000) -> +// ~ emit TestA(function): #0x347eaa94e3f63220b1f27af5888d33325ddbd4dec27fc3050000000000000000 +// f2(function): left(0x347eaa94e3f63220b1f27af5888d33325ddbd4debf3724af0000000000000000) -> +// ~ emit TestB(function): #0x347eaa94e3f63220b1f27af5888d33325ddbd4debf3724af0000000000000000 diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol index 61e1bbdd6c0e..064aeb90d6d8 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -1,3 +1,5 @@ +// TODO: Implement this test for EOF. Now it's not possible becasue deplyed contract address depends on contact bytecode.ยง +// This means that the address changes when optimisations are applied. contract D { event Deposit(address indexed _from, bytes32 indexed _id, uint _value); function deposit(bytes32 _id) public payable { @@ -13,6 +15,8 @@ contract C { d.deposit(_id); } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 113970 diff --git a/test/libsolidity/semanticTests/events/event_indexed_function.sol b/test/libsolidity/semanticTests/events/event_indexed_function.sol index ea7574159500..49dc21497ec5 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_function.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_function.sol @@ -1,9 +1,11 @@ contract C { event Test(function() external indexed); function f() public { - emit Test(this.f); + emit Test(C(address(0x1234)).f); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> -// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000 +// ~ emit Test(function): #0x123426121ff00000000000000000 diff --git a/test/libsolidity/semanticTests/events/event_indexed_function2.sol b/test/libsolidity/semanticTests/events/event_indexed_function2.sol index d4c47e868a1f..0b5cd4b963cb 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_function2.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_function2.sol @@ -2,14 +2,16 @@ contract C { event TestA(function() external indexed); event TestB(function(uint256) external indexed); function f1() public { - emit TestA(this.f1); + emit TestA(C(address(0x1234)).f1); } function f2(uint256 a) public { - emit TestB(this.f2); + emit TestB(C(address(0x1234)).f2); } } +// ==== +// bytecodeFormat: legacy // ---- // f1() -> -// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000 +// ~ emit TestA(function): #0x1234c27fc3050000000000000000 // f2(uint256): 1 -> -// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000 +// ~ emit TestB(function): #0x1234bf3724af0000000000000000 diff --git a/test/libsolidity/semanticTests/experimental/stub.sol b/test/libsolidity/semanticTests/experimental/stub.sol index 6e7a750fe980..d2d0999bfb76 100644 --- a/test/libsolidity/semanticTests/experimental/stub.sol +++ b/test/libsolidity/semanticTests/experimental/stub.sol @@ -92,6 +92,7 @@ contract C { // EVMVersion: >=constantinople // ==== // compileViaYul: true +// bytecodeFormat: legacy // ---- // (): 0 -> 0 // (): 1 -> 544 diff --git a/test/libsolidity/semanticTests/experimental/type_class.sol b/test/libsolidity/semanticTests/experimental/type_class.sol index 69fa568dfd96..7331c0dbd73c 100644 --- a/test/libsolidity/semanticTests/experimental/type_class.sol +++ b/test/libsolidity/semanticTests/experimental/type_class.sol @@ -63,5 +63,6 @@ contract C { // ==== // EVMVersion: >=constantinople // compileViaYul: true +// bytecodeFormat: legacy // ---- // () -> 1, 0 diff --git a/test/libsolidity/semanticTests/externalContracts/eof/snark.sol b/test/libsolidity/semanticTests/externalContracts/eof/snark.sol new file mode 100644 index 000000000000..2331ca52f8c8 --- /dev/null +++ b/test/libsolidity/semanticTests/externalContracts/eof/snark.sol @@ -0,0 +1,310 @@ +library Pairing { + struct G1Point { + uint X; + uint Y; + } + // Encoding of field elements is: X[0] * z + X[1] + struct G2Point { + uint[2] X; + uint[2] Y; + } + + /// @return the generator of G1 + function P1() internal returns (G1Point memory) { + return G1Point(1, 2); + } + + /// @return the generator of G2 + function P2() internal returns (G2Point memory) { + return G2Point( + [11559732032986387107991004021392285783925812861821192530917403151452391805634, + 10857046999023057135944570762232829481370756359578518086990519993285655852781], + [4082367875863433681332203403145435568316851327593401208105741076214120093531, + 8495653923123431417604973247489272438418190587263600148770280649306958101930] + ); + } + + /// @return the negation of p, i.e. p.add(p.negate()) should be zero. + function negate(G1Point memory p) internal returns (G1Point memory) { + // The prime q in the base field F_q for G1 + uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + if (p.X == 0 && p.Y == 0) + return G1Point(0, 0); + return G1Point(p.X, q - (p.Y % q)); + } + + /// @return r the sum of two points of G1 + function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { + uint[4] memory input; + input[0] = p1.X; + input[1] = p1.Y; + input[2] = p2.X; + input[3] = p2.Y; + uint return_flag; + assembly { + return_flag := extcall(6, input, 0xc0, 0) + // Use "invalid" to make gas estimation work + switch return_flag case 1 { invalid() } case 2 { invalid() } + + returndatacopy(r, 0, 64) + } + require(return_flag == 0); + } + + /// @return r the product of a point on G1 and a scalar, i.e. + /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. + function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { + uint[3] memory input; + input[0] = p.X; + input[1] = p.Y; + input[2] = s; + uint return_flag; + assembly { + return_flag := extcall(7, input, 0x80, 0) + // Use "invalid" to make gas estimation work + switch return_flag case 1 { invalid() } case 2 { invalid() } + + returndatacopy(r, 0, 64) + } + require(return_flag == 0); + } + + /// @return the result of computing the pairing check + /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 + /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should + /// return true. + function pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) { + require(p1.length == p2.length); + uint elements = p1.length; + uint inputSize = p1.length * 6; + uint[] memory input = new uint[](inputSize); + for (uint i = 0; i < elements; i++) + { + input[i * 6 + 0] = p1[i].X; + input[i * 6 + 1] = p1[i].Y; + input[i * 6 + 2] = p2[i].X[0]; + input[i * 6 + 3] = p2[i].X[1]; + input[i * 6 + 4] = p2[i].Y[0]; + input[i * 6 + 5] = p2[i].Y[1]; + } + uint[1] memory out; + uint return_flag; + assembly { + return_flag := extcall(8, add(input, 0x20), mul(inputSize, 0x20), 0) + // Use "invalid" to make gas estimation work + switch return_flag case 1 { invalid() } case 2 { invalid() } + + returndatacopy(out, 0, 32) + } + require(return_flag == 0); + return out[0] != 0; + } + function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](2); + G2Point[] memory p2 = new G2Point[](2); + p1[0] = a1; + p1[1] = b1; + p2[0] = a2; + p2[1] = b2; + return pairing(p1, p2); + } + function pairingProd3( + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2 + ) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](3); + G2Point[] memory p2 = new G2Point[](3); + p1[0] = a1; + p1[1] = b1; + p1[2] = c1; + p2[0] = a2; + p2[1] = b2; + p2[2] = c2; + return pairing(p1, p2); + } + function pairingProd4( + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2, + G1Point memory d1, G2Point memory d2 + ) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](4); + G2Point[] memory p2 = new G2Point[](4); + p1[0] = a1; + p1[1] = b1; + p1[2] = c1; + p1[3] = d1; + p2[0] = a2; + p2[1] = b2; + p2[2] = c2; + p2[3] = d2; + return pairing(p1, p2); + } +} + +contract Test { + using Pairing for *; + struct VerifyingKey { + Pairing.G2Point A; + Pairing.G1Point B; + Pairing.G2Point C; + Pairing.G2Point gamma; + Pairing.G1Point gammaBeta1; + Pairing.G2Point gammaBeta2; + Pairing.G2Point Z; + Pairing.G1Point[] IC; + } + struct Proof { + Pairing.G1Point A; + Pairing.G1Point A_p; + Pairing.G2Point B; + Pairing.G1Point B_p; + Pairing.G1Point C; + Pairing.G1Point C_p; + Pairing.G1Point K; + Pairing.G1Point H; + } + function f() public returns (bool) { + Pairing.G1Point memory p1; + Pairing.G1Point memory p2; + p1.X = 1; p1.Y = 2; + p2.X = 1; p2.Y = 2; + Pairing.G1Point memory explicit_sum = Pairing.add(p1, p2); + Pairing.G1Point memory scalar_prod = Pairing.mul(p1, 2); + return (explicit_sum.X == scalar_prod.X && + explicit_sum.Y == scalar_prod.Y); + } + function g() public returns (bool) { + Pairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1())); + // should be zero + return (x.X == 0 && x.Y == 0); + } + function testMul() public returns (bool) { + Pairing.G1Point memory p; + // @TODO The points here are reported to be not well-formed + p.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726; + p.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057; + p = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521); + return + p.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 && + p.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803; + } + function pair() public returns (bool) { + Pairing.G2Point memory fiveTimesP2 = Pairing.G2Point( + [4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072], + [11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846] + ); + // The prime p in the base field F_p for G1 + uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + Pairing.G1Point[] memory g1points = new Pairing.G1Point[](2); + Pairing.G2Point[] memory g2points = new Pairing.G2Point[](2); + // check e(5 P1, P2)e(-P1, 5 P2) == 1 + g1points[0] = Pairing.P1().mul(5); + g1points[1] = Pairing.P1().negate(); + g2points[0] = Pairing.P2(); + g2points[1] = fiveTimesP2; + if (!Pairing.pairing(g1points, g2points)) + return false; + // check e(P1, P2)e(-P1, P2) == 1 + g1points[0] = Pairing.P1(); + g1points[1] = Pairing.P1(); + g1points[1].Y = p - g1points[1].Y; + g2points[0] = Pairing.P2(); + g2points[1] = Pairing.P2(); + if (!Pairing.pairing(g1points, g2points)) + return false; + return true; + } + function verifyingKey() internal returns (VerifyingKey memory vk) { + vk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]); + vk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84); + vk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]); + vk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]); + vk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d); + vk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]); + vk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]); + vk.IC = new Pairing.G1Point[](10); + vk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf); + vk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb); + vk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db); + vk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1); + vk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b); + vk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7); + vk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4); + vk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e); + vk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e); + vk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30); + } + function verify(uint[] memory input, Proof memory proof) internal returns (uint) { + VerifyingKey memory vk = verifyingKey(); + require(input.length + 1 == vk.IC.length); + // Compute the linear combination vk_x + Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); + for (uint i = 0; i < input.length; i++) + vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i])); + vk_x = Pairing.add(vk_x, vk.IC[0]); + if (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1; + if (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2; + if (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3; + if (!Pairing.pairingProd3( + proof.K, vk.gamma, + Pairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2, + Pairing.negate(vk.gammaBeta1), proof.B + )) return 4; + if (!Pairing.pairingProd3( + Pairing.add(vk_x, proof.A), proof.B, + Pairing.negate(proof.H), vk.Z, + Pairing.negate(proof.C), Pairing.P2() + )) return 5; + return 0; + } + event Verified(string); + function verifyTx() public returns (bool) { + uint[] memory input = new uint[](9); + Proof memory proof; + proof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497); + proof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366); + proof.B = Pairing.G2Point( + [8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055], + [15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]); + proof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950); + proof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506); + proof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686); + proof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758); + proof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170); + input[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521; + input[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053; + input[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569; + input[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467; + input[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463; + input[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081; + input[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271; + input[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807; + input[8] = 18066496933330839731877828156604; + if (verify(input, proof) == 0) { + emit Verified("Successfully verified."); + return true; + } else { + return false; + } + } +} +/// Disabled because the point seems to be not well-formed, we need to find another example. +/// testMul() -> true +// +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// library: Pairing +// f() -> true +// g() -> true +// pair() -> true +// gas irOptimized: 270424 +// gas legacy: 275206 +// gas legacyOptimized: 266925 +// verifyTx() -> true +// ~ emit Verified(string): 0x20, 0x16, "Successfully verified." +// gas irOptimized: 785783 +// gas legacy: 801868 +// gas legacyOptimized: 770942 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 906279d17935..5d63b7a44018 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -1,3 +1,5 @@ +pragma abicoder v2; + library Pairing { struct G1Point { uint X; @@ -35,34 +37,26 @@ library Pairing { /// @return r the sum of two points of G1 function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { - uint[4] memory input; + uint[6] memory input; input[0] = p1.X; input[1] = p1.Y; input[2] = p2.X; input[3] = p2.Y; - bool success; - assembly { - success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } + (bool success, bytes memory encodedResult) = address(6).call(abi.encode(input)); require(success); + r = abi.decode(encodedResult, (G1Point)); } /// @return r the product of a point on G1 and a scalar, i.e. /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { - uint[3] memory input; + uint[4] memory input; input[0] = p.X; input[1] = p.Y; input[2] = s; - bool success; - assembly { - success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } + (bool success, bytes memory encodedResult) = address(7).call(abi.encode(input)); require(success); + r = abi.decode(encodedResult, (G1Point)); } /// @return the result of computing the pairing check @@ -83,15 +77,19 @@ library Pairing { input[i * 6 + 4] = p2[i].Y[0]; input[i * 6 + 5] = p2[i].Y[1]; } - uint[1] memory out; - bool success; - assembly { - success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } + + bytes memory encodedInput = new bytes(inputSize * 32); + for (uint i = 0; i < inputSize; i++) + { + uint offset = (i + 1) * 32; + uint item = input[i]; + assembly ("memory-safe") { + mstore(add(encodedInput, offset), item) + } } + (bool success, bytes memory encodedResult) = address(8).call(encodedInput); require(success); - return out[0] != 0; + return abi.decode(encodedResult, (bool)); } function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) { G1Point[] memory p1 = new G1Point[](2); @@ -289,16 +287,17 @@ contract Test { // // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // library: Pairing // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 270409 -// gas legacy: 275219 -// gas legacyOptimized: 266862 +// gas irOptimized: 275319 +// gas legacy: 293854 +// gas legacyOptimized: 276409 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 785720 -// gas legacy: 801903 -// gas legacyOptimized: 770941 +// gas irOptimized: 821446 +// gas legacy: 914211 +// gas legacyOptimized: 820319 diff --git a/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol b/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol index 7a05ff5d0270..e414b8205ba7 100644 --- a/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol +++ b/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol @@ -11,5 +11,7 @@ contract D { return test(); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true diff --git a/test/libsolidity/semanticTests/functionCall/call_options_overload.sol b/test/libsolidity/semanticTests/functionCall/call_options_overload.sol index b9eb6ca42892..61e979f17536 100644 --- a/test/libsolidity/semanticTests/functionCall/call_options_overload.sol +++ b/test/libsolidity/semanticTests/functionCall/call_options_overload.sol @@ -10,6 +10,8 @@ contract C { function bal() external returns (uint) { return address(this).balance; } receive() external payable {} } +// ==== +// bytecodeFormat: legacy // ---- // (), 1 ether // call() -> 1, 2, 2, 2 diff --git a/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol b/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol index 229618384d1e..36dfc844d934 100644 --- a/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol +++ b/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol @@ -21,6 +21,8 @@ contract C { return 7; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> FAILURE // g() -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol b/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol new file mode 100644 index 000000000000..440031e0d192 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint x) external payable returns (uint) { return 1; } + function f(uint x, uint y) external payable returns (uint) { return 2; } + function call() public payable returns (uint x, uint y) { + x = this.f{value: 10}(2); + y = this.f{value: 10}(2, 3); + } + function bal() external returns (uint) { return address(this).balance; } + receive() external payable {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// (), 1 ether +// call() -> 1, 2, 2, 2 +// bal() -> 1000000000000000000 diff --git a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract_throws.sol b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract_throws.sol new file mode 100644 index 000000000000..81b2ea90d44f --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract_throws.sol @@ -0,0 +1,29 @@ +abstract contract D { + function g() public virtual; +} + + +contract C { + D d = D(address(0x1212)); + + function f() public returns (uint256) { + d.g(); + return 7; + } + + function g() public returns (uint256) { + d.g{gas: 200}(); + return 7; + } + + function h() public returns (uint256) { + address(d).call(""); // this does not throw (low-level) + return 7; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> FAILURE +// g() -> FAILURE +// h() -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol new file mode 100644 index 000000000000..eec737de1a11 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol @@ -0,0 +1,24 @@ +// This tests skipping the extcodesize check. + +contract T { + constructor() { this.f(); } + function f() external {} +} +contract U { + constructor() { this.f(); } + function f() external returns (uint) {} +} + +contract C { + function f(uint c) external returns (uint) { + if (c == 0) new T(); + else if (c == 1) new U(); + return 1 + c; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol new file mode 100644 index 000000000000..1093612f456e --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol @@ -0,0 +1,39 @@ +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 88853 +// gas irOptimized code: 164400 +// gas legacy: 102721 +// gas legacy code: 334400 +// gas legacyOptimized: 91499 +// gas legacyOptimized code: 196400 +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> FAILURE +// f(uint256): 3 -> FAILURE +// f(uint256): 4 -> FAILURE +// f(uint256): 5 -> FAILURE +// f(uint256): 6 -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/eof/failed_create.sol b/test/libsolidity/semanticTests/functionCall/eof/failed_create.sol new file mode 100644 index 000000000000..9a80081477b5 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/failed_create.sol @@ -0,0 +1,36 @@ +contract D { constructor() payable {} } +contract C { + uint public x; + constructor() payable {} + function f(uint amount) public returns (bool) { + x++; + return address((new D){value: amount, salt: bytes32(x)}()) != address(0); + } + function stack(uint depth) public payable returns (bool) { + if (depth > 0) + return this.stack(depth - 1); + else + return f(0); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// constructor(), 20 wei +// gas irOptimized: 61548 +// gas irOptimized code: 104600 +// gas legacy: 70147 +// gas legacy code: 215400 +// gas legacyOptimized: 61715 +// gas legacyOptimized code: 106800 +// f(uint256): 20 -> true +// x() -> 1 +// f(uint256): 20 -> FAILURE +// x() -> 1 +// stack(uint256): 1023 -> FAILURE +// gas irOptimized: 252410 +// gas legacy: 477722 +// gas legacyOptimized: 299567 +// x() -> 1 +// stack(uint256): 10 -> true +// x() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol index 6f7f020fe678..c5fa0538e6e7 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -18,6 +18,7 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index 472921c1d25c..0031059c021a 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -20,6 +20,8 @@ contract C { return 1 + c; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 88853 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol index d1b6e8e866ae..a8eafb38ea1a 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -23,6 +23,7 @@ contract C { // ==== // EVMVersion: >=byzantium // revertStrings: debug +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 98698 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 657b4b5cfff6..75253ba3f987 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -2,35 +2,36 @@ contract D { constructor() payable {} } contract C { uint public x; constructor() payable {} - function f(uint amount) public returns (D) { + function f(uint amount) public { x++; - return (new D){value: amount}(); + (new D){value: amount, salt: bytes32(x)}(); } - function stack(uint depth) public payable returns (address) { + function stack(uint depth) public payable { if (depth > 0) - return this.stack(depth - 1); + this.stack(depth - 1); else - return address(f(0)); + f(0); } } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // constructor(), 20 wei -// gas irOptimized: 61548 -// gas irOptimized code: 104600 -// gas legacy: 70147 -// gas legacy code: 215400 -// gas legacyOptimized: 61715 -// gas legacyOptimized code: 106800 -// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a +// gas irOptimized: 59688 +// gas irOptimized code: 81800 +// gas legacy: 64468 +// gas legacy code: 145400 +// gas legacyOptimized: 60443 +// gas legacyOptimized code: 91200 +// f(uint256): 20 -> // x() -> 1 // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 252410 -// gas legacy: 476845 -// gas legacyOptimized: 299061 +// gas irOptimized: 298110 +// gas legacy: 527207 +// gas legacyOptimized: 353607 // x() -> 1 -// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908 +// stack(uint256): 10 -> // x() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index e6187d06e2df..7415accabcd2 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -13,8 +13,6 @@ contract helper { return flag; } } - - contract test { helper h; @@ -36,6 +34,8 @@ contract test { myBal = address(this).balance; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(), 20 wei -> // gas irOptimized: 120218 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol deleted file mode 100644 index 41079af03955..000000000000 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ /dev/null @@ -1,48 +0,0 @@ -contract helper { - bool flag; - - function getBalance() payable public returns(uint256 myBalance) { - return address(this).balance; - } - - function setFlag() public { - flag = true; - } - - function getFlag() public returns(bool fl) { - return flag; - } -} -contract test { - helper h; - constructor() payable { - h = new helper(); - } - - function sendAmount(uint amount) public payable returns(uint256 bal) { - return h.getBalance{value: amount}(); - } - - function outOfGas() public returns(bool ret) { - h.setFlag { - gas: 2 - }(); // should fail due to OOG - return true; - } - - function checkState() public returns(bool flagAfter, uint myBal) { - flagAfter = h.getFlag(); - myBal = address(this).balance; - } -} -// ---- -// constructor(), 20 wei -> -// gas irOptimized: 120218 -// gas irOptimized code: 132000 -// gas legacy: 130583 -// gas legacy code: 261200 -// gas legacyOptimized: 121069 -// gas legacyOptimized code: 147000 -// sendAmount(uint256): 5 -> 5 -// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # -// checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/functionTypes/address_member.sol b/test/libsolidity/semanticTests/functionTypes/address_member.sol index a5f56f3dc688..1117418d0ca1 100644 --- a/test/libsolidity/semanticTests/functionTypes/address_member.sol +++ b/test/libsolidity/semanticTests/functionTypes/address_member.sol @@ -1,10 +1,12 @@ contract C { function f() public view returns (address a1, address a2) { - a1 = this.f.address; - this.f.address; - [this.f.address][0]; - a2 = [this.f.address][0]; + a1 = C(address(0x1234)).f.address; + C(address(0x1234)).f.address; + [C(address(0x1234)).f.address][0]; + a2 = [C(address(0x1234)).f.address][0]; } } +// ==== +// bytecodeFormat: legacy // ---- -// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// f() -> 0x1234, 0x1234 diff --git a/test/libsolidity/semanticTests/functionTypes/eof/address_member.sol b/test/libsolidity/semanticTests/functionTypes/eof/address_member.sol new file mode 100644 index 000000000000..f1061bc79e4e --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/eof/address_member.sol @@ -0,0 +1,19 @@ +contract C { + function f() public view returns (address a1, address a2) { + a1 = this.f.address; + this.f.address; + [this.f.address][0]; + a2 = [this.f.address][0]; + } + + function checkAddress() public returns (bool) { + address a1; + address a2; + (a1, a2) = f(); + return (a1 != address(0) && a1 == a2); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// checkAddress() -> true diff --git a/test/libsolidity/semanticTests/functionTypes/eof/function_external_delete_storage.sol b/test/libsolidity/semanticTests/functionTypes/eof/function_external_delete_storage.sol new file mode 100644 index 000000000000..fbb381cb2be6 --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/eof/function_external_delete_storage.sol @@ -0,0 +1,40 @@ +// TODO: This test should fail on calling a function which was deleted before but for EOF it's impossible to check that +// there is non-empty code under an address. This should be fixed in wiht `ISCONTRACT` opcode ot any other solution. +contract C { + function() external public x; + uint public y = 0; + + function increment() public { + ++y; + } + + function set() external { + x = this.increment; + } + + function incrementIndirectly() public { + x(); + } + + function deleteFunction() public { + // used to lead to an ICE during IR + delete x; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// x() -> 0 +// y() -> 0 +// increment() -> +// y() -> 1 +// set() -> +// increment() -> +// y() -> 2 +// incrementIndirectly() -> +// y() -> 3 +// deleteFunction() -> +// increment() -> +// y() -> 4 +// incrementIndirectly() -> +// y() -> 4 diff --git a/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol index d5e105e5f536..56824ac35b8d 100644 --- a/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol +++ b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol @@ -10,6 +10,10 @@ contract C { x = this.increment; } + function isSet() external returns (bool) { + return x == this.increment; + } + function incrementIndirectly() public { x(); } @@ -19,13 +23,15 @@ contract C { delete x; } } +// ==== +// bytecodeFormat: legacy // ---- -// x() -> 0 +// isSet() -> 0 // y() -> 0 // increment() -> // y() -> 1 // set() -> -// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000 +// isSet() -> true // increment() -> // y() -> 2 // incrementIndirectly() -> diff --git a/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol b/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol index f811988fec9a..1ca391e81095 100644 --- a/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol @@ -19,5 +19,7 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // test_function() -> true diff --git a/test/libsolidity/semanticTests/immutable/eof/multi_creation.sol b/test/libsolidity/semanticTests/immutable/eof/multi_creation.sol new file mode 100644 index 000000000000..3972bdd0b0f5 --- /dev/null +++ b/test/libsolidity/semanticTests/immutable/eof/multi_creation.sol @@ -0,0 +1,39 @@ +contract A { + uint immutable a; + constructor() { + a = 7; + } + function f() public view returns (uint) { return a; } +} +contract B { + uint immutable a; + constructor() { + a = 5; + } + function f() public view returns (uint) { return a; } +} +contract C { + uint immutable a; + uint public x; + uint public y; + constructor() { + a = 3; + x = (new A{salt: hex"00"}()).f(); + y = (new B{salt: hex"00"}()).f(); + } + function f() public returns (uint256, uint, uint) { + return (a, (new A{salt: hex"01"}()).f(), (new B{salt: hex"01"}()).f()); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 3, 7, 5 +// gas irOptimized: 86796 +// gas irOptimized code: 37200 +// gas legacy: 87728 +// gas legacy code: 60800 +// gas legacyOptimized: 86771 +// gas legacyOptimized code: 37200 +// x() -> 7 +// y() -> 5 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index aa8a1ad8a860..5c01e52c74a6 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -18,20 +18,22 @@ contract C { uint public y; constructor() { a = 3; - x = (new A()).f(); - y = (new B()).f(); + x = (new A{salt: hex"00"}()).f(); + y = (new B{salt: hex"00"}()).f(); } function f() public returns (uint256, uint, uint) { - return (a, (new A()).f(), (new B()).f()); + return (a, (new A{salt: hex"01"}()).f(), (new B{salt: hex"01"}()).f()); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 3, 7, 5 -// gas irOptimized: 86796 +// gas irOptimized: 86892 // gas irOptimized code: 37200 -// gas legacy: 87727 +// gas legacy: 87839 // gas legacy code: 60800 -// gas legacyOptimized: 86770 +// gas legacyOptimized: 86870 // gas legacyOptimized code: 37200 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 0865ed2876ad..228231718b5e 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -11,19 +11,21 @@ contract C { contract D { function f() public returns (uint256) { - return (new C()).balance(); + return (new C{salt: hex"00"}()).balance(); } function g() public returns (uint256) { - return (new C()).transfer(5); + return (new C{salt: hex"01"}()).transfer(5); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 1 // gas irOptimized: 77051 -// gas legacy: 54480 +// gas legacy: 54553 // gas legacy code: 57800 // g() -> 5 // gas irOptimized: 77106 -// gas legacy: 55016 +// gas legacy: 55090 // gas legacy code: 57800 diff --git a/test/libsolidity/semanticTests/inheritance/eof/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/eof/address_overload_resolution.sol new file mode 100644 index 000000000000..ae2f391f253a --- /dev/null +++ b/test/libsolidity/semanticTests/inheritance/eof/address_overload_resolution.sol @@ -0,0 +1,31 @@ +contract C { + function balance() public returns (uint256) { + return 1; + } + + function transfer(uint256 amount) public returns (uint256) { + return amount; + } +} + + +contract D { + function f() public returns (uint256) { + return (new C{salt: hex"00"}()).balance(); + } + + function g() public returns (uint256) { + return (new C{salt: hex"01"}()).transfer(5); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 1 +// gas irOptimized: 77051 +// gas legacy: 54480 +// gas legacy code: 57800 +// g() -> 5 +// gas irOptimized: 77106 +// gas legacy: 55016 +// gas legacy code: 57800 diff --git a/test/libsolidity/semanticTests/inheritance/eof/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/eof/member_notation_ctor.sol new file mode 100644 index 000000000000..1e55753de976 --- /dev/null +++ b/test/libsolidity/semanticTests/inheritance/eof/member_notation_ctor.sol @@ -0,0 +1,28 @@ +==== Source: A ==== +contract C { + int private x; + constructor (int p) public { x = p; } + function getX() public returns (int) { return x; } +} +==== Source: B ==== +import "A" as M; + +contract D is M.C { + constructor (int p) M.C(p) public {} +} + +contract A { + function g(int p) public returns (int) { + D d = new D{salt: bytes32(uint256(p))}(p); + return d.getX(); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// g(int256): -1 -> -1 +// gas legacy: 77878 +// gas legacy code: 24200 +// g(int256): 10 -> 10 +// gas legacy: 77506 +// gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index b9697c5ae1d7..43aff01daec4 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -13,14 +13,16 @@ contract D is M.C { contract A { function g(int p) public returns (int) { - D d = new D(p); + D d = new D{salt: bytes32(uint256(p))}(p); return d.getX(); } } +// ==== +// bytecodeFormat: legacy // ---- // g(int256): -1 -> -1 -// gas legacy: 77876 +// gas legacy: 77955 // gas legacy code: 24200 // g(int256): 10 -> 10 -// gas legacy: 77504 +// gas legacy: 77583 // gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/inlineAssembly/eof/external_function_pointer_address.sol b/test/libsolidity/semanticTests/inlineAssembly/eof/external_function_pointer_address.sol new file mode 100644 index 000000000000..0e9231f6b26b --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/eof/external_function_pointer_address.sol @@ -0,0 +1,24 @@ +contract C { + function testFunction() external {} + address contractAddress = address(this); + function testYul() public returns (bool) { + require(contractAddress != address(0)); + function() external fp = this.testFunction; + + address adr; + assembly { + adr := fp.address + } + + return adr == contractAddress; + } + function testSol() public returns (bool) { + require(contractAddress != address(0)); + return this.testFunction.address == contractAddress; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// testYul() -> true +// testSol() -> true diff --git a/test/libsolidity/semanticTests/inlineAssembly/eof/transient_storage_low_level_calls.sol b/test/libsolidity/semanticTests/inlineAssembly/eof/transient_storage_low_level_calls.sol new file mode 100644 index 000000000000..8a5b6b0661d0 --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/eof/transient_storage_low_level_calls.sol @@ -0,0 +1,76 @@ +contract D { + function addOne() external { + assembly { + let x := tload(0) + tstore(0, add(x, 1)) + } + } + function get() external returns (uint x) { + assembly { + x := tload(0) + } + } +} + +contract C { + function set(uint x) external { + assembly { + tstore(0, x) + } + } + + function get() external view returns (uint x) { + assembly { + x := tload(0) + } + } + + function testDelegateCall() external returns (bool) { + this.set(5); + D d = new D{salt: hex"00"}(); + // Caller contract is the owner of the transient storage + (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ())); + require(success); + require(this.get() == 6); + return true; + } + + function testCall() external returns (bool) { + this.set(5); + D d = new D{salt: hex"01"}(); + // Callee/Target contract is the owner of the transient storage + (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ())); + require(success); + require(d.get() == 1); + return true; + } + + function tloadAllowedStaticCall() external returns (bool) { + this.set(5); + D d = new D{salt: hex"02"}(); + (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ())); + require(success); + require(abi.decode(result, (uint)) == 0); + return true; + } + + function tstoreNotAllowedStaticCall() external returns (bool) { + D d = new D{salt: hex"03"}(); + (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ())); + require(!success); + return true; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// testDelegateCall() -> true +// testCall() -> true +// tloadAllowedStaticCall() -> true +// tstoreNotAllowedStaticCall() -> true +// gas irOptimized: 98419720 +// gas irOptimized code: 19000 +// gas legacy: 98409086 +// gas legacy code: 30000 +// gas legacyOptimized: 98420962 +// gas legacyOptimized code: 17800 diff --git a/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol b/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol index ae891df5dc4f..d76c29f47c6c 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol @@ -2,16 +2,18 @@ contract C { function testFunction() external {} function testYul() public returns (address adr) { - function() external fp = this.testFunction; + function() external fp = C(address(0x1234)).testFunction; assembly { adr := fp.address } } function testSol() public returns (address) { - return this.testFunction.address; + return C(address(0x1234)).testFunction.address; } } +// ==== +// bytecodeFormat: legacy // ---- -// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e -// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// testYul() -> 0x1234 +// testSol() -> 0x1234 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol index e43fc475740a..fc90322e0d95 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol @@ -27,7 +27,7 @@ contract C { function testDelegateCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"00"}(); // Caller contract is the owner of the transient storage (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ())); require(success); @@ -37,7 +37,7 @@ contract C { function testCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"01"}(); // Callee/Target contract is the owner of the transient storage (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ())); require(success); @@ -47,7 +47,7 @@ contract C { function tloadAllowedStaticCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"02"}(); (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ())); require(success); require(abi.decode(result, (uint)) == 0); @@ -55,7 +55,7 @@ contract C { } function tstoreNotAllowedStaticCall() external returns (bool) { - D d = new D(); + D d = new D{salt: hex"03"}(); (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ())); require(!success); return true; @@ -63,14 +63,15 @@ contract C { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // testDelegateCall() -> true // testCall() -> true // tloadAllowedStaticCall() -> true // tstoreNotAllowedStaticCall() -> true -// gas irOptimized: 98419720 +// gas irOptimized: 98419721 // gas irOptimized code: 19000 -// gas legacy: 98409086 +// gas legacy: 98409087 // gas legacy code: 30000 // gas legacyOptimized: 98420962 // gas legacyOptimized code: 17800 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol index c2066ef8be1e..26bb09edca7a 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol @@ -38,6 +38,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 127596 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 62e1e4fba6dc..14cca2530bfa 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -10,28 +10,25 @@ interface SubB is Parent { function subBFun() external returns (uint256); } -contract Impl is SubA, SubB { +contract C is SubA, SubB { function parentFun() override external returns (uint256) { return 1; } function subAFun() override external returns (uint256) { return 2; } function subBFun() override external returns (uint256) { return 3; } -} -contract C { function convertParent() public returns (uint256) { - Parent p = new Impl(); - return p.parentFun(); + return this.parentFun(); } function convertSubA() public returns (uint256, uint256) { - SubA sa = new Impl(); - return (sa.parentFun(), sa.subAFun()); + return (this.parentFun(), this.subAFun()); } function convertSubB() public returns (uint256, uint256) { - SubB sb = new Impl(); - return (sb.parentFun(), sb.subBFun()); + return (this.parentFun(), this.subBFun()); } } +// ==== +// bytecodeFormat: legacy // ---- // convertParent() -> 1 // gas irOptimized: 85524 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 1240a8251427..d4d43625361d 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -1,30 +1,11 @@ -contract Other { +contract C { constructor() payable { - } - function getAddress() public returns (address) { - return address(this); - } -} -contract ClientReceipt { - Other other; - constructor() payable { - other = new Other{value:500}(); - } - function getAddress() public returns (address) { - return other.getAddress(); + payable(address(0x1234)).transfer(500); } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(), 2000 wei -> -// gas irOptimized: 114353 -// gas irOptimized code: 58800 -// gas legacy: 118617 -// gas legacy code: 111400 -// gas legacyOptimized: 114067 -// gas legacyOptimized code: 59800 // balance -> 1500 -// gas irOptimized: 191881 -// gas legacy: 235167 -// gas legacyOptimized: 180756 -// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500 +// balance: 0x0000000000000000000000000000000000001234 -> 500 diff --git a/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_pure_external_call.sol new file mode 100644 index 000000000000..16b50a34108a --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_pure_external_call.sol @@ -0,0 +1,67 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdder { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +contract Adder is IAdder { + function mul(Int32 x, Int32 y) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdder adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdder adder) { + assembly { + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder{salt: hex"00"}()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder{salt: hex"01"}()); + + return -x; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 102563 +// gas legacy: 56981 +// gas legacy code: 127000 +// gas legacyOptimized: 55163 +// gas legacyOptimized code: 68400 +// testInc(int32): 42 -> 43 +// gas irOptimized: 102386 +// gas legacy: 56239 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_view_external_call.sol new file mode 100644 index 000000000000..4eedeaf3c04b --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/eof/operator_making_view_external_call.sol @@ -0,0 +1,73 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdderPure { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +interface IAdderView { + function mul(Int32, Int32) external view returns (Int32); + function inc(Int32) external view returns (Int32); +} + +contract Adder is IAdderView { + function mul(Int32 x, Int32 y) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdderView adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdderPure adder) { + assembly { + // The adder we stored is view but we cheat by using a modified version with pure functions + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder{salt: hex"00"}()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder{salt: hex"01"}()); + + return -x; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 102563 +// gas legacy: 56981 +// gas legacy code: 127000 +// gas legacyOptimized: 55163 +// gas legacyOptimized code: 68400 +// testInc(int32): 42 -> 43 +// gas irOptimized: 102386 +// gas legacy: 56239 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index ec41099eecbb..30999c5ea7a2 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -39,27 +39,29 @@ function loadAdder() pure returns (IAdder adder) { contract C { function testMul(Int32 x, Int32 y) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"00"}()); return x + y; } function testInc(Int32 x) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"01"}()); return -x; } } +// ==== +// bytecodeFormat: legacy // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56978 +// gas legacy: 57117 // gas legacy code: 127000 -// gas legacyOptimized: 55161 +// gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56238 +// gas legacy: 56378 // gas legacy code: 127000 -// gas legacyOptimized: 54851 +// gas legacyOptimized: 54943 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index 7e70eb091bf6..5c5ee1a3fc1e 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -45,27 +45,29 @@ function loadAdder() pure returns (IAdderPure adder) { contract C { function testMul(Int32 x, Int32 y) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"00"}()); return x + y; } function testInc(Int32 x) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"01"}()); return -x; } } +// ==== +// bytecodeFormat: legacy // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56978 +// gas legacy: 57117 // gas legacy code: 127000 -// gas legacyOptimized: 55161 +// gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56238 +// gas legacy: 56378 // gas legacy code: 127000 -// gas legacyOptimized: 54851 +// gas legacyOptimized: 54943 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol b/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol index 110b1e50c724..d9a6549252f1 100644 --- a/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol +++ b/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol @@ -8,5 +8,6 @@ contract C { // ==== // EVMVersion: >=byzantium // revertStrings: debug +// bytecodeFormat: legacy // ---- // g() -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" diff --git a/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol b/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol new file mode 100644 index 000000000000..8cec1ca1d66c --- /dev/null +++ b/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol @@ -0,0 +1,19 @@ +contract C { + fallback() external { + revert("abc"); + } + + function f() public returns (uint s, uint r) { + address x = address(this); + assembly { + mstore(0, 7) + s := extcall(x, 0, 0, 0) + returndatacopy(0, 0, 32) + r := mload(0) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 0x01, 0x08c379a000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/reverts/revert_return_area.sol b/test/libsolidity/semanticTests/reverts/revert_return_area.sol index 8ab4ca22722c..5f276f91c948 100644 --- a/test/libsolidity/semanticTests/reverts/revert_return_area.sol +++ b/test/libsolidity/semanticTests/reverts/revert_return_area.sol @@ -14,5 +14,6 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol b/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol new file mode 100644 index 000000000000..e6c6f6eb0772 --- /dev/null +++ b/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol @@ -0,0 +1,23 @@ +contract B +{ + uint x; + function getBalance() public view returns (uint) { + return address(this).balance * 1000 + x; + } + constructor(uint _x) payable { + x = _x; + } +} + +contract A { + function f() public payable returns (uint, uint, uint) { + B x = new B{salt: "abc1", value: 3}(7); + B y = new B{value: 3, salt: "abc2"}(8); + B z = new B{salt: "abc3", value: 3}(9); + return (x.getBalance(), y.getBalance(), z.getBalance()); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(), 10 ether -> 3007, 3008, 3009 diff --git a/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol b/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol index 7d0e3c8b0dbc..f1f62db03230 100644 --- a/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol +++ b/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol @@ -24,6 +24,7 @@ contract C { // ==== // EVMVersion: >=constantinople // compileViaYul: also +// bytecodeFormat: legacy // ---- // createDSalted(bytes32,uint256): 42, 64 -> // gas legacy: 78573 diff --git a/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol b/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol index 25d1935770d1..c810000e5b3c 100644 --- a/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol @@ -19,6 +19,7 @@ contract A { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 187022 diff --git a/test/libsolidity/semanticTests/salted_create/eof/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/eof/salted_create_with_value.sol new file mode 100644 index 000000000000..6c50f0d02e07 --- /dev/null +++ b/test/libsolidity/semanticTests/salted_create/eof/salted_create_with_value.sol @@ -0,0 +1,29 @@ +contract B +{ + uint x; + function getBalance() public view returns (uint) { + return address(this).balance * 1000 + x; + } + constructor(uint _x) payable { + x = _x; + } +} + +contract A { + function f() public payable returns (uint, uint, uint) { + B x = new B{salt: "abc0", value: 3}(7); + B y = new B{value: 3, salt: "abc1"}(8); + B z = new B{salt: "abc2", value: 3}(9); + return (x.getBalance(), y.getBalance(), z.getBalance()); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(), 10 ether -> 3007, 3008, 3009 +// gas irOptimized: 187022 +// gas irOptimized code: 67200 +// gas legacy: 190863 +// gas legacy code: 190200 +// gas legacyOptimized: 187258 +// gas legacyOptimized code: 92400 diff --git a/test/libsolidity/semanticTests/shanghai/evmone_support.sol b/test/libsolidity/semanticTests/shanghai/evmone_support.sol index 359dc516ffcd..4f3c0ee1ba6a 100644 --- a/test/libsolidity/semanticTests/shanghai/evmone_support.sol +++ b/test/libsolidity/semanticTests/shanghai/evmone_support.sol @@ -26,6 +26,7 @@ contract Test { // ==== // compileViaYul: also // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000 // isPush0Supported() -> true diff --git a/test/libsolidity/semanticTests/state/gasleft.sol b/test/libsolidity/semanticTests/state/gasleft.sol index 6ce623ce81ea..2d4a37b48d8b 100644 --- a/test/libsolidity/semanticTests/state/gasleft.sol +++ b/test/libsolidity/semanticTests/state/gasleft.sol @@ -3,6 +3,8 @@ contract C { return gasleft() > 0; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true // f() -> true diff --git a/test/libsolidity/semanticTests/tryCatch/assert.sol b/test/libsolidity/semanticTests/tryCatch/assert.sol index 8b6a7b99692e..6fe1560aaccc 100644 --- a/test/libsolidity/semanticTests/tryCatch/assert.sol +++ b/test/libsolidity/semanticTests/tryCatch/assert.sol @@ -4,13 +4,15 @@ contract C { } function f(bool x) public returns (uint) { // Set the gas to make this work on pre-byzantium VMs - try this.g{gas: 8000}(x) { + try this.g(x) { return 1; } catch { return 2; } } } +// ==== +// bytecodeFormat: legacy // ---- // f(bool): true -> 1 // f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol b/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol new file mode 100644 index 000000000000..a683f531fc0e --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool x) public pure { + assert(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g{gas: 8000}(x) { + return 1; + } catch { + return 2; + } + } +} +// ==== +// EVMVersion: 1 +// f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/create.sol b/test/libsolidity/semanticTests/tryCatch/create.sol index 43d0f22f6506..b2365d3dc9ff 100644 --- a/test/libsolidity/semanticTests/tryCatch/create.sol +++ b/test/libsolidity/semanticTests/tryCatch/create.sol @@ -6,19 +6,19 @@ contract Succeeds { } contract C { - function f() public returns (Reverts x, uint, string memory txt) { + function f() public returns (bool created, string memory txt) { uint i = 3; try new Reverts(i) returns (Reverts r) { - x = r; + created = (address(r) != address(0)); txt = "success"; } catch Error(string memory s) { txt = s; } } - function g() public returns (Succeeds x, uint, string memory txt) { + function g() public returns (bool created, string memory txt) { uint i = 8; try new Succeeds(i) returns (Succeeds r) { - x = r; + created = (address(r) != address(0)); txt = "success"; } catch Error(string memory s) { txt = s; @@ -27,6 +27,7 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- -// f() -> 0, 0, 96, 13, "test message." -// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, "success" +// f() -> false, 0x40, 13, "test message." +// g() -> true, 0x40, 7, "success" diff --git a/test/libsolidity/semanticTests/tryCatch/eof/assert.sol b/test/libsolidity/semanticTests/tryCatch/eof/assert.sol new file mode 100644 index 000000000000..d1030ea0fb2a --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/eof/assert.sol @@ -0,0 +1,17 @@ +contract C { + function g(bool x) public pure { + assert(x); + } + function f(bool x) public returns (uint) { + try this.g(x) { + return 1; + } catch { + return 2; + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/eof/create.sol b/test/libsolidity/semanticTests/tryCatch/eof/create.sol new file mode 100644 index 000000000000..c75026599213 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/eof/create.sol @@ -0,0 +1,32 @@ +contract Reverts { + constructor(uint) { revert("test message."); } +} +contract Succeeds { + constructor(uint) { } +} + +contract C { + function f() public returns (Reverts x, uint, string memory txt) { + uint i = 3; + try new Reverts(i) returns (Reverts r) { + x = r; + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } + function g() public returns (bool x, uint, string memory txt) { + uint i = 8; + try new Succeeds(i) returns (Succeeds r) { + x = address(r) != address(0); + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 0, 0, 96, 13, "test message." +// g() -> true, 0, 0x60, 7, "success" diff --git a/test/libsolidity/semanticTests/tryCatch/eof/return_function.sol b/test/libsolidity/semanticTests/tryCatch/eof/return_function.sol new file mode 100644 index 000000000000..75358f20d01c --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/eof/return_function.sol @@ -0,0 +1,19 @@ +contract C { + function g() public returns (uint a, function() external h, uint b) { + a = 1; + h = this.fun; + b = 9; + } + function f() public returns (uint, bool, uint) { + // Note that the function type uses two stack slots. + try this.g() returns (uint a, function() external h, uint b) { + return (a, h == this.fun, b); + } catch { + } + } + function fun() public pure {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 1, true, 9 diff --git a/test/libsolidity/semanticTests/tryCatch/super_trivial.sol b/test/libsolidity/semanticTests/tryCatch/eof/trivial.sol similarity index 79% rename from test/libsolidity/semanticTests/tryCatch/super_trivial.sol rename to test/libsolidity/semanticTests/tryCatch/eof/trivial.sol index 98fbcddb21b5..cbbccb4d75e7 100644 --- a/test/libsolidity/semanticTests/tryCatch/super_trivial.sol +++ b/test/libsolidity/semanticTests/tryCatch/eof/trivial.sol @@ -1,5 +1,5 @@ contract C { - function g(bool x) external pure { + function g(bool x) public pure { require(x); } function f(bool x) public returns (uint) { @@ -11,7 +11,7 @@ contract C { } } // ==== -// EVMVersion: >=byzantium +// bytecodeFormat: >=EOFv1 // ---- // f(bool): true -> 1 // f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/return_function.sol b/test/libsolidity/semanticTests/tryCatch/return_function.sol index 6aac30fe4617..66ced6263ad0 100644 --- a/test/libsolidity/semanticTests/tryCatch/return_function.sol +++ b/test/libsolidity/semanticTests/tryCatch/return_function.sol @@ -1,7 +1,7 @@ contract C { function g() public returns (uint a, function() external h, uint b) { a = 1; - h = this.fun; + h = C(address(0x1234)).fun; b = 9; } function f() public returns (uint, function() external, uint) { @@ -13,5 +13,7 @@ contract C { } function fun() public pure {} } +// ==== +// bytecodeFormat: legacy // ---- -// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9 +// f() -> 0x1, 0x1234946644cd0000000000000000, 9 diff --git a/test/libsolidity/semanticTests/tryCatch/trivial.sol b/test/libsolidity/semanticTests/tryCatch/trivial.sol index d43477e994ab..730243208e55 100644 --- a/test/libsolidity/semanticTests/tryCatch/trivial.sol +++ b/test/libsolidity/semanticTests/tryCatch/trivial.sol @@ -3,14 +3,15 @@ contract C { require(x); } function f(bool x) public returns (uint) { - // Set the gas to make this work on pre-byzantium VMs - try this.g{gas: 8000}(x) { + try this.g(x) { return 1; } catch { return 2; } } } +// ==== +// EVMVersion: >=byzantium // ---- // f(bool): true -> 1 // f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/trivial_pre_byzantium.sol b/test/libsolidity/semanticTests/tryCatch/trivial_pre_byzantium.sol new file mode 100644 index 000000000000..f1bc9b110613 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/trivial_pre_byzantium.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool x) external pure { + require(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g{gas: 8000}(x) { + return 1; + } catch { + return 2; + } + } +} +// ==== +// EVMVersion: 1 +// f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 549512eb3e44..4d810f970987 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -12,6 +12,8 @@ contract C { function g() public view returns (uint) { return address(0).code.length; } function h() public view returns (uint) { return address(1).code.length; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 70760 diff --git a/test/libsolidity/semanticTests/various/address_code_complex.sol b/test/libsolidity/semanticTests/various/address_code_complex.sol index f2d21c9069b3..d228d99d1767 100644 --- a/test/libsolidity/semanticTests/various/address_code_complex.sol +++ b/test/libsolidity/semanticTests/various/address_code_complex.sol @@ -12,6 +12,8 @@ contract C { function f() public returns (bytes memory) { return address(new A()).code; } function g() public returns (uint) { return address(new A()).code.length; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 0x20, 0x20, 0x48aa5566000000 // g() -> 0x20 diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index 22ceff337f89..b8b13b3c677f 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -36,6 +36,8 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // testRuntime() -> true // gas legacy: 76575 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index f5f0b8644423..e3a6e03728e9 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test when eofcreate will be allowed in inline assembly. contract D { uint256 x; @@ -21,6 +22,8 @@ contract C { return d.f(); } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> 7 // gas legacy: 76647 diff --git a/test/libsolidity/semanticTests/various/code_access_padding.sol b/test/libsolidity/semanticTests/various/code_access_padding.sol index 831d4bde4ab4..6c07fb4e089e 100644 --- a/test/libsolidity/semanticTests/various/code_access_padding.sol +++ b/test/libsolidity/semanticTests/various/code_access_padding.sol @@ -14,5 +14,7 @@ contract C { } } } +// ==== +// bytecodeFormat: legacy // ---- // diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes # diff --git a/test/libsolidity/semanticTests/various/code_access_runtime.sol b/test/libsolidity/semanticTests/various/code_access_runtime.sol index 10d7c1852e95..0c848fc592eb 100644 --- a/test/libsolidity/semanticTests/various/code_access_runtime.sol +++ b/test/libsolidity/semanticTests/various/code_access_runtime.sol @@ -21,6 +21,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // test() -> 42 // gas legacy: 76034 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index 844a0f65706f..08065b302c99 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -57,6 +57,8 @@ contract C { } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() // gas legacy: 66989 diff --git a/test/libsolidity/semanticTests/various/code_length_contract_member.sol b/test/libsolidity/semanticTests/various/code_length_contract_member.sol index ff883139a46e..79e940080f02 100644 --- a/test/libsolidity/semanticTests/various/code_length_contract_member.sol +++ b/test/libsolidity/semanticTests/various/code_length_contract_member.sol @@ -11,5 +11,7 @@ contract C { return (s.code.length, s.another.length, address(this).code.length > 50); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 0x20, 0x20, true diff --git a/test/libsolidity/semanticTests/various/codehash.sol b/test/libsolidity/semanticTests/various/codehash.sol index fa7dab9dab9f..465e2ee31b51 100644 --- a/test/libsolidity/semanticTests/various/codehash.sol +++ b/test/libsolidity/semanticTests/various/codehash.sol @@ -13,6 +13,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f() -> 0x0 // g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/test/libsolidity/semanticTests/various/codehash_assembly.sol b/test/libsolidity/semanticTests/various/codehash_assembly.sol index fe2210fa107a..81c2286d5e44 100644 --- a/test/libsolidity/semanticTests/various/codehash_assembly.sol +++ b/test/libsolidity/semanticTests/various/codehash_assembly.sol @@ -17,6 +17,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f() -> 0 // g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index a5f61d2ddd67..7e3e326228a7 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -6,6 +6,8 @@ contract C { assert(msg.data.length == 0); } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(): 42 -> // gas irOptimized: 68239 diff --git a/test/libsolidity/semanticTests/various/create_random.sol b/test/libsolidity/semanticTests/various/create_random.sol index 676ec32a89ae..b053deb442ed 100644 --- a/test/libsolidity/semanticTests/various/create_random.sol +++ b/test/libsolidity/semanticTests/various/create_random.sol @@ -33,6 +33,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e // testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d diff --git a/test/libsolidity/semanticTests/various/eof/create_calldata.sol b/test/libsolidity/semanticTests/various/eof/create_calldata.sol new file mode 100644 index 000000000000..b2257be9fd1f --- /dev/null +++ b/test/libsolidity/semanticTests/various/eof/create_calldata.sol @@ -0,0 +1,19 @@ +contract C { + bytes public s; + constructor(uint256 x) { + // Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments. + s = msg.data; + assert(msg.data.length == 32); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// constructor(): 42 -> +// gas irOptimized: 68239 +// gas irOptimized code: 69000 +// gas legacy: 78076 +// gas legacy code: 90200 +// gas legacyOptimized: 68321 +// gas legacyOptimized code: 64600 +// s() -> 0x20, 0x20, 0x2a diff --git a/test/libsolidity/semanticTests/various/eof/many_subassemblies.sol b/test/libsolidity/semanticTests/various/eof/many_subassemblies.sol new file mode 100644 index 000000000000..dff669322a60 --- /dev/null +++ b/test/libsolidity/semanticTests/various/eof/many_subassemblies.sol @@ -0,0 +1,40 @@ +contract C0 {} +contract C1 {} +contract C2 {} +contract C3 {} +contract C4 {} +contract C5 {} +contract C6 {} +contract C7 {} +contract C8 {} +contract C9 {} +contract C10 {} + +contract D { + function run() public { + // This is primarily meant to test assembly import via --import-asm-json. + // The exported JSON will fail the reimport unless the subassembly indices are parsed + // correctly - as hex numbers. + new C0{salt: hex"00"}(); + new C1{salt: hex"01"}(); + new C2{salt: hex"02"}(); + new C3{salt: hex"03"}(); + new C4{salt: hex"04"}(); + new C5{salt: hex"05"}(); + new C6{salt: hex"06"}(); + new C7{salt: hex"07"}(); + new C8{salt: hex"08"}(); + new C9{salt: hex"09"}(); + new C10{salt: hex"0a"}(); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// run() -> +// gas irOptimized: 374934 +// gas irOptimized code: 6600 +// gas legacy: 375119 +// gas legacy code: 17600 +// gas legacyOptimized: 375119 +// gas legacyOptimized code: 17600 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/eof/value_complex.sol similarity index 87% rename from test/libsolidity/semanticTests/various/value_complex.sol rename to test/libsolidity/semanticTests/various/eof/value_complex.sol index 4639d34c7071..ccf10106ada9 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/eof/value_complex.sol @@ -14,9 +14,11 @@ contract test { function sendAmount(uint256 amount) public payable returns (uint256 bal) { uint256 someStackElement = 20; - return h.getBalance{value: amount + 3, gas: 1000}(); + return h.getBalance{value: amount + 3}(); } } +// ==== +// bytecodeFormat: >=EOFv1 // ---- // constructor(), 20 wei -> // gas irOptimized: 114463 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/eof/value_insane.sol similarity index 86% rename from test/libsolidity/semanticTests/various/value_insane.sol rename to test/libsolidity/semanticTests/various/eof/value_insane.sol index bc6a803de92f..2b65d11eed9f 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/eof/value_insane.sol @@ -13,9 +13,11 @@ contract test { } function sendAmount(uint256 amount) public returns (uint256 bal) { - return h.getBalance{value: amount + 3, gas: 1000}(); + return h.getBalance{value: amount + 3}(); } } +// ==== +// bytecodeFormat: >=EOFv1 // ---- // constructor(), 20 wei -> // gas irOptimized: 114527 diff --git a/test/libsolidity/semanticTests/various/gasleft_decrease.sol b/test/libsolidity/semanticTests/various/gasleft_decrease.sol index ab7302743f64..ea891edc4e5f 100644 --- a/test/libsolidity/semanticTests/various/gasleft_decrease.sol +++ b/test/libsolidity/semanticTests/various/gasleft_decrease.sol @@ -14,6 +14,8 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true // g() -> true diff --git a/test/libsolidity/semanticTests/various/many_subassemblies.sol b/test/libsolidity/semanticTests/various/many_subassemblies.sol index b270c7006694..3a9ada96c05c 100644 --- a/test/libsolidity/semanticTests/various/many_subassemblies.sol +++ b/test/libsolidity/semanticTests/various/many_subassemblies.sol @@ -15,24 +15,26 @@ contract D { // This is primarily meant to test assembly import via --import-asm-json. // The exported JSON will fail the reimport unless the subassembly indices are parsed // correctly - as hex numbers. - new C0(); - new C1(); - new C2(); - new C3(); - new C4(); - new C5(); - new C6(); - new C7(); - new C8(); - new C9(); - new C10(); + new C0{salt: hex"00"}(); + new C1{salt: hex"01"}(); + new C2{salt: hex"02"}(); + new C3{salt: hex"03"}(); + new C4{salt: hex"04"}(); + new C5{salt: hex"05"}(); + new C6{salt: hex"06"}(); + new C7{salt: hex"07"}(); + new C8{salt: hex"08"}(); + new C9{salt: hex"09"}(); + new C10{salt: hex"0a"}(); } } +// ==== +// bytecodeFormat: legacy // ---- // run() -> -// gas irOptimized: 374934 +// gas irOptimized: 375192 // gas irOptimized code: 6600 -// gas legacy: 375119 +// gas legacy: 375404 // gas legacy code: 17600 -// gas legacyOptimized: 375119 +// gas legacyOptimized: 375464 // gas legacyOptimized code: 17600 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol index 4cb5c8c713bf..bf70caee5b54 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol @@ -62,6 +62,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 67028 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol index a582649196c3..7629fabc1ce2 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -33,6 +33,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 2 ether -> // gas irOptimized: 108104 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol index dd550d31a0cf..c9f50046c07d 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol @@ -80,6 +80,7 @@ contract D { // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 132974 diff --git a/test/libsolidity/semanticTests/viaYul/conversion/eof/function_cast.sol b/test/libsolidity/semanticTests/viaYul/conversion/eof/function_cast.sol new file mode 100644 index 000000000000..aa30fbece048 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/conversion/eof/function_cast.sol @@ -0,0 +1,23 @@ +contract C { + function f(uint x) public pure returns (uint) { + return 2 * x; + } + function g() public view returns (function (uint) external returns (uint)) { + return this.f; + } + function h(uint x) public returns (uint) { + return this.g()(x) + 1; + } + function t(function(uint) external returns (uint) x, function(uint) external view returns (uint) y) external view returns ( + function(uint) external returns (uint) a, + function(uint) external view returns (uint) b) { + a = x; + b = y; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(uint256): 2 -> 4 +// h(uint256): 2 -> 5 +// t(function, function): left(0x51ac6a341cdab4263623cddef6e4860d0679b0a9b3de648b0000000000000000), left(0x51ac6a341cdab4263623cddef6e4860d0679b0a9b3de648b0000000000000000) -> 0x51ac6a341cdab4263623cddef6e4860d0679b0a9b3de648b0000000000000000, 0x51ac6a341cdab4263623cddef6e4860d0679b0a9b3de648b0000000000000000 diff --git a/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol b/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol index 843376baa553..837c1ba34591 100644 --- a/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol +++ b/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol @@ -9,13 +9,16 @@ contract C { return this.g()(x) + 1; } function t() external view returns ( - function(uint) external returns (uint) a, - function(uint) external view returns (uint) b) { - a = this.f; - b = this.f; + function(uint) external returns (uint) a, + function(uint) external view returns (uint) b + ) { + a = C(address(0x1234)).f; + b = C(address(0x1234)).f; } } +// ==== +// bytecodeFormat: legacy // ---- // f(uint256): 2 -> 4 // h(uint256): 2 -> 5 -// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000 +// t() -> 0x1234b3de648b0000000000000000, 0x1234b3de648b0000000000000000 diff --git a/test/libsolidity/semanticTests/viaYul/eof/function_address.sol b/test/libsolidity/semanticTests/viaYul/eof/function_address.sol new file mode 100644 index 000000000000..8a33e9d4c0b0 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/eof/function_address.sol @@ -0,0 +1,17 @@ +contract C { + function f() external returns (bool) { + return this.f.address != address(0); + } + function g() external returns (bool) { + return this.f.address == address(this); + } + function h(function() external a) public returns (address) { + return a.address; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> true +// g() -> true +// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF diff --git a/test/libsolidity/semanticTests/viaYul/function_address.sol b/test/libsolidity/semanticTests/viaYul/function_address.sol index 0c1c58dd821d..74b379994519 100644 --- a/test/libsolidity/semanticTests/viaYul/function_address.sol +++ b/test/libsolidity/semanticTests/viaYul/function_address.sol @@ -1,15 +1,20 @@ contract C { function f() external returns (address) { - return this.f.address; + return C(address(0x1234)).f.address; } - function g() external returns (bool) { - return this.f.address == address(this); + function g() external returns (bool, bool) { + return ( + this.f.address == address(this), + C(address(0x1234)).f.address == address(0x1234) + ); } function h(function() external a) public returns (address) { - return a.address; + return a.address; } } +// ==== +// bytecodeFormat: legacy // ---- -// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e -// g() -> true +// f() -> 0x1234 +// g() -> true, true // h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF