Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/assembly.rst
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,10 @@ of Solidity, you can use a special comment to annotate an assembly block as memo
...
}

Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with
backward-compatibility with older compiler versions, prefer using the dialect string.
.. warning::
The ``memory-safe-assembly`` special comment is deprecated and scheduled for
removal in the next breaking version (0.9).
For new code targeting recent compilers, prefer specifying the dialect string.

Advanced Safe Use of Memory
---------------------------
Expand Down
12 changes: 8 additions & 4 deletions docs/common-patterns.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ you receive the funds of the person who is now the richest.
// Remember to zero the pending refund before
// sending to prevent reentrancy attacks
pendingWithdrawals[msg.sender] = 0;
payable(msg.sender).transfer(amount);
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success);
}
}

Expand All @@ -84,7 +85,8 @@ This is as opposed to the more intuitive sending pattern:
function becomeRichest() public payable {
if (msg.value <= mostSent) revert NotEnoughEther();
// This line can cause problems (explained below).
richest.transfer(msg.value);
(bool success, ) = richest.call{value: msg.value}("");
require(success);
richest = payable(msg.sender);
mostSent = msg.value;
}
Expand Down Expand Up @@ -210,8 +212,10 @@ restrictions highly readable.
revert NotEnoughEther();

_;
if (msg.value > amount)
payable(msg.sender).transfer(msg.value - amount);
if (msg.value > amount) {
(bool success, ) = payable(msg.sender).call{value: msg.value - amount}("");
require(success);
}
}

function forceOwnerChange(address newOwner)
Expand Down
5 changes: 5 additions & 0 deletions docs/contracts/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ will consume more gas than the 2300 gas stipend:
not recommended, since the fallback is invoked and would not fail for interface confusions
on the part of the sender).

.. warning::
Note that ``send`` and ``transfer`` are deprecated and scheduled for removal in the next breaking version (0.9).
You are encouraged to use the :ref:`call function <address_related>` with an optionally provided maximum
amount of gas (default forwards all remaining gas) and an empty calldata parameter, e.g., ``call{value: amount}("")``.

.. warning::
A contract without a receive Ether function can receive Ether as a
Expand Down Expand Up @@ -440,6 +444,7 @@ operations as long as there is enough gas passed on to it.

// If someone sends Ether to that contract,
// the transfer will fail, i.e. this returns false here.
// This will report a warning (deprecation)
return testPayable.send(2 ether);
}

Expand Down
9 changes: 7 additions & 2 deletions docs/contracts/inheritance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,8 @@ of the variable:

.. _modifier-overriding:

Modifier Overriding
===================
Modifier Overriding (deprecated)
================================

Function modifiers can override each other. This works in the same way as
:ref:`function overriding <function-overriding>` (except that there is no overloading for modifiers). The
Expand All @@ -392,6 +392,7 @@ and the ``override`` keyword must be used in the overriding modifier:

contract Base
{
// This will report a warning (deprecation)
modifier foo() virtual {_;}
}

Expand All @@ -411,11 +412,13 @@ explicitly:

contract Base1
{
// This will report a warning (deprecation)
modifier foo() virtual {_;}
}

contract Base2
{
// This will report a warning (deprecation)
modifier foo() virtual {_;}
}

Expand All @@ -424,6 +427,8 @@ explicitly:
modifier foo() override(Base1, Base2) {_;}
}

.. warning::
``virtual`` modifiers are deprecated and scheduled for removal in the next breaking version (0.9).


.. index:: ! constructor
Expand Down
15 changes: 9 additions & 6 deletions docs/control-structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -692,15 +692,17 @@ and ``assert`` for internal error checking.
:force:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
pragma solidity >=0.6.2 <0.9.0;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some examples need this because before 0.6.2 the language didn't support the Ether value parameter.


contract Sharer {
function sendHalf(address payable addr) public payable returns (uint balance) {
require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = address(this).balance;
addr.transfer(msg.value / 2);
// Since transfer throws an exception on failure and
// cannot call back here, there should be no way for us to
(bool success, ) = addr.call{value: msg.value / 2}("");
require(success);
// Since require will stop execution and
// revert if success is false,
// there should be no way for us to
// still have half of the Ether.
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
return address(this).balance;
Expand Down Expand Up @@ -775,7 +777,8 @@ together with ``revert`` and the equivalent ``require``:
if (msg.sender != owner)
revert Unauthorized();

payable(msg.sender).transfer(address(this).balance);
(bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
require(success);
}
}

Expand Down Expand Up @@ -914,4 +917,4 @@ in scope in the block that follows.
out-of-gas situation and not a deliberate error condition:
The caller always retains at least 1/64th of the gas in a call and thus
even if the called contract goes out of gas, the caller still
has some gas left.
has some gas left.
17 changes: 11 additions & 6 deletions docs/examples/blind-auction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ to receive their Ether - contracts cannot activate themselves.

// msg.sender is not of type `address payable` and must be
// explicitly converted using `payable(msg.sender)` in order
// use the member function `send()`.
if (!payable(msg.sender).send(amount)) {
// use the member function `call()`.
(bool success, ) = payable(msg.sender).call{value: amount}("");
if (!success) {
// No need to call throw here, just reset the amount owing
pendingReturns[msg.sender] = amount;
return false;
Expand Down Expand Up @@ -160,7 +161,8 @@ to receive their Ether - contracts cannot activate themselves.
emit AuctionEnded(highestBidder, highestBid);

// 3. Interaction
beneficiary.transfer(highestBid);
(bool success, ) = beneficiary.call{value: highestBid}("");
require(success);
}
}

Expand Down Expand Up @@ -310,7 +312,8 @@ invalid bids.
// the same deposit.
bidToCheck.blindedBid = bytes32(0);
}
payable(msg.sender).transfer(refund);
(bool success, ) = payable(msg.sender).call{value: refund}("");
require(success);
}

/// Withdraw a bid that was overbid.
Expand All @@ -323,7 +326,8 @@ invalid bids.
// conditions -> effects -> interaction).
pendingReturns[msg.sender] = 0;

payable(msg.sender).transfer(amount);
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success);
}
}

Expand All @@ -336,7 +340,8 @@ invalid bids.
if (ended) revert AuctionEndAlreadyCalled();
emit AuctionEnded(highestBidder, highestBid);
ended = true;
beneficiary.transfer(highestBid);
(bool success, ) = beneficiary.call{value: highestBid}("");
require(success);
}

// This is an "internal" function which means that it
Expand Down
15 changes: 10 additions & 5 deletions docs/examples/micropayment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ The full contract
// this recreates the message that was signed on the client
bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
require(recoverSigner(message, signature) == owner);
payable(msg.sender).transfer(amount);
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success);
}

/// freeze the contract and reclaim the leftover funds.
Expand All @@ -195,7 +196,8 @@ The full contract
{
require(msg.sender == owner);
freeze();
payable(msg.sender).transfer(address(this).balance);
(bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
require(success);
}

/// signature methods.
Expand Down Expand Up @@ -406,9 +408,11 @@ The full contract
require(msg.sender == recipient);
require(isValidSignature(amount, signature));

recipient.transfer(amount);
(bool success, ) = recipient.call{value: amount}("");
require(success);
freeze();
sender.transfer(address(this).balance);
(success, ) = sender.call{value: address(this).balance}("");
require(success);
}

/// the sender can extend the expiration at any time
Expand All @@ -430,7 +434,8 @@ The full contract
{
require(block.timestamp >= expiration);
freeze();
sender.transfer(address(this).balance);
(bool success, ) = sender.call{value: address(this).balance}("");
require(success);
}

function isValidSignature(uint256 amount, bytes memory signature)
Expand Down
9 changes: 6 additions & 3 deletions docs/examples/safe-remote.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ you can use state machine-like constructs inside a contract.
// reentrancy-safe, because it is the
// last call in this function and we
// already changed the state.
seller.transfer(address(this).balance);
(bool success, ) = seller.call{value: address(this).balance}("");
require(success);
}

/// Confirm the purchase as buyer.
Expand Down Expand Up @@ -128,7 +129,8 @@ you can use state machine-like constructs inside a contract.
// can call in again here.
state = State.Release;

buyer.transfer(value);
(bool success, ) = buyer.call{value: value}("");
require(success);
}

/// This function refunds the seller, i.e.
Expand All @@ -144,6 +146,7 @@ you can use state machine-like constructs inside a contract.
// can call in again here.
state = State.Inactive;

seller.transfer(3 * value);
(bool success, ) = seller.call{value: 3 * value}("");
require(success);
}
}
7 changes: 5 additions & 2 deletions docs/layout-of-source-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,13 @@ select between the two implementations of the ABI encoder and decoder.
The new ABI coder (v2) is able to encode and decode arbitrarily nested
arrays and structs. Apart from supporting more types, it involves more extensive
validation and safety checks, which may result in higher gas costs, but also heightened
security. It is considered
non-experimental as of Solidity 0.6.0 and it is enabled by default starting
security.
It is considered non-experimental as of Solidity 0.6.0 and it is enabled by default starting
with Solidity 0.8.0. The old ABI coder can still be selected using ``pragma abicoder v1;``.

.. warning::
The ABI coder v1 is deprecated and scheduled for removal in the next breaking version (0.9).

The set of types supported by the new encoder is a strict superset of
the ones supported by the old one. Contracts that use it can interact with ones
that do not without limitations. The reverse is possible only as long as the
Expand Down
7 changes: 5 additions & 2 deletions docs/security-considerations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ To give an example, the following code contains a bug (it is just a snippet and
mapping(address => uint) shares;
/// Withdraw your share.
function withdraw() public {
// This will report a warning (deprecation)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left some of these comments because the text mentions send/transfer in the description or explanation of the examples. This should be rewritten to avoid that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to leave it as-is with your warnings but we should complete the section with reentrancy when using call. or is it there and i just didn't see it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I changed the final example replacing transfer with call.
Not sure if you were referring to something more that needs adjustment in this section.

if (payable(msg.sender).send(shares[msg.sender]))
shares[msg.sender] = 0;
}
Expand Down Expand Up @@ -100,7 +101,7 @@ To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demo
.. code-block:: solidity

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
pragma solidity >=0.6.2 <0.9.0;

contract Fund {
/// @dev Mapping of ether shares of the contract.
Expand All @@ -109,7 +110,8 @@ To avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demo
function withdraw() public {
uint share = shares[msg.sender];
shares[msg.sender] = 0;
payable(msg.sender).transfer(share);
(bool success, ) = payable(msg.sender).call{value: share}("");
require(success);
}
}

Expand Down Expand Up @@ -255,6 +257,7 @@ Let's say you have a wallet contract like this:
function transferTo(address payable dest, uint amount) public {
// THE BUG IS RIGHT HERE, you must use msg.sender instead of tx.origin
require(tx.origin == owner);
// This will report a warning (deprecation)
dest.transfer(amount);
}
}
Expand Down
6 changes: 3 additions & 3 deletions docs/types/reference-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ shown in the following example:
.. code-block:: solidity

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
pragma solidity >=0.6.2 <0.9.0;

// Defines a new type with two fields.
// Declaring a struct outside of a contract allows
Expand Down Expand Up @@ -729,8 +729,8 @@ shown in the following example:
return false;
uint amount = c.amount;
c.amount = 0;
c.beneficiary.transfer(amount);
return true;
(bool success, ) = c.beneficiary.call{value: amount}("");
return success;
}
}

Expand Down
12 changes: 12 additions & 0 deletions docs/types/value-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ reverts on failure.
.. note::
If ``x`` is a contract address, its code (more specifically: its :ref:`receive-ether-function`, if present, or otherwise its :ref:`fallback-function`, if present) will be executed together with the ``transfer`` call (this is a feature of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted and the current contract will stop with an exception.

.. warning::
``transfer`` is deprecated and scheduled for removal in the next breaking version (0.9).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't hurt to repeat the bit about using call instead here and/or link to it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

You are encouraged to use the :ref:`call function <address_call_functions>` with an optionally provided maximum
amount of gas (default forwards all remaining gas) and an empty calldata parameter, e.g., ``call{value: amount}("")``.

* ``send``

``send`` is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``.
Expand All @@ -271,6 +276,13 @@ reverts on failure.
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
use a pattern where the recipient withdraws the Ether.

.. warning::
``send`` is deprecated and scheduled for removal in the next breaking version (0.9).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't hurt to repeat the bit about using call instead here and/or link to it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

You are encouraged to use the :ref:`call function <address_call_functions>` with an optionally provided maximum
amount of gas (default forwards all remaining gas) and an empty calldata parameter, e.g., ``call{value: amount}("")``.

.. _address_call_functions:

* ``call``, ``delegatecall`` and ``staticcall``

In order to interface with contracts that do not adhere to the ABI,
Expand Down
5 changes: 5 additions & 0 deletions libsolidity/analysis/DocStringTagParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ bool DocStringTagParser::visit(InlineAssembly const& _assembly)
"otherwise only use the NatSpec tag."
);
_assembly.annotation().markedMemorySafe = true;
m_errorReporter.warning(
2424_error,
_assembly.location(),
"Natspec memory safe annotation for inline assembly is deprecated and scheduled for removal in the next breaking version (0.9)."
);
}
else
m_errorReporter.warning(
Expand Down
Loading