aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity/SolidityEndToEndTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/libsolidity/SolidityEndToEndTest.cpp')
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp151
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();
}