diff --git a/crates/fv/tests/specs.rs b/crates/fv/tests/specs.rs index 33fb7ecfce..6190b31458 100644 --- a/crates/fv/tests/specs.rs +++ b/crates/fv/tests/specs.rs @@ -64,4 +64,5 @@ test_spec! { abi_address_u16_revert_1, "abi/foo.fe", "abi/address_u16_revert_1.k // storage test_spec! { store_u256, "storage/foo.fe", "storage/store_u256.k" } -test_spec! { store_map, "storage/foo.fe", "storage/store_sol_map.k" } +test_spec! { store_sol_map, "storage/foo.fe", "storage/store_sol_map.k" } +test_spec! { store_fe_map, "storage/foo.fe", "storage/store_fe_map.k" } diff --git a/crates/test-files/fixtures/kspecs/storage/foo.fe b/crates/test-files/fixtures/kspecs/storage/foo.fe index 4d48aca87e..1892d9de48 100644 --- a/crates/test-files/fixtures/kspecs/storage/foo.fe +++ b/crates/test-files/fixtures/kspecs/storage/foo.fe @@ -10,7 +10,7 @@ contract StoreU256: contract StoreSolMap: - pub fn __call__(self): + pub fn __call__(): unsafe: let key: u256 = evm::call_data_load(0) evm::mstore(0, key) @@ -19,3 +19,12 @@ contract StoreSolMap: let value: u256 = evm::sload(slot) evm::mstore(0, value) evm::return_mem(0, 32) + +contract StoreFeMap: + my_map: Map + + pub fn __call__(self): + unsafe: + let key: u256 = evm::call_data_load(0) + evm::mstore(0, self.my_map[key]) + evm::return_mem(0, 32) diff --git a/crates/test-files/fixtures/kspecs/storage/store_fe_map.k b/crates/test-files/fixtures/kspecs/storage/store_fe_map.k new file mode 100644 index 0000000000..c5754988f1 --- /dev/null +++ b/crates/test-files/fixtures/kspecs/storage/store_fe_map.k @@ -0,0 +1,109 @@ +module $TEST_NAME + imports VERIFICATION + + claim + + + #execute => #halt + 1 + NORMAL + ISTANBUL + + + + #buf(32, VAL) + _ => EVMC_SUCCESS + _ => ?_ + _ + _ + _ => ?_ + + + #parseByteStack($StoreFeMap::RUNTIME) + #computeValidJumpDests(#parseByteStack($StoreFeMap::RUNTIME)) + + ACCT_ID // contract owner + CALLER_ID // who called this contract; in the beginning, origin // msg.sender + + #buf(32, KEY) + + 0 + .WordStack => ?_ + .Memory => ?_ + 0 => ?_ + #gas(_VGAS) => ?_ + 0 => ?_ + _ => ?_ + + false // NOTE: non-static call + CALL_DEPTH + + + + _ + _ + _ // TODO: more detail + _ => ?_ + _ => ?_ + + + _ + ORIGIN_ID // who fires tx + + _ + + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + _ + + + + + _ + + SetItem(ACCT_ID) _:Set + + + + ACCT_ID + _ + #parseByteStack($StoreFeMap::RUNTIME) + #hashedLocation("Fe", 0, KEY) |-> VAL _:Map + _ + _ + + + + _ + _ + _ + + + + + requires 0 <=Int ACCT_ID andBool ACCT_ID Vec { ] } -/// Returns the highest available pointer. +/// Returns the highest available pointerhttps://buy.gazelle.com/collections/ipads?_=pf&pf_v_model=iPad%20Pro%2012.9%204th%20Gen. pub fn avail() -> yul::Statement { function_definition! { function avail() -> ptr { @@ -315,7 +315,7 @@ pub fn bytes_sloadn() -> yul::Statement { function bytes_sloadn(sptr, size) -> val { (let word_ptr := div(sptr, 32)) (let bytes_offset := mod(sptr, 32)) - (val := sloadn(word_ptr, bytes_offset, size)) + (val := sload(word_ptr)) } } } @@ -354,7 +354,7 @@ pub fn map_value_ptr() -> yul::Statement { (mstore(ptr, a)) (mstore((add(ptr, 32)), b)) (let hash := keccak256(ptr, 64)) - (return_val := set_zero(248, 256, hash)) + (return_val := mul((div(hash, 256)), 256)) } } }