From c0fc33d70485b1f2187314055044648a336f457e Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:05:46 +0200 Subject: [PATCH 01/12] add abi check (does not work) --- src/main.etk | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main.etk b/src/main.etk index 6e9d6c3..5e64344 100644 --- a/src/main.etk +++ b/src/main.etk @@ -7,8 +7,12 @@ 98304 %end +%macro function_sig() + push4 0x9507d39a +%end + %macro get_input() - %push0() + push1 4 calldataload %end @@ -29,10 +33,14 @@ jumpi # READ # ######## -# Check if calldata is less than 32 bytes -push1 32 # [32] -calldatasize # [calldatasize, 32] -lt # [calldatasize < 32] +# Check if calldata has the function signature +push1 0 # [0] +calldataload # [calldataload] +push1 224 +shr +%function_sig() # [] +eq +not push1 revert # [revert_addr, calldatasize < 32] jumpi # [] From ac42b0972674029e47a1aa1c610ce9d419c87c94 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:09:07 +0200 Subject: [PATCH 02/12] try to fix test --- test/Contract.t.sol.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Contract.t.sol.in b/test/Contract.t.sol.in index 2209680..a230ceb 100644 --- a/test/Contract.t.sol.in +++ b/test/Contract.t.sol.in @@ -27,7 +27,7 @@ contract ContractTest is Test { bytes memory root = hex"88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6"; vm.store(unit, bytes32(uint256(block.timestamp % historical_roots_modulus + historical_roots_modulus)), bytes32(root)); - (bool ret, bytes memory data) = unit.call(bytes.concat(bytes32(uint256(block.timestamp)))); + (bool ret, bytes memory data) = unit.call(bytes.concat(bytes4(0x9507d39a), bytes32(uint256(block.timestamp)))); assertTrue(ret); assertEq(data, bytes(root)); } From 4b81ca1bb043891fa7496c51682251c43a6d963f Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:18:58 +0200 Subject: [PATCH 03/12] this passes? --- src/main.etk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.etk b/src/main.etk index 5e64344..6337e28 100644 --- a/src/main.etk +++ b/src/main.etk @@ -36,11 +36,10 @@ jumpi # Check if calldata has the function signature push1 0 # [0] calldataload # [calldataload] -push1 224 +push1 28 shr %function_sig() # [] eq -not push1 revert # [revert_addr, calldatasize < 32] jumpi # [] From c949df35a56d029f731acf2c84b1b8adbd598a82 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:19:08 +0200 Subject: [PATCH 04/12] this does not pass --- src/main.etk | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.etk b/src/main.etk index 6337e28..b6cd5f9 100644 --- a/src/main.etk +++ b/src/main.etk @@ -40,6 +40,7 @@ push1 28 shr %function_sig() # [] eq +not push1 revert # [revert_addr, calldatasize < 32] jumpi # [] From dddf6fea3199799f15855a1eeb51530dd0b4ee26 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:19:19 +0200 Subject: [PATCH 05/12] restore old version --- src/main.etk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.etk b/src/main.etk index b6cd5f9..5e64344 100644 --- a/src/main.etk +++ b/src/main.etk @@ -36,7 +36,7 @@ jumpi # Check if calldata has the function signature push1 0 # [0] calldataload # [calldataload] -push1 28 +push1 224 shr %function_sig() # [] eq From d5a8e8d182415f0c5ca1f34d42b1d84b6337444d Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:24:18 +0200 Subject: [PATCH 06/12] add comments --- src/main.etk | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main.etk b/src/main.etk index 5e64344..8f0880e 100644 --- a/src/main.etk +++ b/src/main.etk @@ -13,7 +13,7 @@ %macro get_input() push1 4 - calldataload + calldataload # calldataloads[4:36] (timestamp) %end %macro get_timestamp_index() @@ -36,13 +36,13 @@ jumpi # Check if calldata has the function signature push1 0 # [0] calldataload # [calldataload] -push1 224 -shr -%function_sig() # [] -eq -not -push1 revert # [revert_addr, calldatasize < 32] -jumpi # [] +push1 224 # +shr # shift 224 bits to right, stack now has [function_sig] of the call (first 4 bytes) +%function_sig() # +eq # check if function_sig equals the first 4 bytes of calldata +not # invert +push1 revert # +jumpi # jumpi to revert iff function_sig != first 4 bytes of calldata # Load stored timestamp. push3 historical_roots_modulus() # [hrm, time] From 097c04e43b5cfc190ef30b837dd92ec833294241 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:31:53 +0200 Subject: [PATCH 07/12] update stack comments + add input length check --- src/main.etk | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main.etk b/src/main.etk index 8f0880e..b28ded2 100644 --- a/src/main.etk +++ b/src/main.etk @@ -12,8 +12,8 @@ %end %macro get_input() - push1 4 - calldataload # calldataloads[4:36] (timestamp) + push1 4 # [4] + calldataload # [calldata[4:36]] %end %macro get_timestamp_index() @@ -33,16 +33,24 @@ jumpi # READ # ######## +# Check if calldata is 36 bytes +push1 36 # [36] +calldatasize # [calldatasize, 36] +eq # [calldatasize == 36] +not # [calldatasize != 36] +push1 revert # [revert_addr, calldatasize != 36] +jumpi # [] + # Check if calldata has the function signature push1 0 # [0] calldataload # [calldataload] -push1 224 # -shr # shift 224 bits to right, stack now has [function_sig] of the call (first 4 bytes) -%function_sig() # -eq # check if function_sig equals the first 4 bytes of calldata -not # invert -push1 revert # -jumpi # jumpi to revert iff function_sig != first 4 bytes of calldata +push1 224 # [224, calldataload] +shr # [calldataload >> 224] +%function_sig() # [function_sig(), calldataload >> 224] +eq # [function_sig() == calldataload >> 224] +not # [function_sig() != calldataload >> 224] +push1 revert # [revert_addr, function_sig() != calldataload >> 224] +jumpi # [] # Load stored timestamp. push3 historical_roots_modulus() # [hrm, time] From 0f04d736d46540e318ab1210a7d13db5241186fc Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 11:34:48 +0200 Subject: [PATCH 08/12] add wrong sig check --- test/Contract.t.sol.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/Contract.t.sol.in b/test/Contract.t.sol.in index a230ceb..5f2b3fb 100644 --- a/test/Contract.t.sol.in +++ b/test/Contract.t.sol.in @@ -32,6 +32,18 @@ contract ContractTest is Test { assertEq(data, bytes(root)); } + function testReadWrongSig() public { + assertTrue(unit != address(0)); + + vm.store(unit, bytes32(uint256(block.timestamp % historical_roots_modulus)), bytes32(uint256(block.timestamp))); + + bytes memory root = hex"88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6"; + vm.store(unit, bytes32(uint256(block.timestamp % historical_roots_modulus + historical_roots_modulus)), bytes32(root)); + + (bool ret, bytes memory data) = unit.call(bytes.concat(bytes4(0x01020304), bytes32(uint256(block.timestamp)))); + assertFalse(ret); + } + function testUpdate() public { assertTrue(unit != address(0)); From 7fd49b42f2e1424b13aac1dee86af191a92f3b94 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 16:19:29 +0200 Subject: [PATCH 09/12] fix contract --- src/main.etk | 4 ++-- test/Contract.t.sol.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.etk b/src/main.etk index b28ded2..80ecda4 100644 --- a/src/main.etk +++ b/src/main.etk @@ -37,7 +37,7 @@ jumpi push1 36 # [36] calldatasize # [calldatasize, 36] eq # [calldatasize == 36] -not # [calldatasize != 36] +iszero # [calldatasize != 36] push1 revert # [revert_addr, calldatasize != 36] jumpi # [] @@ -48,7 +48,7 @@ push1 224 # [224, calldataload] shr # [calldataload >> 224] %function_sig() # [function_sig(), calldataload >> 224] eq # [function_sig() == calldataload >> 224] -not # [function_sig() != calldataload >> 224] +iszero # [function_sig() != calldataload >> 224] push1 revert # [revert_addr, function_sig() != calldataload >> 224] jumpi # [] diff --git a/test/Contract.t.sol.in b/test/Contract.t.sol.in index 5f2b3fb..e9bba02 100644 --- a/test/Contract.t.sol.in +++ b/test/Contract.t.sol.in @@ -40,7 +40,7 @@ contract ContractTest is Test { bytes memory root = hex"88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6"; vm.store(unit, bytes32(uint256(block.timestamp % historical_roots_modulus + historical_roots_modulus)), bytes32(root)); - (bool ret, bytes memory data) = unit.call(bytes.concat(bytes4(0x01020304), bytes32(uint256(block.timestamp)))); + (bool ret, /*bytes memory data*/) = unit.call(bytes.concat(bytes4(0x01020304), bytes32(uint256(block.timestamp)))); assertFalse(ret); } From 4109929627eaba0e94eae95a32d42b83196cd609 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 18:45:11 +0200 Subject: [PATCH 10/12] add revert fn macro --- src/main.etk | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main.etk b/src/main.etk index 80ecda4..8f924e1 100644 --- a/src/main.etk +++ b/src/main.etk @@ -21,6 +21,15 @@ timestamp mod %end + +# revert_if_neq reverts if the top two stack arguments are not equal +# stack: [a, b] (assumed precondition) +%macro revert_if_neq() + eq # [a == b] + iszero # [a != b] + push1 revert # [revert, a != b] + jumpi # [] +%end # If caller is from system, jump to update. caller @@ -47,10 +56,7 @@ calldataload # [calldataload] push1 224 # [224, calldataload] shr # [calldataload >> 224] %function_sig() # [function_sig(), calldataload >> 224] -eq # [function_sig() == calldataload >> 224] -iszero # [function_sig() != calldataload >> 224] -push1 revert # [revert_addr, function_sig() != calldataload >> 224] -jumpi # [] +%revert_if_neq() # Load stored timestamp. push3 historical_roots_modulus() # [hrm, time] @@ -61,10 +67,7 @@ sload # [want, time_index] # Verify stored timestamp matches input. %get_input() # [got, want, time_index] -eq # [got == want, time_index] -iszero # [got != want, time_index] -push1 revert # [revert_addr, got != want, time_index] -jumpi # [time_index] +%revert_if_neq() # Extend index to get root index. push3 historical_roots_modulus() # [hsm, time_index] From ddd59856d15c4761444d5720424f1fed60f8d078 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 18:57:25 +0200 Subject: [PATCH 11/12] fix comments --- src/main.etk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.etk b/src/main.etk index 6ffb097..cfdabfe 100644 --- a/src/main.etk +++ b/src/main.etk @@ -70,7 +70,7 @@ # Protect the submit routine by verifying the caller is equal to sysaddr(). caller # [caller] -push20 sysaddr() # [sysaddr, caller] +push20 sysaddr() # [sysaddr, caller] eq # [sysaddr == caller] push1 submit # [submitaddr, sysaddr == caller] jumpi # [] @@ -153,4 +153,8 @@ revert: jumpdest %push0() %push0() -revert \ No newline at end of file +revert + +############## +# REVERT END # +############## \ No newline at end of file From 3846d29c523d4817aeae7751f3bda3daa02522e9 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 4 Aug 2023 19:15:26 +0200 Subject: [PATCH 12/12] use selector --- src/main.etk | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main.etk b/src/main.etk index cfdabfe..37c9e10 100644 --- a/src/main.etk +++ b/src/main.etk @@ -39,10 +39,6 @@ 0xfffffffffffffffffffffffffffffffffffffffe %end -%macro function_sig() - push4 0x9507d39a -%end - %macro get_input() push1 4 # [4] calldataload # [calldata[4:36]] @@ -84,11 +80,11 @@ calldatasize # [calldatasize, 36] %revert_if_neq() # Check if calldata has the function signature -push1 0 # [0] -calldataload # [calldataload] -push1 224 # [224, calldataload] -shr # [calldataload >> 224] -%function_sig() # [function_sig(), calldataload >> 224] +push1 0 # [0] +calldataload # [calldataload] +push1 224 # [224, calldataload] +shr # [calldataload >> 224] +push4 selector("get(uint256)") # [function_sig, calldataload >> 224] %revert_if_neq() # Load stored timestamp.