aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2016-09-06 18:25:19 +0800
committerGitHub <noreply@github.com>2016-09-06 18:25:19 +0800
commitf687635e4743a1e12d01fb082a4f8a76a759ab48 (patch)
tree7e3b917cfcc5ebf44c6770c6d742da0fa9277a12 /test
parent171c74843bb231c4663ec0fe7f4252ac03266f53 (diff)
parentdff9633084ebc241d8268c5dbd35a0c5307fd6fc (diff)
downloaddexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar.gz
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar.bz2
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar.lz
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar.xz
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.tar.zst
dexon-solidity-f687635e4743a1e12d01fb082a4f8a76a759ab48.zip
Merge pull request #665 from axic/feature/accept-ether
BREAKING: Add payable modifier
Diffstat (limited to 'test')
-rw-r--r--test/contracts/AuctionRegistrar.cpp7
-rw-r--r--test/contracts/FixedFeeRegistrar.cpp2
-rw-r--r--test/contracts/Wallet.cpp2
-rw-r--r--test/libsolidity/Assembly.cpp2
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp69
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp142
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp108
-rw-r--r--test/libsolidity/SolidityParser.cpp10
8 files changed, 301 insertions, 41 deletions
diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp
index 9161f2ce..05da3490 100644
--- a/test/contracts/AuctionRegistrar.cpp
+++ b/test/contracts/AuctionRegistrar.cpp
@@ -115,11 +115,6 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
// TODO: Populate with hall-of-fame.
}
- function() {
- // prevent people from just sending funds to the registrar
- throw;
- }
-
function onAuctionEnd(string _name) internal {
var auction = m_auctions[_name];
var record = m_toRecord[_name];
@@ -136,7 +131,7 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
}
}
- function reserve(string _name) external {
+ function reserve(string _name) external payable {
if (bytes(_name).length == 0)
throw;
bool needAuction = requiresAuction(_name);
diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp
index c37873cf..af8ee595 100644
--- a/test/contracts/FixedFeeRegistrar.cpp
+++ b/test/contracts/FixedFeeRegistrar.cpp
@@ -73,7 +73,7 @@ contract FixedFeeRegistrar is Registrar {
modifier onlyrecordowner(string _name) { if (m_record(_name).owner == msg.sender) _; }
- function reserve(string _name) {
+ function reserve(string _name) payable {
Record rec = m_record(_name);
if (rec.owner == 0 && msg.value >= c_fee) {
rec.owner = msg.sender;
diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp
index d3e1b8d7..b4f29a87 100644
--- a/test/contracts/Wallet.cpp
+++ b/test/contracts/Wallet.cpp
@@ -378,7 +378,7 @@ contract Wallet is multisig, multiowned, daylimit {
}
// gets called when no other function matches
- function() {
+ function() payable {
// just being sent some cash?
if (msg.value > 0)
Deposit(msg.sender, msg.value);
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index 81332f4f..8d7a3540 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(location_test)
AssemblyItems items = compileContract(sourceCode);
vector<SourceLocation> locations =
vector<SourceLocation>(18, SourceLocation(2, 75, n)) +
- vector<SourceLocation>(28, SourceLocation(20, 72, n)) +
+ vector<SourceLocation>(31, SourceLocation(20, 72, n)) +
vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
vector<SourceLocation>(4, SourceLocation(58, 67, n)) +
vector<SourceLocation>(3, SourceLocation(20, 72, n));
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index ec621104..185ba3bf 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -68,6 +68,7 @@ BOOST_AUTO_TEST_CASE(basic_test)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -107,6 +108,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -124,6 +126,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
{
"name": "g",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -153,6 +156,7 @@ BOOST_AUTO_TEST_CASE(multiple_params)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -188,6 +192,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
{
"name": "c",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -205,6 +210,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -235,6 +241,7 @@ BOOST_AUTO_TEST_CASE(const_function)
{
"name": "foo",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -256,6 +263,7 @@ BOOST_AUTO_TEST_CASE(const_function)
{
"name": "boo",
"constant": true,
+ "payable" : false,
"type": "function",
"inputs": [{
"name": "a",
@@ -284,6 +292,7 @@ BOOST_AUTO_TEST_CASE(events)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -361,6 +370,7 @@ BOOST_AUTO_TEST_CASE(inherited)
{
"name": "baseFunction",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs":
[{
@@ -376,6 +386,7 @@ BOOST_AUTO_TEST_CASE(inherited)
{
"name": "derivedFunction",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs":
[{
@@ -429,6 +440,7 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -469,6 +481,7 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
{
"name": "f",
"constant": false,
+ "payable" : false,
"type": "function",
"inputs": [
{
@@ -536,6 +549,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi)
[
{
"constant" : false,
+ "payable" : false,
"inputs" : [],
"name" : "ret",
"outputs" : [
@@ -573,6 +587,7 @@ BOOST_AUTO_TEST_CASE(strings_and_arrays)
[
{
"constant" : false,
+ "payable" : false,
"name": "f",
"inputs": [
{ "name": "a", "type": "string" },
@@ -600,6 +615,7 @@ BOOST_AUTO_TEST_CASE(library_function)
[
{
"constant" : false,
+ "payable" : false,
"name": "f",
"inputs": [
{ "name": "b", "type": "test.StructType storage" },
@@ -629,6 +645,59 @@ BOOST_AUTO_TEST_CASE(include_fallback_function)
[
{
"constant" : false,
+ "payable": false,
+ "type" : "fallback"
+ }
+ ]
+ )";
+ checkInterface(sourceCode, interface);
+}
+
+BOOST_AUTO_TEST_CASE(payable_function)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() {}
+ function g() payable {}
+ }
+ )";
+
+ char const* interface = R"(
+ [
+ {
+ "constant" : false,
+ "payable": false,
+ "inputs": [],
+ "name": "f",
+ "outputs": [],
+ "type" : "function"
+ },
+ {
+ "constant" : false,
+ "payable": true,
+ "inputs": [],
+ "name": "g",
+ "outputs": [],
+ "type" : "function"
+ }
+ ]
+ )";
+ checkInterface(sourceCode, interface);
+}
+
+BOOST_AUTO_TEST_CASE(payable_fallback_unction)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function () payable {}
+ }
+ )";
+
+ char const* interface = R"(
+ [
+ {
+ "constant" : false,
+ "payable": true,
"type" : "fallback"
}
]
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()
}
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 8d4890d1..ab0f9c7b 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -3852,7 +3852,113 @@ BOOST_AUTO_TEST_CASE(modifier_without_underscore)
modifier m() {}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::SyntaxError);
+ BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
+}
+
+BOOST_AUTO_TEST_CASE(payable_in_library)
+{
+ char const* text = R"(
+ library test {
+ function f() payable {}
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(payable_external)
+{
+ char const* text = R"(
+ contract test {
+ function f() payable external {}
+ }
+ )";
+ BOOST_CHECK(success(text));
+}
+
+BOOST_AUTO_TEST_CASE(payable_internal)
+{
+ char const* text = R"(
+ contract test {
+ function f() payable internal {}
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(payable_private)
+{
+ char const* text = R"(
+ contract test {
+ function f() payable private {}
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(illegal_override_payable)
+{
+ char const* text = R"(
+ contract B { function f() payable {} }
+ contract C is B { function f() {} }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable)
+{
+ char const* text = R"(
+ contract B { function f() {} }
+ contract C is B { function f() payable {} }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(payable_constant_conflict)
+{
+ char const* text = R"(
+ contract C { function f() payable constant {} }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(calling_payable)
+{
+ char const* text = R"(
+ contract receiver { function pay() payable {} }
+ contract test {
+ funciton f() { (new receiver()).pay.value(10)(); }
+ recevier r = new receiver();
+ function g() { r.pay.value(10)(); }
+ }
+ )";
+ BOOST_CHECK(success(text));
+}
+
+BOOST_AUTO_TEST_CASE(calling_nonpayable)
+{
+ char const* text = R"(
+ contract receiver { function nopay() {} }
+ contract test {
+ function f() { (new receiver()).nopay.value(10)(); }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(non_payable_constructor)
+{
+ char const* text = R"(
+ contract C {
+ function C() { }
+ }
+ contract D {
+ function f() returns (uint) {
+ (new C).value(2)();
+ return 2;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text) == Error::Type::TypeError);
}
BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index 0c0e343b..a81a9828 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -1231,6 +1231,16 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check)
BOOST_CHECK(!successParse(text));
}
+BOOST_AUTO_TEST_CASE(payable_accessor)
+{
+ char const* text = R"(
+ contract test {
+ uint payable x;
+ }
+ )";
+ BOOST_CHECK(!successParse(text));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}