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
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ Language Features:

Compiler Features:
* ethdebug: Experimental support for instructions and source locations under EOF.
* DocString Parser: Deprecation of inline assembly special comment `memory-safe-assembly`.
* Syntax Checker: Deprecation of ABI coder v1.
* Syntax Checker: Deprecation of `virtual` modifiers.
* Type Checker: Deprecation of `send` and `transfer` functions on instances of `address`.
* Type Checker: Deprecation of comparisons between `contract`-typed variables.

Bugfixes:
* Assembler: Fix not using a fixed-width type for IDs being assigned to subassemblies nested more than one level away, resulting in inconsistent `--asm-json` output between target architectures.
Expand Down
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 assembly block annotation.

Advanced Safe Use of Memory
---------------------------
Expand Down
5 changes: 5 additions & 0 deletions docs/cheatsheet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ Members of ``address``
returns ``false`` on failure
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure

.. warning::
``transfer`` and ``send`` are deprecated and scheduled for removal in the next breaking version (0.9).
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}("")``.

.. index:: blockhash, blobhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin

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
7 changes: 6 additions & 1 deletion docs/contracts/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ will consume more gas than the 2300 gas stipend:
- Calling an external function which consumes a large amount of gas
- Sending Ether

.. 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::
When Ether is sent directly to a contract (without a function call, i.e. sender uses ``send`` or ``transfer``)
but the receiving contract does not define a receive Ether function or a payable fallback function,
Expand All @@ -319,7 +324,6 @@ 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::
A contract without a receive Ether function can receive Ether as a
recipient of a *coinbase transaction* (aka *miner block reward*)
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;

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)
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
Loading