From e3097b30dace9bbd88a5a74e6507baad0bc12cc4 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 4 Sep 2018 15:03:06 +0200 Subject: [PATCH] Add another end-to-end test. --- test/libsolidity/SolidityEndToEndTest.cpp | 127 ++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 922f0fb63..63067b3cc 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -12501,6 +12501,133 @@ BOOST_AUTO_TEST_CASE(bare_call_invalid_address) } } +BOOST_AUTO_TEST_CASE(bare_call_return_data) +{ + if (dev::test::Options::get().evmVersion().supportsReturndata()) + { + vector calltypes = {"call", "delegatecall"}; + if (dev::test::Options::get().evmVersion().hasStaticCall()) + calltypes.emplace_back("staticcall"); + for (string const& calltype: calltypes) + { + string sourceCode = R"DELIMITER( + contract A { + constructor() public { + } + function return_bool() public pure returns(bool) { + return true; + } + function return_int32() public pure returns(int32) { + return -32; + } + function return_uint32() public pure returns(uint32) { + return 0x3232; + } + function return_int256() public pure returns(int256) { + return -256; + } + function return_uint256() public pure returns(uint256) { + return 0x256256; + } + function return_bytes4() public pure returns(bytes4) { + return 0xabcd0012; + } + function return_multi() public pure returns(bool, uint32, bytes4) { + return (false, 0x3232, 0xabcd0012); + } + function return_bytes() public pure returns(bytes memory b) { + b = new bytes(2); + b[0] = 0x42; + b[1] = 0x21; + } + } + contract C { + A addr; + constructor() public { + addr = new A(); + } + function f(string memory signature) public returns (bool, bytes memory) { + return address(addr).)DELIMITER" + calltype + R"DELIMITER((abi.encodeWithSignature(signature)); + } + function check_bool() external returns (bool) { + (bool success, bytes memory data) = f("return_bool()"); + assert(success); + bool a = abi.decode(data, (bool)); + assert(a); + return true; + } + function check_int32() external returns (bool) { + (bool success, bytes memory data) = f("return_int32()"); + assert(success); + int32 a = abi.decode(data, (int32)); + assert(a == -32); + return true; + } + function check_uint32() external returns (bool) { + (bool success, bytes memory data) = f("return_uint32()"); + assert(success); + uint32 a = abi.decode(data, (uint32)); + assert(a == 0x3232); + return true; + } + function check_int256() external returns (bool) { + (bool success, bytes memory data) = f("return_int256()"); + assert(success); + int256 a = abi.decode(data, (int256)); + assert(a == -256); + return true; + } + function check_uint256() external returns (bool) { + (bool success, bytes memory data) = f("return_uint256()"); + assert(success); + uint256 a = abi.decode(data, (uint256)); + assert(a == 0x256256); + return true; + } + function check_bytes4() external returns (bool) { + (bool success, bytes memory data) = f("return_bytes4()"); + assert(success); + bytes4 a = abi.decode(data, (bytes4)); + assert(a == 0xabcd0012); + return true; + } + function check_multi() external returns (bool) { + (bool success, bytes memory data) = f("return_multi()"); + assert(success); + (bool a, uint32 b, bytes4 c) = abi.decode(data, (bool, uint32, bytes4)); + assert(a == false && b == 0x3232 && c == 0xabcd0012); + return true; + } + function check_bytes() external returns (bool) { + (bool success, bytes memory data) = f("return_bytes()"); + assert(success); + (bytes memory d) = abi.decode(data, (bytes)); + assert(d.length == 2 && d[0] == 0x42 && d[1] == 0x21); + return true; + } + } + )DELIMITER"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_bool()"))), encodeArgs(true, 0x40, 0x20, true)); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_int32()"))), encodeArgs(true, 0x40, 0x20, u256(-32))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_uint32()"))), encodeArgs(true, 0x40, 0x20, u256(0x3232))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_int256()"))), encodeArgs(true, 0x40, 0x20, u256(-256))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_uint256()"))), encodeArgs(true, 0x40, 0x20, u256(0x256256))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_bytes4()"))), encodeArgs(true, 0x40, 0x20, u256(0xabcd0012) << (28*8))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_multi()"))), encodeArgs(true, 0x40, 0x60, false, u256(0x3232), u256(0xabcd0012) << (28*8))); + ABI_CHECK(callContractFunction("f(string)", encodeDyn(string("return_bytes()"))), encodeArgs(true, 0x40, 0x60, 0x20, 0x02, encode(bytes{0x42,0x21}, false))); + ABI_CHECK(callContractFunction("check_bool()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_int32()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_uint32()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_int256()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_uint256()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_bytes4()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_multi()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("check_bytes()"), encodeArgs(true)); + } + } +} + BOOST_AUTO_TEST_CASE(delegatecall_return_value) { if (dev::test::Options::get().evmVersion().supportsReturndata())