From d066dd2bc0677e4b371471ede7f8ba034e36d21e Mon Sep 17 00:00:00 2001 From: wechman Date: Fri, 22 Jul 2022 10:16:04 +0200 Subject: [PATCH] Calldata validation tests --- .../calldata_dynamic_array_to_memory.sol | 27 ++++++++ .../calldata_nested_array_reencode.sol | 45 ++++++++---- .../calldata_overlapped_dynamic_arrays.sol | 43 ++++++++++++ ...ldata_overlapped_nested_dynamic_arrays.sol | 37 ++++++++++ .../calldata_struct_array_reencode.sol | 56 +++++++++++++++ ...dimensional_dynamic_array_index_access.sol | 42 +++++++++++ .../abiEncoderV2/calldata_with_garbage.sol | 69 +++++++++++++++++++ 7 files changed, 304 insertions(+), 15 deletions(-) create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_dynamic_array_to_memory.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_nested_dynamic_arrays.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_array_reencode.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_three_dimensional_dynamic_array_index_access.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/calldata_with_garbage.sol diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_dynamic_array_to_memory.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_dynamic_array_to_memory.sol new file mode 100644 index 000000000..6bc20432d --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_dynamic_array_to_memory.sol @@ -0,0 +1,27 @@ +pragma abicoder v2; + +contract C { + function f(uint[][] calldata a) public returns (uint[][] memory) { + return a; + } + + function g(uint[][][] calldata a) public returns (uint[][][] memory) { + return a; + } + + function h(uint[2][][] calldata a) public returns (uint[2][][] memory) { + return a; + } +} + +// ==== +// compileViaYul: also +// ---- +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE +// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_reencode.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_reencode.sol index 0872a7f5d..f62f105c8 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_reencode.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_reencode.sol @@ -1,22 +1,37 @@ pragma abicoder v2; contract C { - function h(uint[][] calldata a) public { - abi.encode(a); - } - struct S { uint[] x; } - function f(S calldata a) public { - abi.encode(a); - } + function f(uint[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function g(uint8[][][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function h(uint16[][2][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function i(uint16[][][1] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function j(uint16[2][][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } } // ==== // revertStrings: debug +// compileViaYul: also // ---- -// h(uint256[][]): 0x20, 1, 0x20, 0 -> -// h(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" -// h(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" -// h(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" -// f((uint256[])): 0x20, 0x20, 0 -> -// f((uint256[])): 0x20, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" -// f((uint256[])): 0x20, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" -// f((uint256[])): 0x20, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0 +// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access offset" +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 +// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 +// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 +// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15 +// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol new file mode 100644 index 000000000..7d197fcb5 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; + +contract C { + uint[] s; + uint[2] n; + + function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) { + return (a, b); + } + + function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) { + return abi.encode(a[which], b[1]); + } + + function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) { + s = a; + n = b; + return abi.encode(s); + } +} + +// ==== +// compileViaYul: also +// ---- +// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2 +// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6 +// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE +// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2 +// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6 +// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2 +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE +// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 +// gas irOptimized: 111653 +// gas legacy: 112987 +// gas legacyOptimized: 112104 +// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 +// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_nested_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_nested_dynamic_arrays.sol new file mode 100644 index 000000000..6ec079a81 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_nested_dynamic_arrays.sol @@ -0,0 +1,37 @@ +pragma abicoder v2; + +contract C { + uint[] s; + uint[2] n; + + function f_memory(uint[][] calldata a) public returns (uint[][] memory) { + return a; + } + + function f_encode(uint[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) { + return a[which]; + } +} + +// ==== +// compileViaYul: also +// ---- +// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE +// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE +// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2 +// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_array_reencode.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_array_reencode.sol new file mode 100644 index 000000000..17f0e1f84 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_array_reencode.sol @@ -0,0 +1,56 @@ +pragma abicoder v2; + +contract C { + struct D { uint[] x; } + struct S { uint x; } + + function f(D calldata a) public returns (bytes memory){ + return abi.encode(a); + } + + function g(D[2] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function h(D[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function i(D[2][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function j(S[] memory a) public returns (bytes memory) { + return abi.encode(a); + } + + function k(S[2] memory a) public returns (bytes memory) { + return abi.encode(a); + } + + function l(S[][] memory a) public returns (bytes memory) { + return abi.encode(a); + } + +} + +// ==== +// compileViaYul: also +// ---- +// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0 +// f((uint256[])): 0x20, 0x20, 1 -> FAILURE +// f((uint256[])): 0x20, 0x20, 2 -> FAILURE +// f((uint256[])): 0x20, 0x20, 3 -> FAILURE +// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 +// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE +// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 +// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE +// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 +// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE +// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2 +// j((uint256)[]): 0x20, 2, 1 -> FAILURE +// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2 +// k((uint256)[2]): 1 -> FAILURE +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_three_dimensional_dynamic_array_index_access.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_three_dimensional_dynamic_array_index_access.sol new file mode 100644 index 000000000..073bb25e2 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_three_dimensional_dynamic_array_index_access.sol @@ -0,0 +1,42 @@ +pragma abicoder v2; + +contract C { + struct S { uint[] a; } + + function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j]); + } + + function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) { + return abi.encode(s[i][j][k]); + } + + function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) { + return abi.encode(s[0][i]); + } + + function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j].a); + } + + function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j].a); + } +} + +// ==== +// compileViaYul: also +// revertStrings: debug +// ---- +// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7 +// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32 +// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9 +// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex"4e487b71", 0x32 +// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6 +// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32 +// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9 +// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_with_garbage.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_with_garbage.sol new file mode 100644 index 000000000..ef5ece3f0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_with_garbage.sol @@ -0,0 +1,69 @@ +pragma abicoder v2; + +contract C { + uint[] aTmp; + uint[2] bTmp; + + function f_memory(uint[] calldata a) public returns (uint[] memory) { + return a; + } + + function f_encode(uint[] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function f_storage(uint[] calldata a) public returns (bytes memory) { + aTmp = a; + return abi.encode(aTmp); + } + + function f_index(uint[] calldata a, uint which) public returns (uint) { + return a[which]; + } + + function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) { + return (a, b); + } + + function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + aTmp = a; + bTmp = b; + return abi.encode(aTmp, bTmp); + } + + function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) { + return (a[which], b[0]); + } +} + +// ==== +// compileViaYul: also +// ---- +// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0 +// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7 +// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0 +// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7 +// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0 +// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7 +// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7 +// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8 +// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex"4e487b71", 0x32 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0 +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7 +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0 +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7 +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1 +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1 +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE