Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Add ABI version #5

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
30 changes: 23 additions & 7 deletions src/main.etk
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
98304
%end

%macro function_sig()
push4 0x9507d39a
%end

%macro get_input()
%push0()
calldataload
push1 4 # [4]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this is 4 words, you'll actually need to load 1 word and mask out the upper 4 bytes. you can see how to do that here: https://github.com/lightclient/erc20/blob/7b0d75d60f4e746c697a9ff88c62da411ac3f3b5/src/jump_table.etk#L20-L23

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calldataload puts 32 bytes from calldata on stack, and item on stack is the offset?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not load function selector but it loads the timestamp input from calldata BTW

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh this is 4 words

Nope, the calldataload offset is a byte-offset, not word-offset

func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x := scope.Stack.peek()
	if offset, overflow := x.Uint64WithOverflow(); !overflow {
		data := getData(scope.Contract.Input, offset, 32)
		x.SetBytes(data)

So it's correct

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah you're right i got confused with how i was mloading the data in the other project!

calldataload # [calldata[4:36]]
%end

%macro get_timestamp_index()
Expand All @@ -29,11 +33,23 @@ jumpi
# READ #
########

# Check if calldata is less than 32 bytes
push1 32 # [32]
calldatasize # [calldatasize, 32]
lt # [calldatasize < 32]
push1 revert # [revert_addr, calldatasize < 32]
# Check if calldata is 36 bytes
push1 36 # [36]
calldatasize # [calldatasize, 36]
eq # [calldatasize == 36]
iszero # [calldatasize != 36]
push1 revert # [revert_addr, calldatasize != 36]
jumpi # []
jochem-brouwer marked this conversation as resolved.
Show resolved Hide resolved

# Check if calldata has the function signature
jochem-brouwer marked this conversation as resolved.
Show resolved Hide resolved
push1 0 # [0]
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 # []

# Load stored timestamp.
Expand Down
14 changes: 13 additions & 1 deletion test/Contract.t.sol.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,23 @@ 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));
}

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));

Expand Down