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.cpp142
1 files changed, 111 insertions, 31 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index f3fdef15..1ecd7a2c 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1320,7 +1320,7 @@ BOOST_AUTO_TEST_CASE(balance)
BOOST_AUTO_TEST_CASE(blockchain)
{
char const* sourceCode = "contract test {\n"
- " function someInfo() returns (uint256 value, address coinbase, uint256 blockNumber) {\n"
+ " function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) {\n"
" value = msg.value;\n"
" coinbase = block.coinbase;\n"
" blockNumber = block.number;\n"
@@ -1342,7 +1342,7 @@ BOOST_AUTO_TEST_CASE(msg_sig)
}
)";
compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunctionWithValue("foo(uint256)", 13) == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes())));
+ BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes())));
}
BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
@@ -1358,7 +1358,7 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
}
)";
compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunctionWithValue("foo(uint256)", 13) == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes())));
+ BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes())));
}
BOOST_AUTO_TEST_CASE(now)
@@ -1526,8 +1526,10 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size)
}
})";
compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("UintToBytes(uint16)", u256("0x6162")) ==
- encodeArgs(string("\0\0\0\0\0\0ab", 8)));
+ BOOST_CHECK(
+ callContractFunction("UintToBytes(uint16)", u256("0x6162")) ==
+ encodeArgs(string("\0\0\0\0\0\0ab", 8))
+ );
}
BOOST_AUTO_TEST_CASE(send_ether)
@@ -2053,11 +2055,11 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses)
{
char const* sourceCode = R"(
contract helper {
- function() { } // can receive ether
+ function() payable { } // can receive ether
}
contract test {
helper h;
- function test() { h = new helper(); h.send(5); }
+ function test() payable { h = new helper(); h.send(5); }
function getBalance() returns (uint256 myBalance, uint256 helperBalance) {
myBalance = this.balance;
helperBalance = h.balance;
@@ -2065,6 +2067,7 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses)
}
)";
compileAndRun(sourceCode, 20);
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 20 - 5);
BOOST_REQUIRE(callContractFunction("getBalance()") == encodeArgs(u256(20 - 5), u256(5)));
}
@@ -2073,7 +2076,7 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
char const* sourceCode = R"(
contract helper {
bool flag;
- function getBalance() returns (uint256 myBalance) {
+ function getBalance() payable returns (uint256 myBalance) {
return this.balance;
}
function setFlag() { flag = true; }
@@ -2081,8 +2084,8 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
}
contract test {
helper h;
- function test() { h = new helper(); }
- function sendAmount(uint amount) returns (uint256 bal) {
+ function test() payable { h = new helper(); }
+ function sendAmount(uint amount) payable returns (uint256 bal) {
return h.getBalance.value(amount)();
}
function outOfGas() returns (bool ret) {
@@ -2098,8 +2101,8 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
compileAndRun(sourceCode, 20);
BOOST_REQUIRE(callContractFunction("sendAmount(uint256)", 5) == encodeArgs(5));
// call to helper should not succeed but amount should be transferred anyway
- BOOST_REQUIRE(callContractFunction("outOfGas()", 5) == bytes());
- BOOST_REQUIRE(callContractFunction("checkState()", 5) == encodeArgs(false, 20 - 5));
+ BOOST_REQUIRE(callContractFunction("outOfGas()") == bytes());
+ BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
}
BOOST_AUTO_TEST_CASE(gas_for_builtin)
@@ -2121,14 +2124,14 @@ BOOST_AUTO_TEST_CASE(value_complex)
{
char const* sourceCode = R"(
contract helper {
- function getBalance() returns (uint256 myBalance) {
+ function getBalance() payable returns (uint256 myBalance) {
return this.balance;
}
}
contract test {
helper h;
- function test() { h = new helper(); }
- function sendAmount(uint amount) returns (uint256 bal) {
+ function test() payable { h = new helper(); }
+ function sendAmount(uint amount) payable returns (uint256 bal) {
var x1 = h.getBalance.value(amount);
uint someStackElement = 20;
var x2 = x1.gas(1000);
@@ -2144,13 +2147,13 @@ BOOST_AUTO_TEST_CASE(value_insane)
{
char const* sourceCode = R"(
contract helper {
- function getBalance() returns (uint256 myBalance) {
+ function getBalance() payable returns (uint256 myBalance) {
return this.balance;
}
}
contract test {
helper h;
- function test() { h = new helper(); }
+ function test() payable { h = new helper(); }
function sendAmount(uint amount) returns (uint256 bal) {
var x1 = h.getBalance.value;
var x2 = x1(amount).gas;
@@ -2169,7 +2172,7 @@ BOOST_AUTO_TEST_CASE(value_for_constructor)
contract Helper {
bytes3 name;
bool flag;
- function Helper(bytes3 x, bool f) {
+ function Helper(bytes3 x, bool f) payable {
name = x;
flag = f;
}
@@ -2178,7 +2181,7 @@ BOOST_AUTO_TEST_CASE(value_for_constructor)
}
contract Main {
Helper h;
- function Main() {
+ function Main() payable {
h = (new Helper).value(10)("abc", true);
}
function getFlag() returns (bool ret) { return h.getFlag(); }
@@ -2352,7 +2355,7 @@ BOOST_AUTO_TEST_CASE(function_modifier)
{
char const* sourceCode = R"(
contract C {
- function getOne() nonFree returns (uint r) { return 1; }
+ function getOne() payable nonFree returns (uint r) { return 1; }
modifier nonFree { if (msg.value > 0) _; }
}
)";
@@ -2559,7 +2562,7 @@ BOOST_AUTO_TEST_CASE(event)
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
- function deposit(bytes32 _id, bool _manually) {
+ function deposit(bytes32 _id, bool _manually) payable {
if (_manually) {
bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;
log3(bytes32(msg.value), s, bytes32(msg.sender), _id);
@@ -2624,7 +2627,7 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics)
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;
- function deposit(bytes32 _id, bool _manually) {
+ function deposit(bytes32 _id, bool _manually) payable {
Deposit(msg.sender, _id, msg.value, 2, "abc");
}
}
@@ -2648,7 +2651,7 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address _from, bytes32 _id, uint _value, bool _flag);
- function deposit(bytes32 _id) {
+ function deposit(bytes32 _id) payable {
Deposit(msg.sender, _id, msg.value, true);
}
}
@@ -2874,9 +2877,10 @@ BOOST_AUTO_TEST_CASE(generic_call)
char const* sourceCode = R"**(
contract receiver {
uint public received;
- function receive(uint256 x) { received = x; }
+ function receive(uint256 x) payable { received = x; }
}
contract sender {
+ function sender() payable {}
function doSend(address rec) returns (uint d)
{
bytes4 signature = bytes4(bytes32(sha3("receive(uint256)")));
@@ -2897,10 +2901,11 @@ BOOST_AUTO_TEST_CASE(generic_callcode)
char const* sourceCode = R"**(
contract receiver {
uint public received;
- function receive(uint256 x) { received = x; }
+ function receive(uint256 x) payable { received = x; }
}
contract sender {
uint public received;
+ function sender() payable { }
function doSend(address rec) returns (uint d)
{
bytes4 signature = bytes4(bytes32(sha3("receive(uint256)")));
@@ -2930,16 +2935,16 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
uint public received;
address public sender;
uint public value;
- function receive(uint256 x) { received = x; sender = msg.sender; value = msg.value; }
+ function receive(uint256 x) payable { received = x; sender = msg.sender; value = msg.value; }
}
contract sender {
uint public received;
address public sender;
uint public value;
- function doSend(address rec)
+ function doSend(address rec) payable
{
bytes4 signature = bytes4(bytes32(sha3("receive(uint256)")));
- rec.delegatecall(signature, 23);
+ if (rec.delegatecall(signature, 23)) {}
}
}
)**";
@@ -5958,7 +5963,7 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)
function f(address x) returns (bool) {
return x.send(1);
}
- function () {}
+ function () payable {}
}
)";
compileAndRun(sourceCode, 0, "lib");
@@ -6876,7 +6881,7 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types_for_structs)
BOOST_AUTO_TEST_CASE(failed_create)
{
char const* sourceCode = R"(
- contract D { }
+ contract D { function D() payable {} }
contract C {
uint public x;
function f(uint amount) returns (address) {
@@ -7026,7 +7031,7 @@ BOOST_AUTO_TEST_CASE(mutex)
else
return fund.withdrawUnprotected(10);
}
- function() {
+ function() payable {
callDepth++;
if (callDepth < 4)
attackInternal();
@@ -7087,6 +7092,81 @@ BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
BOOST_CHECK(callContractFunction("h()") == encodeArgs(u256(7)));
}
+BOOST_AUTO_TEST_CASE(payable_constructor)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function C() payable { }
+ }
+ )";
+ compileAndRun(sourceCode, 27, "C");
+}
+
+BOOST_AUTO_TEST_CASE(payable_function)
+{
+ char const* sourceCode = R"(
+ contract C {
+ uint public a;
+ function f() payable returns (uint) {
+ return msg.value;
+ }
+ function() payable {
+ a = msg.value + 1;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs(u256(27)));
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27);
+ BOOST_CHECK(callContractFunctionWithValue("", 27) == encodeArgs());
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27 + 27);
+ BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(28)));
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27 + 27);
+}
+
+BOOST_AUTO_TEST_CASE(non_payable_throw)
+{
+ char const* sourceCode = R"(
+ contract C {
+ uint public a;
+ function f() returns (uint) {
+ return msg.value;
+ }
+ function() {
+ a = msg.value + 1;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs());
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
+ BOOST_CHECK(callContractFunction("") == encodeArgs());
+ BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunctionWithValue("", 27) == encodeArgs());
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
+ BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunctionWithValue("a()", 27) == encodeArgs());
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
+}
+
+BOOST_AUTO_TEST_CASE(no_nonpayable_circumvention_by_modifier)
+{
+ char const* sourceCode = R"(
+ contract C {
+ modifier tryCircumvent {
+ if (false) _; // avoid the function, we should still not accept ether
+ }
+ function f() tryCircumvent returns (uint) {
+ return msg.value;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs());
+ BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
}