diff options
Diffstat (limited to 'test/libsolidity/SolidityEndToEndTest.cpp')
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 151 |
1 files changed, 115 insertions, 36 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 85582ece..f65c8b27 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2215,7 +2215,7 @@ BOOST_AUTO_TEST_CASE(send_ether) char const* sourceCode = R"( contract test { constructor() payable public {} - function a(address addr, uint amount) public returns (uint ret) { + function a(address payable addr, uint amount) public returns (uint ret) { addr.send(amount); return address(this).balance; } @@ -2233,11 +2233,11 @@ BOOST_AUTO_TEST_CASE(transfer_ether) char const* sourceCode = R"( contract A { constructor() public payable {} - function a(address addr, uint amount) public returns (uint) { + function a(address payable addr, uint amount) public returns (uint) { addr.transfer(amount); return address(this).balance; } - function b(address addr, uint amount) public { + function b(address payable addr, uint amount) public { addr.transfer(amount); } } @@ -2406,7 +2406,7 @@ BOOST_AUTO_TEST_CASE(selfdestruct) char const* sourceCode = R"( contract test { constructor() public payable {} - function a(address receiver) public returns (uint ret) { + function a(address payable receiver) public returns (uint ret) { selfdestruct(receiver); return 10; } @@ -3039,26 +3039,26 @@ BOOST_AUTO_TEST_CASE(gasprice) BOOST_AUTO_TEST_CASE(blockhash) { - char const* sourceCode = R"( - contract C { - uint256 counter; - function g() public returns (bool) { counter++; return true; } - function f() public returns (bytes32[] memory r) { - r = new bytes32[](259); - for (uint i = 0; i < 259; i++) - r[i] = blockhash(block.number - 257 + i); - } - } - )"; - compileAndRun(sourceCode); - // generate a sufficient amount of blocks - while (blockNumber() < u256(255)) - ABI_CHECK(callContractFunction("g()"), encodeArgs(true)); - - vector<u256> hashes; - // currently the test only works for pre-constantinople + // depending on the aleth version, this test only works for pre-constantinople if (Options::get().evmVersion() < EVMVersion::constantinople()) { + char const* sourceCode = R"( + contract C { + uint256 counter; + function g() public returns (bool) { counter++; return true; } + function f() public returns (bytes32[] memory r) { + r = new bytes32[](259); + for (uint i = 0; i < 259; i++) + r[i] = blockhash(block.number - 257 + i); + } + } + )"; + compileAndRun(sourceCode); + // generate a sufficient amount of blocks + while (blockNumber() < u256(255)) + ABI_CHECK(callContractFunction("g()"), encodeArgs(true)); + + vector<u256> hashes; // ``blockhash()`` is only valid for the last 256 blocks, otherwise zero hashes.emplace_back(0); for (u256 i = blockNumber() - u256(255); i <= blockNumber(); i++) @@ -3067,18 +3067,9 @@ BOOST_AUTO_TEST_CASE(blockhash) hashes.emplace_back(0); // future block hashes are zero hashes.emplace_back(0); - } - else - // TODO: Starting from constantinople blockhash always seems to return zero. - // The blockhash contract introduced in EIP96 seems to break in our setup of - // aleth (setting the constantinople fork block to zero and resetting the chain - // to block zero before each test run). Pre-deploying the blockchain contract - // during genesis seems to help, but currently causes problems with other tests. - // Set the expectation to zero for now, so that this test tracks changes in this - // behavior. - hashes.assign(259, 0); - ABI_CHECK(callContractFunction("f()"), encodeDyn(hashes)); + ABI_CHECK(callContractFunction("f()"), encodeDyn(hashes)); + } } BOOST_AUTO_TEST_CASE(value_complex) @@ -7151,7 +7142,7 @@ BOOST_AUTO_TEST_CASE(failing_send) } contract Main { constructor() public payable {} - function callHelper(address _a) public returns (bool r, uint bal) { + function callHelper(address payable _a) public returns (bool r, uint bal) { r = !_a.send(5); bal = address(this).balance; } @@ -8838,7 +8829,7 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library) library lib {} contract c { constructor() public payable {} - function f(address x) public returns (bool) { + function f(address payable x) public returns (bool) { return x.send(1); } function () external payable {} @@ -10095,6 +10086,54 @@ BOOST_AUTO_TEST_CASE(cleanup_bytes_types_shortening) ABI_CHECK(callContractFunction("f()"), encodeArgs("\xff\xff\xff\xff")); } +BOOST_AUTO_TEST_CASE(cleanup_address_types) +{ + // Checks that address types are properly cleaned before they are compared. + char const* sourceCode = R"( + contract C { + function f(address a) public returns (uint) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } + function g(address payable a) public returns (uint) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + // We input longer data on purpose. + ABI_CHECK(callContractFunction("f(address)", u256("0xFFFF1234567890123456789012345678901234567890")), encodeArgs(0)); + ABI_CHECK(callContractFunction("g(address)", u256("0xFFFF1234567890123456789012345678901234567890")), encodeArgs(0)); +} + +BOOST_AUTO_TEST_CASE(cleanup_address_types_shortening) +{ + char const* sourceCode = R"( + contract C { + function f() public pure returns (address r) { + bytes21 x = 0x1122334455667788990011223344556677889900ff; + bytes20 y; + assembly { y := x } + address z = address(y); + assembly { r := z } + require(z == 0x1122334455667788990011223344556677889900); + } + function g() public pure returns (address payable r) { + bytes21 x = 0x1122334455667788990011223344556677889900ff; + bytes20 y; + assembly { y := x } + address payable z = address(y); + assembly { r := z } + require(z == 0x1122334455667788990011223344556677889900); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256("0x1122334455667788990011223344556677889900"))); + ABI_CHECK(callContractFunction("g()"), encodeArgs(u256("0x1122334455667788990011223344556677889900"))); +} + BOOST_AUTO_TEST_CASE(skip_dynamic_types) { // The EVM cannot provide access to dynamically-sized return values, so we have to skip them. @@ -11870,6 +11909,46 @@ BOOST_AUTO_TEST_CASE(shift_bytes_cleanup) ABI_CHECK(callContractFunction("right(uint8)", 8 * 8), encodeArgs(string(8, 0) + "123456789012")); } +BOOST_AUTO_TEST_CASE(exp_cleanup) +{ + char const* sourceCode = R"( + contract C { + function f() public pure returns (uint8 x) { + uint8 y = uint8(2) ** uint8(8); + return 0 ** y; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1))); +} + +BOOST_AUTO_TEST_CASE(exp_cleanup_direct) +{ + char const* sourceCode = R"( + contract C { + function f() public pure returns (uint8 x) { + return uint8(0) ** uint8(uint8(2) ** uint8(8)); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1))); +} + +BOOST_AUTO_TEST_CASE(exp_cleanup_nonzero_base) +{ + char const* sourceCode = R"( + contract C { + function f() public pure returns (uint8 x) { + return uint8(0x166) ** uint8(uint8(2) ** uint8(8)); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1))); +} + BOOST_AUTO_TEST_CASE(cleanup_in_compound_assign) { char const* sourceCode = R"( @@ -12406,7 +12485,7 @@ BOOST_AUTO_TEST_CASE(interface_contract) } contract C { - function f(address _interfaceAddress) public returns (bool) { + function f(address payable _interfaceAddress) public returns (bool) { I i = I(_interfaceAddress); return i.f(); } |