diff --git a/actors/evm/tests/basic.rs b/actors/evm/tests/basic.rs index be57a4fb7..d59518049 100644 --- a/actors/evm/tests/basic.rs +++ b/actors/evm/tests/basic.rs @@ -202,3 +202,30 @@ fn test_push_last_byte() { util::invoke_contract(&rt, &[]); } + +#[test] +fn mcopy() { + let bytecode = hex::decode(include_str!("contracts/MCOPYTest.hex")).unwrap(); + mcopy_test(bytecode); +} + +fn mcopy_test(bytecode: Vec) { + let contract = Address::new_id(100); + + let rt = util::init_construct_and_verify(bytecode, |rt| { + rt.actor_code_cids.borrow_mut().insert(contract, *EVM_ACTOR_CODE_ID); + rt.set_origin(contract); + }); + + // invoke contract + + let encoded_testdata = hex::decode("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000087465737464617461000000000000000000000000000000000000000000000000").unwrap(); + + let mut solidity_params = vec![]; + + solidity_params.extend_from_slice(&hex::decode("73358055").unwrap()); // function selector, "optimizedCopy(bytes)" + solidity_params.extend_from_slice(&encoded_testdata); + + let result = util::invoke_contract(&rt, &solidity_params); + assert_eq!(&*result, &*encoded_testdata); +} diff --git a/actors/evm/tests/contracts/MCOPYTest.hex b/actors/evm/tests/contracts/MCOPYTest.hex new file mode 100644 index 000000000..72db0fa73 --- /dev/null +++ b/actors/evm/tests/contracts/MCOPYTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f80fd5b506103148061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063733580551461002d575b5f80fd5b61004760048036038101906100429190610217565b61005d565b60405161005491906102be565b60405180910390f35b60605f825167ffffffffffffffff81111561007b5761007a6100f3565b5b6040519080825280601f01601f1916602001820160405280156100ad5781602001600182028036833780820191505090505b509050825160208401602083018282825e50505080915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610129826100e3565b810181811067ffffffffffffffff82111715610148576101476100f3565b5b80604052505050565b5f61015a6100ca565b90506101668282610120565b919050565b5f67ffffffffffffffff821115610185576101846100f3565b5b61018e826100e3565b9050602081019050919050565b828183375f83830152505050565b5f6101bb6101b68461016b565b610151565b9050828152602081018484840111156101d7576101d66100df565b5b6101e284828561019b565b509392505050565b5f82601f8301126101fe576101fd6100db565b5b813561020e8482602086016101a9565b91505092915050565b5f6020828403121561022c5761022b6100d3565b5b5f82013567ffffffffffffffff811115610249576102486100d7565b5b610255848285016101ea565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6102908261025e565b61029a8185610268565b93506102aa818560208601610278565b6102b3816100e3565b840191505092915050565b5f6020820190508181035f8301526102d68184610286565b90509291505056fea2646970667358221220636e7de4492dd5c1e8857edc7182c645466bf34d0a2a0cea445a7de5360a9fe364736f6c634300081a0033 \ No newline at end of file diff --git a/actors/evm/tests/contracts/MCOPYTest.sol b/actors/evm/tests/contracts/MCOPYTest.sol new file mode 100644 index 000000000..21e0ed397 --- /dev/null +++ b/actors/evm/tests/contracts/MCOPYTest.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +contract MCOPYTest { + function optimizedCopy(bytes memory data) public pure returns (bytes memory) { + bytes memory result = new bytes(data.length); + assembly { + let length := mload(data) // Get the length of the input data + let source := add(data, 0x20) // Point to the start of the data (skip the length) + let destination := add(result, 0x20) // Point to the start of the result memory (skip the length) + + // Use MCOPY opcode directly for memory copying + // destination: destination memory pointer + // source: source memory pointer + // length: number of bytes to copy + mcopy(destination, source, length) + } + return result; + } + +}