Tests, Docs and Changelog

This commit is contained in:
hrkrshnn 2020-04-03 19:59:17 +05:30
parent 051eec5c51
commit bd0b06e8db
29 changed files with 51 additions and 110 deletions

View File

@ -2,6 +2,7 @@
Breaking changes: Breaking changes:
* Type Checker: Disallow virtual for library functions. * Type Checker: Disallow virtual for library functions.
* Deprecated dot syntax for `value` and `gas`.
Language Features: Language Features:

View File

@ -123,9 +123,9 @@ throws an exception or goes out of gas.
so your contract is not vulnerable to a reentrancy exploit. so your contract is not vulnerable to a reentrancy exploit.
.. note:: .. note::
Before Solidity 0.6.2, the recommended way to specify the value and gas Before Solidity 0.6.2, the recommended way to specify the value and gas was to
was to use ``f.value(x).gas(g)()``. This is still possible but deprecated use ``f.value(x).gas(g)()``. This was deprecated in Solidity 0.6.2 and is no
and will be removed with Solidity 0.7.0. longer possible since Solidity 0.7.0.
Named Calls and Anonymous Function Parameters Named Calls and Anonymous Function Parameters
--------------------------------------------- ---------------------------------------------

View File

@ -641,17 +641,18 @@ External (or public) functions have the following members:
* ``.address`` returns the address of the contract of the function. * ``.address`` returns the address of the contract of the function.
* ``.selector`` returns the :ref:`ABI function selector <abi_function_selector>` * ``.selector`` returns the :ref:`ABI function selector <abi_function_selector>`
* ``.gas(uint)`` returns a callable function object which, when called, will send
the specified amount of gas to the target function. Deprecated - use ``{gas: ...}`` instead. .. note::
See :ref:`External Function Calls <external-function-calls>` for more information. External (or public) functions used to have the additional members
* ``.value(uint)`` returns a callable function object which, when called, will ``.gas(uint)`` and ``.value(uint)``. These were deprecated in Solidity 0.6.2
send the specified amount of wei to the target function. Deprecated - use ``{value: ...}`` instead. and removed in Solidity 0.7.0. Instead use ``{gas: ...}`` and ``{value: ...}``
See :ref:`External Function Calls <external-function-calls>` for more information. to specify the amount of gas or the amount of wei sent to a function,
respectively. See :ref:`External Function Calls <external-function-calls>` for
more information.
Example that shows how to use the members:: Example that shows how to use the members::
pragma solidity >=0.6.0 <0.8.0; pragma solidity >=0.6.4 <0.8.0;
// This will report a warning
contract Example { contract Example {
function f() public payable returns (bytes4) { function f() public payable returns (bytes4) {
@ -660,9 +661,7 @@ Example that shows how to use the members::
} }
function g() public { function g() public {
this.f.gas(10).value(800)(); this.f{gas: 10, value: 800}();
// New syntax:
// this.f{gas: 10, value: 800}()
} }
} }

View File

@ -227,7 +227,7 @@ contract MultiSigWallet {
{ {
if (isConfirmed(transactionId)) { if (isConfirmed(transactionId)) {
Transaction storage tx = transactions[transactionId]; Transaction storage tx = transactions[transactionId];
(tx.executed,) = tx.destination.call.value(tx.value)(tx.data); (tx.executed,) = tx.destination.call{value: tx.value}(tx.data);
if (tx.executed) if (tx.executed)
emit Execution(transactionId); emit Execution(transactionId);
else else

View File

@ -48,7 +48,7 @@ contract MultiSigWalletWithDailyLimit is MultiSigWallet {
if (confirmed || tx.data.length == 0 && isUnderLimit(tx.value)) { if (confirmed || tx.data.length == 0 && isUnderLimit(tx.value)) {
if (!confirmed) if (!confirmed)
spentToday += tx.value; spentToday += tx.value;
(tx.executed,) = tx.destination.call.value(tx.value)(tx.data); (tx.executed,) = tx.destination.call{value: tx.value}(tx.data);
if (tx.executed) if (tx.executed)
emit Execution(transactionId); emit Execution(transactionId);
else { else {

View File

@ -360,7 +360,7 @@ contract MilestoneTracker {
// Recheck again to not pay twice // Recheck again to not pay twice
if (milestone.status == MilestoneStatus.AuthorizedForPayment) revert(); if (milestone.status == MilestoneStatus.AuthorizedForPayment) revert();
milestone.status = MilestoneStatus.AuthorizedForPayment; milestone.status = MilestoneStatus.AuthorizedForPayment;
(bool success,) = milestone.paymentSource.call.value(0)(milestone.payData); (bool success,) = milestone.paymentSource.call{value: 0}(milestone.payData);
require(success); require(success);
emit ProposalStatusChanged(_idMilestone, milestone.status); emit ProposalStatusChanged(_idMilestone, milestone.status);
} }

View File

@ -395,7 +395,7 @@ contract Wallet is multisig, multiowned, daylimit {
if (underLimit(_value)) { if (underLimit(_value)) {
emit SingleTransact(msg.sender, _value, _to, _data); emit SingleTransact(msg.sender, _value, _to, _data);
// yes - just execute the call. // yes - just execute the call.
_to.call.value(_value)(_data); _to.call{value: _value}(_data);
return 0; return 0;
} }
// determine our operation hash. // determine our operation hash.
@ -412,7 +412,7 @@ contract Wallet is multisig, multiowned, daylimit {
// to determine the body of the transaction from the hash provided. // to determine the body of the transaction from the hash provided.
function confirm(bytes32 _h) onlymanyowners(_h) public override returns (bool) { function confirm(bytes32 _h) onlymanyowners(_h) public override returns (bool) {
if (m_txs[_h].to != 0x0000000000000000000000000000000000000000) { if (m_txs[_h].to != 0x0000000000000000000000000000000000000000) {
m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data); m_txs[_h].to.call{value: m_txs[_h].value}(m_txs[_h].data);
emit MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data); emit MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);
delete m_txs[_h]; delete m_txs[_h];
return true; return true;

View File

@ -587,7 +587,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
// multiple times out of the DAO // multiple times out of the DAO
p.proposalPassed = true; p.proposalPassed = true;
(bool success,) = p.recipient.call.value(p.amount)(_transactionData); (bool success,) = p.recipient.call{value: p.amount}(_transactionData);
if (!success) if (!success)
revert(); revert();
@ -663,7 +663,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
uint fundsToBeMoved = uint fundsToBeMoved =
(balances[msg.sender] * p.splitData[0].splitBalance) / (balances[msg.sender] * p.splitData[0].splitBalance) /
p.splitData[0].totalSupply; p.splitData[0].totalSupply;
if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false) if (p.splitData[0].newDAO.createTokenProxy{value: fundsToBeMoved}(msg.sender) == false)
revert(); revert();
@ -697,7 +697,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
function newContract(address payable _newContract) public override { function newContract(address payable _newContract) public override {
if (msg.sender != address(this) || !allowedRecipients[_newContract]) return; if (msg.sender != address(this) || !allowedRecipients[_newContract]) return;
// move all ether // move all ether
(bool success,) = _newContract.call.value(address(this).balance)(""); (bool success,) = _newContract.call{value: address(this).balance}("");
if (!success) { if (!success) {
revert(); revert();
} }

View File

@ -57,7 +57,7 @@ contract ManagedAccount is ManagedAccountInterface{
function payOut(address payable _recipient, uint _amount) public override returns (bool) { function payOut(address payable _recipient, uint _amount) public override returns (bool) {
if (msg.sender != owner || (payOwnerOnly && _recipient != owner)) if (msg.sender != owner || (payOwnerOnly && _recipient != owner))
revert(); revert();
(bool success,) = _recipient.call.value(_amount)(""); (bool success,) = _recipient.call{value: _amount}("");
if (success) { if (success) {
emit PayOut(_recipient, _amount); emit PayOut(_recipient, _amount);
return true; return true;

View File

@ -106,7 +106,7 @@ override returns (bool success) {
&& (privateCreation == 0x0000000000000000000000000000000000000000 || privateCreation == msg.sender)) { && (privateCreation == 0x0000000000000000000000000000000000000000 || privateCreation == msg.sender)) {
uint token = (msg.value * 20) / divisor(); uint token = (msg.value * 20) / divisor();
address(extraBalance).call.value(msg.value - token)(""); address(extraBalance).call{value: msg.value - token}("");
balances[_tokenHolder] += token; balances[_tokenHolder] += token;
totalSupply += token; totalSupply += token;
weiGiven[_tokenHolder] += msg.value; weiGiven[_tokenHolder] += msg.value;
@ -127,7 +127,7 @@ override returns (bool success) {
extraBalance.payOut(address(this), extraBalance.accumulatedInput()); extraBalance.payOut(address(this), extraBalance.accumulatedInput());
// Execute refund // Execute refund
(bool success,) = msg.sender.call.value(weiGiven[msg.sender])(""); (bool success,) = msg.sender.call{value: weiGiven[msg.sender]}("");
if (success) { if (success) {
emit Refund(msg.sender, weiGiven[msg.sender]); emit Refund(msg.sender, weiGiven[msg.sender]);
totalSupply -= balances[msg.sender]; totalSupply -= balances[msg.sender];

View File

@ -2382,7 +2382,7 @@ BOOST_AUTO_TEST_CASE(generic_call)
function doSend(address rec) public returns (uint d) function doSend(address rec) public returns (uint d)
{ {
bytes4 signature = bytes4(bytes32(keccak256("recv(uint256)"))); bytes4 signature = bytes4(bytes32(keccak256("recv(uint256)")));
rec.call.value(2)(abi.encodeWithSelector(signature, 23)); rec.call{value: 2}(abi.encodeWithSelector(signature, 23));
return receiver(rec).received(); return receiver(rec).received();
} }
} }
@ -5210,7 +5210,7 @@ BOOST_AUTO_TEST_CASE(failed_create)
constructor() public payable {} constructor() public payable {}
function f(uint amount) public returns (D) { function f(uint amount) public returns (D) {
x++; x++;
return (new D).value(amount)(); return (new D){value: amount}();
} }
function stack(uint depth) public returns (address) { function stack(uint depth) public returns (address) {
if (depth < 1024) if (depth < 1024)
@ -5278,7 +5278,7 @@ BOOST_AUTO_TEST_CASE(mutex)
// NOTE: It is very bad practice to write this function this way. // NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly. // Please refer to the documentation of how to do this properly.
if (amount > shares) revert(); if (amount > shares) revert();
(bool success,) = msg.sender.call.value(amount)(""); (bool success,) = msg.sender.call{value: amount}("");
require(success); require(success);
shares -= amount; shares -= amount;
return shares; return shares;
@ -5287,7 +5287,7 @@ BOOST_AUTO_TEST_CASE(mutex)
// NOTE: It is very bad practice to write this function this way. // NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly. // Please refer to the documentation of how to do this properly.
if (amount > shares) revert(); if (amount > shares) revert();
(bool success,) = msg.sender.call.value(amount)(""); (bool success,) = msg.sender.call{value: amount}("");
require(success); require(success);
shares -= amount; shares -= amount;
return shares; return shares;

View File

@ -12,7 +12,7 @@ contract C {
} }
function g() public returns (uint256) { function g() public returns (uint256) {
d.g.gas(200)(); d.g{gas: 200}();
return 7; return 7;
} }

View File

@ -23,11 +23,11 @@ contract test {
} }
function sendAmount(uint256 amount) public payable returns (uint256 bal) { function sendAmount(uint256 amount) public payable returns (uint256 bal) {
return h.getBalance.value(amount)(); return h.getBalance{value: amount}();
} }
function outOfGas() public returns (bool ret) { function outOfGas() public returns (bool ret) {
h.setFlag.gas(2)(); // should fail due to OOG h.setFlag{gas: 2}(); // should fail due to OOG
return true; return true;
} }

View File

@ -21,7 +21,7 @@ contract Main {
Helper h; Helper h;
constructor() public payable { constructor() public payable {
h = (new Helper).value(10)("abc", true); h = (new Helper){value: 10}("abc", true);
} }
function getFlag() public returns (bool ret) { function getFlag() public returns (bool ret) {

View File

@ -14,7 +14,7 @@ contract test {
function sendAmount(uint256 amount) public payable returns (uint256 bal) { function sendAmount(uint256 amount) public payable returns (uint256 bal) {
uint256 someStackElement = 20; uint256 someStackElement = 20;
return h.getBalance.value(amount).gas(1000).value(amount + 3)(); return h.getBalance{value: amount + 3, gas: 1000}();
} }
} }

View File

@ -13,7 +13,7 @@ contract test {
} }
function sendAmount(uint256 amount) public returns (uint256 bal) { function sendAmount(uint256 amount) public returns (uint256 bal) {
return h.getBalance.value(amount).gas(1000).value(amount + 3)(); // overwrite value return h.getBalance{value: amount + 3, gas: 1000}();
} }
} }

View File

@ -2,13 +2,8 @@ pragma experimental SMTChecker;
contract C { contract C {
function f(function(uint) external payable g) internal { function f(function(uint) external payable g) internal {
g.selector; g.selector;
g.gas(2).value(3)(4);
g{gas: 2, value: 3}(4); g{gas: 2, value: 3}(4);
} }
} }
// ---- // ----
// Warning: (122-127): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// Warning: (122-136): Using ".value(...)" is deprecated. Use "{value: ...}" instead.
// Warning: (108-118): Assertion checker does not yet support this expression. // Warning: (108-118): Assertion checker does not yet support this expression.
// Warning: (122-130): Assertion checker does not yet implement this type of function call.
// Warning: (122-139): Assertion checker does not yet implement this type of function call.

View File

@ -4,7 +4,6 @@ contract C {
this.foo{value:2, gas: 5}{gas:2}; this.foo{value:2, gas: 5}{gas:2};
(this.foo{value:2, gas: 5}){gas:2}; (this.foo{value:2, gas: 5}){gas:2};
this.foo{value:2, gas: 5}{value:6}; this.foo{value:2, gas: 5}{value:6};
this.foo.value(4){value:2, gas: 5};
this.foo{gas:2, value: 5}{value:2, gas:5}; this.foo{gas:2, value: 5}{value:2, gas:5};
new D{salt:"abc"}{salt:"a"}(); new D{salt:"abc"}{salt:"a"}();
} }
@ -15,8 +14,6 @@ contract C {
// TypeError: (78-110): Option "gas" has already been set. // TypeError: (78-110): Option "gas" has already been set.
// TypeError: (120-154): Option "gas" has already been set. // TypeError: (120-154): Option "gas" has already been set.
// TypeError: (164-198): Option "value" has already been set. // TypeError: (164-198): Option "value" has already been set.
// Warning: (208-222): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // TypeError: (208-249): Option "value" has already been set.
// TypeError: (208-242): Option "value" has already been set. // TypeError: (208-249): Option "gas" has already been set.
// TypeError: (252-293): Option "value" has already been set. // TypeError: (259-286): Option "salt" has already been set.
// TypeError: (252-293): Option "gas" has already been set.
// TypeError: (303-330): Option "salt" has already been set.

View File

@ -1,8 +1,8 @@
contract C { contract C {
function (uint) external returns (uint) x; function (uint) external returns (uint) x;
function f() public { function f() public {
x.value(2)(1); x{value: 2}(1);
} }
} }
// ---- // ----
// TypeError: (94-101): Member "value" is only available for payable functions. // TypeError: (94-105): Cannot set option "value" on a non-payable function type.

View File

@ -5,4 +5,4 @@ contract C {
} }
} }
// ---- // ----
// Warning: (102-107): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead. // TypeError: (102-107): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.

View File

@ -8,4 +8,4 @@ contract D {
} }
} }
// ---- // ----
// Warning: (122-135): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // TypeError: (122-135): Using ".value(...)" is deprecated. Use "{value: ...}" instead.

View File

@ -5,4 +5,4 @@ contract C {
} }
} }
// ---- // ----
// Warning: (102-109): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // TypeError: (102-109): Using ".value(...)" is deprecated. Use "{value: ...}" instead.

View File

@ -1,10 +1,7 @@
contract test { contract test {
function f() public { function f() public {
address(0x12).call.value(2)("abc");
address(0x12).call{value: 2}("abc"); address(0x12).call{value: 2}("abc");
} }
} }
// ---- // ----
// Warning: (50-74): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // Warning: (50-85): Return value of low-level calls not used.
// Warning: (50-84): Return value of low-level calls not used.
// Warning: (94-129): Return value of low-level calls not used.

View File

@ -1,11 +1,7 @@
contract receiver { function pay() payable public {} } contract receiver { function pay() payable public {} }
contract test { contract test {
function f() public { (new receiver()).pay{value: 10}(); } function f() public { (new receiver()).pay{value: 10}(); }
function g() public { (new receiver()).pay.value(10)(); }
receiver r = new receiver(); receiver r = new receiver();
function h() public { r.pay{value: 10}(); } function h() public { r.pay{value: 10}(); }
function i() public { r.pay.value(10)(); }
} }
// ---- // ----
// Warning: (160-186): Using ".value(...)" is deprecated. Use "{value: ...}" instead.
// Warning: (303-314): Using ".value(...)" is deprecated. Use "{value: ...}" instead.

View File

@ -3,9 +3,9 @@ contract C {
} }
contract D { contract D {
function f() public returns (uint) { function f() public returns (uint) {
(new C).value(2)(); (new C){value: 2}();
return 2; return 2;
} }
} }
// ---- // ----
// TypeError: (106-119): Constructor for contract C must be payable for member "value" to be available. // TypeError: (106-123): Cannot set option "value", since the constructor of contract C is not payable.

View File

@ -1,26 +1,14 @@
contract C { contract C {
function f() external payable {} function f() external payable {}
function g(address a) external pure { function g(address a) external pure {
a.call.value(42);
a.call{value: 42}; a.call{value: 42};
a.call.gas(42);
a.call{gas: 42}; a.call{gas: 42};
a.staticcall.gas(42);
a.staticcall{gas: 42}; a.staticcall{gas: 42};
a.delegatecall.gas(42);
a.delegatecall{gas: 42}; a.delegatecall{gas: 42};
} }
function h() external view { function h() external view {
this.f.value(42);
this.f{value: 42}; this.f{value: 42};
this.f.gas(42);
this.f{gas: 42}; this.f{gas: 42};
} }
} }
// ---- // ----
// Warning: (91-103): Using ".value(...)" is deprecated. Use "{value: ...}" instead.
// Warning: (132-142): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// Warning: (169-185): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// Warning: (218-236): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// Warning: (304-316): Using ".value(...)" is deprecated. Use "{value: ...}" instead.
// Warning: (345-355): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.

View File

@ -1,27 +1,12 @@
contract C { contract C {
function f(address a) external view returns (bool success) { function f(address a) external view returns (bool success) {
(success,) = a.call.gas(42)("");
(success,) = a.call{gas: 42}("");
}
function g(address a) external view returns (bool success) {
(success,) = a.call.gas(42)("");
(success,) = a.call{gas: 42}(""); (success,) = a.call{gas: 42}("");
} }
function h() external payable {} function h() external payable {}
function i() external view { function i() external view {
this.h.gas(42)();
}
function j() external view {
this.h{gas: 42}(); this.h{gas: 42}();
} }
} }
// ---- // ----
// Warning: (90-100): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead. // TypeError: (90-109): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// Warning: (226-236): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead. // TypeError: (180-197): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// Warning: (351-361): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// TypeError: (90-108): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (125-144): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (226-244): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (261-280): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (351-367): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (404-421): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.

View File

@ -2,14 +2,10 @@ contract C {
function f() external view {} function f() external view {}
function test(address a) external view returns (bool status) { function test(address a) external view returns (bool status) {
// This used to incorrectly raise an error about violating the view mutability. // This used to incorrectly raise an error about violating the view mutability.
(status,) = a.staticcall.gas(42)("");
(status,) = a.staticcall{gas: 42}(""); (status,) = a.staticcall{gas: 42}("");
this.f.gas(42)();
this.f{gas: 42}(); this.f{gas: 42}();
} }
} }
// ==== // ====
// EVMVersion: >=byzantium // EVMVersion: >=byzantium
// ---- // ----
// Warning: (207-223): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.
// Warning: (276-286): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead.

View File

@ -1,25 +1,12 @@
contract C { contract C {
function f(address a) external view returns (bool success) { function f(address a) external view returns (bool success) {
(success,) = a.call.value(42)("");
(success,) = a.call{value: 42}("");
}
function g(address a) external view returns (bool success) {
(success,) = a.call.value(42)("");
(success,) = a.call{value: 42}(""); (success,) = a.call{value: 42}("");
} }
function h() external payable {} function h() external payable {}
function i() external view { function i() external view {
this.h.value(42)();
this.h{value: 42}(); this.h{value: 42}();
} }
} }
// ---- // ----
// Warning: (90-102): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // TypeError: (90-111): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// Warning: (230-242): Using ".value(...)" is deprecated. Use "{value: ...}" instead. // TypeError: (182-201): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// Warning: (359-371): Using ".value(...)" is deprecated. Use "{value: ...}" instead.
// TypeError: (90-110): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (127-148): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (230-250): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (267-288): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (359-377): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
// TypeError: (381-400): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.