Merge pull request #10496 from ethereum/address-payable

[BREAKING] tx.origin, msg.sender and address(literal) are non-payable addresses
This commit is contained in:
chriseth 2020-12-14 20:16:52 +01:00 committed by GitHub
commit 271a17d908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 298 additions and 132 deletions

View File

@ -27,6 +27,8 @@ Breaking Changes:
* Type System: Support ``address(...).codehash`` to retrieve the codehash of an account. * Type System: Support ``address(...).codehash`` to retrieve the codehash of an account.
* Type System: Unary negation can only be used on signed integers, not on unsigned integers. * Type System: Unary negation can only be used on signed integers, not on unsigned integers.
* View Pure Checker: Mark ``chainid`` as view. * View Pure Checker: Mark ``chainid`` as view.
* Type System: Explicit conversion to ``address`` type always returns a non-payable ``address`` type. In particular, ``address(u)``, ``address(b)``, ``address(c)`` and ``address(this)`` have the type ``address`` instead of ``address payable`` (Here ``u``, ``b``, and ``c`` are arbitrary variables of type ``uint160``, ``bytes20`` and contract type respectively.)
* Type System: The global variables ``tx.origin`` and ``msg.sender`` have type ``address`` instead of ``address payable``.
* Yul: Disallow the use of reserved identifiers, such as EVM instructions, even if they are not available in the given dialect / EVM version. * Yul: Disallow the use of reserved identifiers, such as EVM instructions, even if they are not available in the given dialect / EVM version.
Language Features: Language Features:

View File

@ -65,6 +65,13 @@ This section lists changes that might cause existing contracts to not compile an
with ``type(uint).max``. with ``type(uint).max``.
3. Explicit conversions between literals and enums are only allowed if the literal can 3. Explicit conversions between literals and enums are only allowed if the literal can
represent a value in the enum. represent a value in the enum.
4. Explicit conversions between literals and ``address`` type (e.g. ``address(literal)``) have the
type ``address`` instead of ``address payable``. One can get a payable address type by using an
explicit conversion, i.e., ``payable(literal)``.
* :ref:`Address literals<address_literals>` have the type ``address`` instead of ``address
payable``. They can be converted to ``address payable`` by using an explicit conversion, e.g.
``payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF)``.
* There are new restrictions on explicit type conversions. The conversion is only allowed when there * There are new restrictions on explicit type conversions. The conversion is only allowed when there
is at most one change in sign, width or type-category (``int``, ``address``, ``bytesNN``, etc.). is at most one change in sign, width or type-category (``int``, ``address``, ``bytesNN``, etc.).
@ -105,6 +112,28 @@ This section lists changes that might cause existing contracts to not compile an
* Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences in code. * Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences in code.
They can still be inserted via hexadecimal escapes, e.g. ``\x08``, ``\x0c``, and ``\x0b``, respectively. They can still be inserted via hexadecimal escapes, e.g. ``\x08``, ``\x0c``, and ``\x0b``, respectively.
* The global variables ``tx.origin`` and ``msg.sender`` have the type ``address`` instead of
``address payable``. One can convert them into ``address payable`` by using an explicit
conversion, i.e., ``payable(tx.origin)`` or ``payable(msg.sender)``.
This change was done since the compiler cannot determine whether or not these addresses
are payable or not, so it now requires an explicit conversion to make this requirement visible.
* Explicit conversion into ``address`` type always returns a non-payable ``address`` type. In
particular, the following explicit conversions have the type ``address`` instead of ``address
payable``:
- ``address(u)`` where ``u`` is an arbitrary variable of type ``uint160``. One can convert ``u``
into the type ``address payable`` by using an explicit conversion, i.e., ``payable(u)``.
- ``address(b)`` where ``b`` is an arbitrary variable of type ``bytes20``. One can convert ``b``
into the type ``address payable`` by using an explicit conversion, i.e., ``payable(bytes20)``.
- ``address(c)`` where ``c`` is an arbitrary contract. Previously, the return type of this
conversion depended on whether the contract can receive Ether (either by having a receive
function or a payable fallback function). The conversion ``payable(c)`` has the type ``address
payable`` and is only allowed when the contract ``c`` can receive Ether. In general, one can
always convert ``c`` into the type ``address payable`` by using the following explicit
conversion: ``payable(address(c))``. Note that ``address(this)`` falls under the same category
as ``address(c)`` and the same rules apply for it.
* The ``chainid`` builtin in inline assembly is now considered ``view`` instead of ``pure``. * The ``chainid`` builtin in inline assembly is now considered ``view`` instead of ``pure``.

View File

@ -90,10 +90,10 @@ Global Variables
- ``block.timestamp`` (``uint``): current block timestamp - ``block.timestamp`` (``uint``): current block timestamp
- ``gasleft() returns (uint256)``: remaining gas - ``gasleft() returns (uint256)``: remaining gas
- ``msg.data`` (``bytes``): complete calldata - ``msg.data`` (``bytes``): complete calldata
- ``msg.sender`` (``address payable``): sender of the message (current call) - ``msg.sender`` (``address``): sender of the message (current call)
- ``msg.value`` (``uint``): number of wei sent with the message - ``msg.value`` (``uint``): number of wei sent with the message
- ``tx.gasprice`` (``uint``): gas price of the transaction - ``tx.gasprice`` (``uint``): gas price of the transaction
- ``tx.origin`` (``address payable``): sender of the transaction (full call chain) - ``tx.origin`` (``address``): sender of the transaction (full call chain)
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error) - ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use - ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use
for malformed input or error in external component) for malformed input or error in external component)

View File

@ -53,7 +53,7 @@ you receive the funds of the person who is now the richest.
// Remember to zero the pending refund before // Remember to zero the pending refund before
// sending to prevent re-entrancy attacks // sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0; pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount); payable(msg.sender).transfer(amount);
} }
} }
@ -69,7 +69,7 @@ This is as opposed to the more intuitive sending pattern:
uint public mostSent; uint public mostSent;
constructor() payable { constructor() payable {
richest = msg.sender; richest = payable(msg.sender);
mostSent = msg.value; mostSent = msg.value;
} }
@ -77,7 +77,7 @@ This is as opposed to the more intuitive sending pattern:
require(msg.value > mostSent, "Not enough money sent."); require(msg.value > mostSent, "Not enough money sent.");
// This line can cause problems (explained below). // This line can cause problems (explained below).
richest.transfer(msg.value); richest.transfer(msg.value);
richest = msg.sender; richest = payable(msg.sender);
mostSent = msg.value; mostSent = msg.value;
} }
} }
@ -124,7 +124,7 @@ restrictions highly readable.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0; pragma solidity >=0.6.0 <0.9.0;
contract AccessRestriction { contract AccessRestriction {
// These will be assigned at the construction // These will be assigned at the construction
@ -192,7 +192,7 @@ restrictions highly readable.
); );
_; _;
if (msg.value > _amount) if (msg.value > _amount)
msg.sender.transfer(msg.value - _amount); payable(msg.sender).transfer(msg.value - _amount);
} }
function forceOwnerChange(address _newOwner) function forceOwnerChange(address _newOwner)

View File

@ -21,7 +21,7 @@ if they are marked ``virtual``. For details, please see
pragma solidity >0.7.0 <0.9.0; pragma solidity >0.7.0 <0.9.0;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() { owner = payable(msg.sender); }
address payable owner; address payable owner;
// This contract only defines a modifier but does not use // This contract only defines a modifier but does not use

View File

@ -438,7 +438,7 @@ operations as long as there is enough gas passed on to it.
// results in test.x becoming == 1 and test.y becoming 1. // results in test.x becoming == 1 and test.y becoming 1.
// If someone sends Ether to that contract, the receive function in TestPayable will be called. // If someone sends Ether to that contract, the receive function in TestPayable will be called.
require(address(test).send(2 ether)); require(payable(test).send(2 ether));
// results in test.x becoming == 2 and test.y becoming 2 ether. // results in test.x becoming == 2 and test.y becoming 2 ether.
return true; return true;

View File

@ -43,7 +43,7 @@ Details are given in the following example.
contract Owned { contract Owned {
constructor() { owner = msg.sender; } constructor() { owner = payable(msg.sender); }
address payable owner; address payable owner;
} }
@ -130,7 +130,7 @@ seen in the following example::
pragma solidity >=0.7.0 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() { owner = payable(msg.sender); }
address payable owner; address payable owner;
} }
@ -160,7 +160,7 @@ explicitly in the final override, but this function will bypass
pragma solidity >=0.7.0 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() { owner = payable(msg.sender); }
address payable owner; address payable owner;
} }

View File

@ -114,7 +114,7 @@ to receive their money - contracts cannot activate themselves.
// before `send` returns. // before `send` returns.
pendingReturns[msg.sender] = 0; pendingReturns[msg.sender] = 0;
if (!msg.sender.send(amount)) { if (!payable(msg.sender).send(amount)) {
// No need to call throw here, just reset the amount owing // No need to call throw here, just reset the amount owing
pendingReturns[msg.sender] = amount; pendingReturns[msg.sender] = amount;
return false; return false;
@ -280,7 +280,7 @@ invalid bids.
// the same deposit. // the same deposit.
bidToCheck.blindedBid = bytes32(0); bidToCheck.blindedBid = bytes32(0);
} }
msg.sender.transfer(refund); payable(msg.sender).transfer(refund);
} }
/// Withdraw a bid that was overbid. /// Withdraw a bid that was overbid.
@ -293,7 +293,7 @@ invalid bids.
// conditions -> effects -> interaction). // conditions -> effects -> interaction).
pendingReturns[msg.sender] = 0; pendingReturns[msg.sender] = 0;
msg.sender.transfer(amount); payable(msg.sender).transfer(amount);
} }
} }

View File

@ -159,13 +159,13 @@ The full contract
require(recoverSigner(message, signature) == owner); require(recoverSigner(message, signature) == owner);
msg.sender.transfer(amount); payable(msg.sender).transfer(amount);
} }
/// destroy the contract and reclaim the leftover funds. /// destroy the contract and reclaim the leftover funds.
function shutdown() public { function shutdown() public {
require(msg.sender == owner); require(msg.sender == owner);
selfdestruct(msg.sender); selfdestruct(payable(msg.sender));
} }
/// signature methods. /// signature methods.
@ -347,7 +347,7 @@ The full contract
constructor (address payable _recipient, uint256 duration) constructor (address payable _recipient, uint256 duration)
payable payable
{ {
sender = msg.sender; sender = payable(msg.sender);
recipient = _recipient; recipient = _recipient;
expiration = block.timestamp + duration; expiration = block.timestamp + duration;
} }

View File

@ -74,7 +74,7 @@ you can use state machine-like constructs inside a contract.
// Division will truncate if it is an odd number. // Division will truncate if it is an odd number.
// Check via multiplication that it wasn't an odd number. // Check via multiplication that it wasn't an odd number.
constructor() payable { constructor() payable {
seller = msg.sender; seller = payable(msg.sender);
value = msg.value / 2; value = msg.value / 2;
require((2 * value) == msg.value, "Value has to be even."); require((2 * value) == msg.value, "Value has to be even.");
} }
@ -107,7 +107,7 @@ you can use state machine-like constructs inside a contract.
payable payable
{ {
emit PurchaseConfirmed(); emit PurchaseConfirmed();
buyer = msg.sender; buyer = payable(msg.sender);
state = State.Locked; state = State.Locked;
} }

View File

@ -59,7 +59,7 @@ complete contract):
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0; pragma solidity >=0.6.0 <0.9.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE // THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund { contract Fund {
@ -67,7 +67,7 @@ complete contract):
mapping(address => uint) shares; mapping(address => uint) shares;
/// Withdraw your share. /// Withdraw your share.
function withdraw() public { function withdraw() public {
if (msg.sender.send(shares[msg.sender])) if (payable(msg.sender).send(shares[msg.sender]))
shares[msg.sender] = 0; shares[msg.sender] = 0;
} }
} }
@ -103,7 +103,7 @@ outlined further below:
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.11 <0.9.0; pragma solidity >=0.6.0 <0.9.0;
contract Fund { contract Fund {
/// @dev Mapping of ether shares of the contract. /// @dev Mapping of ether shares of the contract.
@ -112,7 +112,7 @@ outlined further below:
function withdraw() public { function withdraw() public {
uint share = shares[msg.sender]; uint share = shares[msg.sender];
shares[msg.sender] = 0; shares[msg.sender] = 0;
msg.sender.transfer(share); payable(msg.sender).transfer(share);
} }
} }
@ -230,7 +230,7 @@ Now someone tricks you into sending Ether to the address of this attack wallet:
address payable owner; address payable owner;
constructor() { constructor() {
owner = msg.sender; owner = payable(msg.sender);
} }
receive() external payable { receive() external payable {

View File

@ -188,25 +188,22 @@ Type conversions:
Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable``
must be explicit via ``payable(<address>)``. must be explicit via ``payable(<address>)``.
:ref:`Address literals<address_literals>` can be implicitly converted to ``address payable``.
Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following
caveat: caveat:
The result of a conversion of the form ``address(x)`` The result of a conversion of the form ``address(x)``
has the type ``address payable``, if ``x`` is of integer or fixed bytes type, has the type ``address payable``, if ``x`` is of integer or fixed bytes type,
a literal or a contract with a receive or payable fallback function. or a contract with a receive or payable fallback function.
If ``x`` is a contract without a receive or payable fallback function, If ``x`` is a contract without a receive or payable fallback function,
then ``address(x)`` will be of type ``address``. then ``address(x)`` will be of type ``address``.
Similarly, if ``x`` is a literal, then ``address(x)`` will also be of type ``address``.
In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type. In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type.
Only expressions of type ``address`` can be converted to type ``address payable`` via ``payable(<address>)``. Only expressions of type ``address`` can be converted to type ``address payable`` via ``payable(<address>)``.
.. note:: .. note::
It might very well be that you do not need to care about the distinction between ``address`` If you need a variable of type ``address`` and plan to send Ether to it, then
and ``address payable`` and just use ``address`` everywhere. For example, declare its type as ``address payable`` to make this requirement visible. Also,
if you are using the :ref:`withdrawal pattern<withdrawal_pattern>`, you can (and should) store the try to make this distinction or conversion as early as possible.
address itself as ``address``, because you invoke the ``transfer`` function on
``msg.sender``, which is an ``address payable``.
Operators: Operators:
@ -410,7 +407,7 @@ Address Literals
---------------- ----------------
Hexadecimal literals that pass the address checksum test, for example Hexadecimal literals that pass the address checksum test, for example
``0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`` are of ``address payable`` type. ``0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`` are of ``address`` type.
Hexadecimal literals that are between 39 and 41 digits Hexadecimal literals that are between 39 and 41 digits
long and do not pass the checksum test produce long and do not pass the checksum test produce
an error. You can prepend (for integer types) or append (for bytesNN types) zeros to remove the error. an error. You can prepend (for integer types) or append (for bytesNN types) zeros to remove the error.

View File

@ -1764,14 +1764,6 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
result.message() result.message()
); );
} }
if (auto addressType = dynamic_cast<AddressType const*>(resultType))
if (addressType->stateMutability() != StateMutability::Payable)
{
bool payable = false;
if (argType->category() != Type::Category::Address)
payable = argType->isExplicitlyConvertibleTo(*TypeProvider::payableAddress());
resultType = payable ? TypeProvider::payableAddress() : TypeProvider::address();
}
} }
return resultType; return resultType;
} }
@ -3314,7 +3306,7 @@ void TypeChecker::endVisit(Literal const& _literal)
if (_literal.looksLikeAddress()) if (_literal.looksLikeAddress())
{ {
// Assign type here if it even looks like an address. This prevents double errors for invalid addresses // Assign type here if it even looks like an address. This prevents double errors for invalid addresses
_literal.annotation().type = TypeProvider::payableAddress(); _literal.annotation().type = TypeProvider::address();
string msg; string msg;
if (_literal.valueWithoutUnderscores().length() != 42) // "0x" + 40 hex digits if (_literal.valueWithoutUnderscores().length() != 42) // "0x" + 40 hex digits

View File

@ -3838,7 +3838,7 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
}); });
case Kind::Message: case Kind::Message:
return MemberList::MemberMap({ return MemberList::MemberMap({
{"sender", TypeProvider::payableAddress()}, {"sender", TypeProvider::address()},
{"gas", TypeProvider::uint256()}, {"gas", TypeProvider::uint256()},
{"value", TypeProvider::uint256()}, {"value", TypeProvider::uint256()},
{"data", TypeProvider::array(DataLocation::CallData)}, {"data", TypeProvider::array(DataLocation::CallData)},
@ -3846,7 +3846,7 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
}); });
case Kind::Transaction: case Kind::Transaction:
return MemberList::MemberMap({ return MemberList::MemberMap({
{"origin", TypeProvider::payableAddress()}, {"origin", TypeProvider::address()},
{"gasprice", TypeProvider::uint256()} {"gasprice", TypeProvider::uint256()}
}); });
case Kind::ABI: case Kind::ABI:

View File

@ -65,7 +65,7 @@ contract ico is safeMath {
icoExchangeRate = exchangeRate; icoExchangeRate = exchangeRate;
icoExchangeRateSetBlock = block.number + exchangeRateDelay; icoExchangeRateSetBlock = block.number + exchangeRateDelay;
icoEtcPriceAddr = priceSet; icoEtcPriceAddr = priceSet;
owner = msg.sender; owner = payable(msg.sender);
if ( startBlockNum > 0 ) { if ( startBlockNum > 0 ) {
require( startBlockNum >= block.number ); require( startBlockNum >= block.number );
startBlock = startBlockNum; startBlock = startBlockNum;
@ -272,7 +272,7 @@ contract ico is safeMath {
require( brought[msg.sender].eth > 0 ); require( brought[msg.sender].eth > 0 );
uint256 _val = brought[msg.sender].eth * 90 / 100; uint256 _val = brought[msg.sender].eth * 90 / 100;
delete brought[msg.sender]; delete brought[msg.sender];
require( msg.sender.send(_val) ); require( payable(msg.sender).send(_val) );
} }
receive () external payable { receive () external payable {
@ -281,7 +281,7 @@ contract ico is safeMath {
If they call the contract without any function then this process will be taken place. If they call the contract without any function then this process will be taken place.
*/ */
require( isICO() ); require( isICO() );
require( buy(msg.sender, address(0x00)) ); require( buy(payable(msg.sender), address(0x00)) );
} }
function buy(address payable beneficiaryAddress, address affilateAddress) public payable returns (bool success) { function buy(address payable beneficiaryAddress, address affilateAddress) public payable returns (bool success) {
@ -300,7 +300,7 @@ contract ico is safeMath {
@affilateAddress The address of the person who offered who will get the referral reward. It can not be equal with the beneficiaryAddress. @affilateAddress The address of the person who offered who will get the referral reward. It can not be equal with the beneficiaryAddress.
*/ */
require( isICO() ); require( isICO() );
if ( beneficiaryAddress == address(0x00)) { beneficiaryAddress = msg.sender; } if ( beneficiaryAddress == address(0x00)) { beneficiaryAddress = payable(msg.sender); }
if ( beneficiaryAddress == affilateAddress ) { if ( beneficiaryAddress == affilateAddress ) {
affilateAddress = address(0x00); affilateAddress = address(0x00);
} }

View File

@ -90,10 +90,10 @@ contract module {
@newModuleAddress New module handler address @newModuleAddress New module handler address
*/ */
require( moduleStatus != status.New && moduleStatus != status.Disconnected); require( moduleStatus != status.New && moduleStatus != status.Disconnected);
(bool _success, uint256 _balance) = abstractModuleHandler(moduleHandlerAddress).balanceOf(address(this)); (bool _success, uint256 _balance) = abstractModuleHandler(moduleHandlerAddress).balanceOf(payable(this));
require( _success ); require( _success );
if ( _balance > 0 ) { if ( _balance > 0 ) {
require( abstractModuleHandler(moduleHandlerAddress).transfer(address(this), newModuleAddress, _balance, false) ); require( abstractModuleHandler(moduleHandlerAddress).transfer(payable(this), newModuleAddress, _balance, false) );
} }
if ( address(this).balance > 0 ) { if ( address(this).balance > 0 ) {
require( newModuleAddress.send(address(this).balance) ); require( newModuleAddress.send(address(this).balance) );

View File

@ -19,7 +19,7 @@ contract ptokenDB is tokenDB {}
*/ */
contract premium is module, safeMath { contract premium is module, safeMath {
function replaceModule(address payable addr) external override returns (bool success) { function replaceModule(address payable addr) external override returns (bool success) {
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
require( db.replaceOwner(addr) ); require( db.replaceOwner(addr) );
super._replaceModule(addr); super._replaceModule(addr);
return true; return true;

View File

@ -10,7 +10,7 @@ contract provider is module, safeMath, announcementTypes {
module callbacks module callbacks
*/ */
function connectModule() external override returns (bool success) { function connectModule() external override returns (bool success) {
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
super._connectModule(); super._connectModule();
(bool _success, uint256 currentSchellingRound) = moduleHandler(moduleHandlerAddress).getCurrentSchellingRoundID(); (bool _success, uint256 currentSchellingRound) = moduleHandler(moduleHandlerAddress).getCurrentSchellingRoundID();
require( _success ); require( _success );
@ -26,7 +26,7 @@ contract provider is module, safeMath, announcementTypes {
@value amount @value amount
@bool Was the function successful? @bool Was the function successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
transferEvent_(from, value, true); transferEvent_(from, value, true);
transferEvent_(to, value, false); transferEvent_(to, value, false);
return true; return true;
@ -41,7 +41,7 @@ contract provider is module, safeMath, announcementTypes {
@reward token emission @reward token emission
@bool Was the function successful? @bool Was the function successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
globalFunds[roundID].reward = reward; globalFunds[roundID].reward = reward;
globalFunds[roundID].supply = globalFunds[roundID-1].supply; globalFunds[roundID].supply = globalFunds[roundID-1].supply;
currentSchellingRound = roundID; currentSchellingRound = roundID;
@ -133,7 +133,7 @@ contract provider is module, safeMath, announcementTypes {
@a Type of the setting @a Type of the setting
@b value @b value
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
if ( a == announcementType.providerPublicFunds ) { minFundsForPublic = b; } if ( a == announcementType.providerPublicFunds ) { minFundsForPublic = b; }
else if ( a == announcementType.providerPrivateFunds ) { minFundsForPrivate = b; } else if ( a == announcementType.providerPrivateFunds ) { minFundsForPrivate = b; }
else if ( a == announcementType.providerPrivateClientLimit ) { privateProviderLimit = b; } else if ( a == announcementType.providerPrivateClientLimit ) { privateProviderLimit = b; }

View File

@ -14,7 +14,7 @@ contract publisher is announcementTypes, module, safeMath {
Transaction completed. This function is available only for moduleHandler Transaction completed. This function is available only for moduleHandler
If a transaction is carried out from or to an address which participated in the objection of an announcement, its objection purport is automatically set If a transaction is carried out from or to an address which participated in the objection of an announcement, its objection purport is automatically set
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
uint256 announcementID; uint256 announcementID;
uint256 a; uint256 a;
// need reverse lookup // need reverse lookup

View File

@ -136,7 +136,7 @@ contract schelling is module, announcementTypes, schellingVars {
module callbacks module callbacks
*/ */
function replaceModule(address payable addr) external override returns (bool) { function replaceModule(address payable addr) external override returns (bool) {
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
require( db.replaceOwner(addr) ); require( db.replaceOwner(addr) );
super._replaceModule(addr); super._replaceModule(addr);
return true; return true;
@ -151,7 +151,7 @@ contract schelling is module, announcementTypes, schellingVars {
@value Amount @value Amount
@bool Was the transaction successful? @bool Was the transaction successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
if ( to == address(this) ) { if ( to == address(this) ) {
uint256 currentRound = getCurrentRound(); uint256 currentRound = getCurrentRound();
schellingVars._rounds memory round = getRound(currentRound); schellingVars._rounds memory round = getRound(currentRound);
@ -271,7 +271,7 @@ contract schelling is module, announcementTypes, schellingVars {
@a Sort of configuration @a Sort of configuration
@b Value @b Value
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
if ( a == announcementType.schellingRoundBlockDelay ) { roundBlockDelay = b; } if ( a == announcementType.schellingRoundBlockDelay ) { roundBlockDelay = b; }
else if ( a == announcementType.schellingCheckRounds ) { interestCheckRounds = uint8(b); } else if ( a == announcementType.schellingCheckRounds ) { interestCheckRounds = uint8(b); }
else if ( a == announcementType.schellingCheckAboves ) { interestCheckAboves = uint8(b); } else if ( a == announcementType.schellingCheckAboves ) { interestCheckAboves = uint8(b); }

View File

@ -22,7 +22,7 @@ contract token is safeMath, module, announcementTypes {
module callbacks module callbacks
*/ */
function replaceModule(address payable addr) external override returns (bool success) { function replaceModule(address payable addr) external override returns (bool success) {
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
require( db.replaceOwner(addr) ); require( db.replaceOwner(addr) );
super._replaceModule(addr); super._replaceModule(addr);
return true; return true;
@ -255,7 +255,7 @@ contract token is safeMath, module, announcementTypes {
@success Was the Function successful? @success Was the Function successful?
*/ */
bytes memory _data; bytes memory _data;
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
_transfer( from, to, amount, fee); _transfer( from, to, amount, fee);
emit Transfer(from, to, amount, _data); emit Transfer(from, to, amount, _data);
return true; return true;
@ -353,7 +353,7 @@ contract token is safeMath, module, announcementTypes {
@success Was the Function successful? @success Was the Function successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
_processTransactionFee(owner, value); _processTransactionFee(owner, value);
return true; return true;
} }
@ -412,7 +412,7 @@ contract token is safeMath, module, announcementTypes {
@success Was the Function successful? @success Was the Function successful?
*/ */
require( super.isModuleHandler(msg.sender) || msg.sender == icoAddr ); require( super.isModuleHandler(payable(msg.sender)) || msg.sender == icoAddr );
_mint(owner, value); _mint(owner, value);
return true; return true;
} }
@ -441,7 +441,7 @@ contract token is safeMath, module, announcementTypes {
@success Was the Function successful? @success Was the Function successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
_burn(owner, value); _burn(owner, value);
return true; return true;
} }
@ -502,7 +502,7 @@ contract token is safeMath, module, announcementTypes {
@success Was the Function successful? @success Was the Function successful?
*/ */
require( super.isModuleHandler(msg.sender) ); require( super.isModuleHandler(payable(msg.sender)) );
if ( aType == announcementType.transactionFeeRate ) { transactionFeeRate = value; } if ( aType == announcementType.transactionFeeRate ) { transactionFeeRate = value; }
else if ( aType == announcementType.transactionFeeMin ) { transactionFeeMin = value; } else if ( aType == announcementType.transactionFeeMin ) { transactionFeeMin = value; }
else if ( aType == announcementType.transactionFeeMax ) { transactionFeeMax = value; } else if ( aType == announcementType.transactionFeeMax ) { transactionFeeMax = value; }

View File

@ -41,7 +41,7 @@ contract EtherToken is StandardToken {
// Balance covers value // Balance covers value
balances[msg.sender] = balances[msg.sender].sub(value); balances[msg.sender] = balances[msg.sender].sub(value);
totalTokens = totalTokens.sub(value); totalTokens = totalTokens.sub(value);
msg.sender.transfer(value); payable(msg.sender).transfer(value);
emit Withdrawal(msg.sender, value); emit Withdrawal(msg.sender, value);
} }
} }

View File

@ -43,7 +43,7 @@ namespace solidity::frontend::test
namespace namespace
{ {
static char const* registrarCode = R"DELIMITER( static char const* registrarCode = R"DELIMITER(
pragma solidity >=0.4.0 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
abstract contract NameRegister { abstract contract NameRegister {
function addr(string memory _name) public virtual view returns (address o_owner); function addr(string memory _name) public virtual view returns (address o_owner);
@ -143,12 +143,12 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
{ {
if (block.timestamp < m_toRecord[_name].renewalDate) if (block.timestamp < m_toRecord[_name].renewalDate)
revert(); revert();
bid(_name, msg.sender, msg.value); bid(_name, payable(msg.sender), msg.value);
} else { } else {
Record storage record = m_toRecord[_name]; Record storage record = m_toRecord[_name];
if (record.owner != 0x0000000000000000000000000000000000000000) if (record.owner != 0x0000000000000000000000000000000000000000)
revert(); revert();
m_toRecord[_name].owner = msg.sender; m_toRecord[_name].owner = payable(msg.sender);
emit Changed(_name); emit Changed(_name);
} }
} }

View File

@ -391,7 +391,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
receive() external payable override(DAOInterface, TokenCreation) { receive() external payable override(DAOInterface, TokenCreation) {
if (block.timestamp < closingTime + creationGracePeriod && msg.sender != address(extraBalance)) if (block.timestamp < closingTime + creationGracePeriod && msg.sender != address(extraBalance))
createTokenProxy(msg.sender); createTokenProxy(payable(msg.sender));
else else
receiveEther(); receiveEther();
} }
@ -459,7 +459,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
p.newCurator = _newCurator; p.newCurator = _newCurator;
if (_newCurator) if (_newCurator)
p.splitData.push(); p.splitData.push();
p.creator = msg.sender; p.creator = payable(msg.sender);
p.proposalDeposit = msg.value; p.proposalDeposit = msg.value;
sumOfProposalDeposits += msg.value; sumOfProposalDeposits += msg.value;
@ -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}(payable(msg.sender)) == false)
revert(); revert();
@ -687,7 +687,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
// Burn DAO Tokens // Burn DAO Tokens
emit Transfer(msg.sender, 0x0000000000000000000000000000000000000000, balances[msg.sender]); emit Transfer(msg.sender, 0x0000000000000000000000000000000000000000, balances[msg.sender]);
withdrawRewardFor(msg.sender); // be nice, and get his rewards withdrawRewardFor(payable(msg.sender)); // be nice, and get his rewards
totalSupply -= balances[msg.sender]; totalSupply -= balances[msg.sender];
balances[msg.sender] = 0; balances[msg.sender] = 0;
paidOut[msg.sender] = 0; paidOut[msg.sender] = 0;
@ -711,7 +711,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
function retrieveDAOReward(bool _toMembers) external override returns (bool _success) { function retrieveDAOReward(bool _toMembers) external override returns (bool _success) {
DAO dao = DAO(msg.sender); DAO dao = DAO(payable(msg.sender));
if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) / if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /
totalRewardToken < DAOpaidOut[msg.sender]) totalRewardToken < DAOpaidOut[msg.sender])
@ -724,11 +724,11 @@ contract DAO is DAOInterface, Token, TokenCreation {
reward = address(DAOrewardAccount).balance < reward ? address(DAOrewardAccount).balance : reward; reward = address(DAOrewardAccount).balance < reward ? address(DAOrewardAccount).balance : reward;
if(_toMembers) { if(_toMembers) {
if (!DAOrewardAccount.payOut(address(dao.rewardAccount()), reward)) if (!DAOrewardAccount.payOut(payable(dao.rewardAccount()), reward))
revert(); revert();
} }
else { else {
if (!DAOrewardAccount.payOut(address(dao), reward)) if (!DAOrewardAccount.payOut(payable(dao), reward))
revert(); revert();
} }
DAOpaidOut[msg.sender] += reward; DAOpaidOut[msg.sender] += reward;
@ -736,7 +736,7 @@ contract DAO is DAOInterface, Token, TokenCreation {
} }
function getMyReward() public override returns (bool _success) { function getMyReward() public override returns (bool _success) {
return withdrawRewardFor(msg.sender); return withdrawRewardFor(payable(msg.sender));
} }

View File

@ -124,7 +124,7 @@ override returns (bool success) {
if (block.timestamp > closingTime && !isFueled) { if (block.timestamp > closingTime && !isFueled) {
// Get extraBalance - will only succeed when called for the first time // Get extraBalance - will only succeed when called for the first time
if (address(extraBalance).balance >= extraBalance.accumulatedInput()) if (address(extraBalance).balance >= extraBalance.accumulatedInput())
extraBalance.payOut(address(this), extraBalance.accumulatedInput()); extraBalance.payOut(payable(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]}("");

View File

@ -445,8 +445,8 @@
"tryCall": false, "tryCall": false,
"typeDescriptions": "typeDescriptions":
{ {
"typeIdentifier": "t_address_payable", "typeIdentifier": "t_address",
"typeString": "address payable" "typeString": "address"
} }
}, },
"src": "232:17:1", "src": "232:17:1",

View File

@ -1328,7 +1328,7 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses)
} }
contract test { contract test {
helper h; helper h;
constructor() payable { h = new helper(); address(h).send(5); } constructor() payable { h = new helper(); payable(h).send(5); }
function getBalance() public returns (uint256 myBalance, uint256 helperBalance) { function getBalance() public returns (uint256 myBalance, uint256 helperBalance) {
myBalance = address(this).balance; myBalance = address(this).balance;
helperBalance = address(h).balance; helperBalance = address(h).balance;
@ -4640,7 +4640,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer)
revert("message"); revert("message");
} }
function f() public { function f() public {
address(this).transfer(0); payable(this).transfer(0);
} }
} }
contract C { contract C {

View File

@ -18,7 +18,7 @@ contract C {
assembly { assembly {
y := x y := x
} }
address payable z = address(y); address payable z = payable(y);
assembly { assembly {
r := z r := z
} }

View File

@ -1,7 +1,7 @@
contract TransferTest { contract TransferTest {
fallback() external payable { fallback() external payable {
// This used to cause an ICE // This used to cause an ICE
address(this).transfer; payable(this).transfer;
} }
function f() pure public {} function f() pure public {}

View File

@ -10,7 +10,7 @@ contract Main {
function s() public returns (bool) { function s() public returns (bool) {
Receiver r = new Receiver(); Receiver r = new Receiver();
return address(r).send(0); return payable(r).send(0);
} }
} }

View File

@ -3,7 +3,7 @@ contract C {
bytes2 constant b = 0xabcd; bytes2 constant b = 0xabcd;
bytes3 constant c = "abc"; bytes3 constant c = "abc";
bool constant d = true; bool constant d = true;
address payable constant e = 0x1212121212121212121212121212121212121212; address constant e = 0x1212121212121212121212121212121212121212;
function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) { function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {
assembly { assembly {
w := a w := a

View File

@ -10,8 +10,8 @@ contract C {
bytes3 constant cccc = ccc; bytes3 constant cccc = ccc;
bool constant d = true; bool constant d = true;
bool constant dd = d; bool constant dd = d;
address payable constant e = 0x1212121212121212121212121212121212121212; address constant e = 0x1212121212121212121212121212121212121212;
address payable constant ee = e; address constant ee = e;
function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) { function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {
assembly { assembly {
w := aaa w := aaa

View File

@ -8,13 +8,13 @@ contract C {
A a = new A(); A a = new A();
receive() external payable {} receive() external payable {}
function f() public { function f() public {
address(a).transfer(1 wei); payable(a).transfer(1 wei);
} }
function h() public { function h() public {
address(a).transfer(100 ether); payable(a).transfer(100 ether);
} }
function g() public view returns (uint) { function g() public view returns (uint) {
return address(this).balance; return payable(this).balance;
} }
} }
// ==== // ====

View File

@ -1,5 +1,5 @@
contract C { contract C {
function f() public returns (address payable) { function f() public returns (address) {
return msg.sender; return msg.sender;
} }
} }

View File

@ -1,5 +1,5 @@
contract C { contract C {
function f() public returns (address payable) { function f() public returns (address) {
return tx.origin; return tx.origin;
} }
} }

View File

@ -4,7 +4,7 @@ contract test {
x; x;
} }
function g() public { function g() public {
suicide(0x0000000000000000000000000000000000000001); suicide(payable(0x0000000000000000000000000000000000000001));
} }
} }
// ---- // ----

View File

@ -0,0 +1,7 @@
contract C {
function f() public {
(msg.sender).send(10);
}
}
// ----
// TypeError 9862: (47-64): "send" and "transfer" are only available for objects of type "address payable", not "address".

View File

@ -0,0 +1,7 @@
contract C {
function f() public {
(msg.sender).transfer(10);
}
}
// ----
// TypeError 9862: (47-68): "send" and "transfer" are only available for objects of type "address payable", not "address".

View File

@ -0,0 +1,7 @@
contract C {
function f() public {
(tx.origin).send(10);
}
}
// ----
// TypeError 9862: (47-63): "send" and "transfer" are only available for objects of type "address payable", not "address".

View File

@ -0,0 +1,7 @@
contract C {
function f() public {
(tx.origin).transfer(10);
}
}
// ----
// TypeError 9862: (47-67): "send" and "transfer" are only available for objects of type "address payable", not "address".

View File

@ -1,6 +1,6 @@
contract test { contract test {
function f() public { function f() public {
address(0x12).send(1); payable(0x12).send(1);
} }
} }
// ---- // ----

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public { function f() public {
(0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E).transfer(2); payable(0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E).transfer(2);
} }
} }
// ---- // ----

View File

@ -9,7 +9,7 @@ contract B {
A a; A a;
fallback() external { fallback() external {
address(a).transfer(100); payable(a).transfer(100);
} }
} }
// ---- // ----

View File

@ -4,7 +4,7 @@ contract C {
return 1; return 1;
} }
function transfer(uint amount) public { function transfer(uint amount) public {
address(this).transfer(amount); // to avoid pureness warning payable(this).transfer(amount); // to avoid pureness warning
} }
receive() payable external { receive() payable external {
} }

View File

@ -1,3 +1,3 @@
contract C { contract C {
address payable constant a = address(0); address payable constant a = payable(0);
} }

View File

@ -9,7 +9,7 @@ contract C {
} }
} }
// ---- // ----
// TypeError 2271: (85-108): Operator + not compatible with types address payable and address payable. Arithmetic operations on addresses are not supported. Convert to integer first before using them. // TypeError 2271: (85-108): Operator + not compatible with types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.
// TypeError 2271: (122-145): Operator - not compatible with types address payable and address payable. Arithmetic operations on addresses are not supported. Convert to integer first before using them. // TypeError 2271: (122-145): Operator - not compatible with types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.
// TypeError 2271: (159-182): Operator * not compatible with types address payable and address payable. Arithmetic operations on addresses are not supported. Convert to integer first before using them. // TypeError 2271: (159-182): Operator * not compatible with types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.
// TypeError 2271: (196-219): Operator / not compatible with types address payable and address payable. Arithmetic operations on addresses are not supported. Convert to integer first before using them. // TypeError 2271: (196-219): Operator / not compatible with types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.

View File

@ -1,6 +1,6 @@
contract C { contract C {
address constant a = address(0); address constant a = address(0);
address payable constant b = address(0); address payable constant b = payable(0);
function f() public pure returns (address, address) { function f() public pure returns (address, address) {
return (a,b); return (a,b);
} }

View File

@ -1,9 +1,9 @@
contract C { contract C {
address constant a = address(0); address constant a = address(0);
address payable constant b = address(0); address payable constant b = payable(0);
function f() public { function f() public {
a = address(0); a = address(0);
b = address(0); b = payable(0);
} }
} }
// ---- // ----

View File

@ -13,8 +13,8 @@ contract B {
} }
S s; S s;
function f() public { function f() public {
s.a = address(this); s.a = payable(this);
} }
receive() external payable { receive() external payable {
} }
} }

View File

@ -0,0 +1,9 @@
contract C {
function f() public pure {
address payable a = payable(address(0x00000000219ab540356cBB839Cbe05303d7705Fa));
address payable b = payable(0x00000000219ab540356cBB839Cbe05303d7705Fa);
a = b;
b = a;
}
}
// ----

View File

@ -0,0 +1,9 @@
contract C {
function f() public pure {
address payable a = address(0x00000000219ab540356cBB839Cbe05303d7705Fa);
address payable b = 0x00000000219ab540356cBB839Cbe05303d7705Fa;
}
}
// ----
// TypeError 9574: (52-123): Type address is not implicitly convertible to expected type address payable.
// TypeError 9574: (133-195): Type address is not implicitly convertible to expected type address payable.

View File

@ -2,7 +2,7 @@ contract C {
function f(address payable) internal pure {} function f(address payable) internal pure {}
function f(address) internal pure {} function f(address) internal pure {}
function g() internal pure { function g() internal pure {
address payable a = address(0); address payable a = payable(0);
f(a); f(a);
} }
} }

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError 9574: (46-62): Type address payable is not implicitly convertible to expected type contract C. // TypeError 9574: (46-62): Type address is not implicitly convertible to expected type contract C.

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public pure returns (C c) { function f() public pure returns (C c) {
c = C(address(2)); c = C(payable(2));
} }
fallback() external payable { fallback() external payable {
} }

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public pure returns (C c) { function f() public pure returns (C c) {
c = C(address(2)); c = C(payable(address(2)));
} }
receive() external payable { receive() external payable {
} }

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public view returns (address payable a, address b) { function f() public view returns (address payable a, address b) {
(address c, address payable d) = (address(this), address(0)); (address c, address payable d) = (address(this), payable(0));
(a,b) = (c,d); (a,b) = (c,d);
} }
} }

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public view returns (address payable a, address b) { function f() public view returns (address payable a, address b) {
(address c, address payable d) = (address(this), address(0)); (address c, address payable d) = (address(this), payable(0));
(a,b) = (d,c); (a,b) = (d,c);
} }
} }

View File

@ -0,0 +1,23 @@
contract C {
function f() public view {
address a1 = address(uint160(0));
address a2 = address(bytes20(0));
address a3 = address(this);
address payable a4 = payable(uint160(0));
address payable a5 = payable(bytes20(0));
address payable a6 = payable(this);
// Trivial conversions
address payable a7 = payable(address(uint160(0)));
address payable a8 = payable(address(bytes20(0)));
address payable a9 = payable(address(this));
a1; a2; a3; a4; a5; a6; a7; a8; a9;
}
// to make payable(this) work
receive() payable external {
}
}
// ----

View File

@ -0,0 +1,11 @@
contract C {
function f() public pure {
address payable a = address(uint160(0));
address payable b = address(bytes20(0));
address payable c = address(this);
}
}
// ----
// TypeError 9574: (52-91): Type address is not implicitly convertible to expected type address payable.
// TypeError 9574: (101-140): Type address is not implicitly convertible to expected type address payable.
// TypeError 9574: (150-183): Type address is not implicitly convertible to expected type address payable.

View File

@ -1,5 +1,5 @@
contract C { contract C {
function f(bytes20 x) public pure returns (address payable) { function f(bytes20 x) public pure returns (address payable) {
return address(x); return payable(x);
} }
} }

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public view { function f() public view {
address payable a = address(this); address payable a = payable(this);
a; a;
} }
fallback() external payable { fallback() external payable {

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public view { function f() public view {
address payable a = address(this); address payable a = payable(this);
a; a;
} }
receive() external payable { receive() external payable {

View File

@ -0,0 +1,5 @@
contract C {
function f() public returns (bool success) {
(success, ) = (address(0)).call{value: 30}("");
}
}

View File

@ -1,8 +1,8 @@
contract C { contract C {
function f() public pure { function f() public pure {
address payable a = address(0); address payable a = payable(0);
a = address(1); a = payable(1);
address payable b = 0x0123456789012345678901234567890123456789; address payable b = payable(0x0123456789012345678901234567890123456789);
b = 0x9876543210987654321098765432109876543210; b = payable(0x9876543210987654321098765432109876543210);
} }
} }

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
address payable a = address(0);
}
}
// ----
// TypeError 9574: (52-82): Type address is not implicitly convertible to expected type address payable.

View File

@ -0,0 +1,29 @@
contract C {
function f() public {
address payable a = payable(address(new D()));
address payable b = payable(new E());
address payable c = payable(new F());
a;
b;
c;
}
}
// A contract that cannot receive Ether
contract D {}
// A contract that can receive Ether
contract E {
receive() external payable {
}
}
// A contract that can receive Ether using the fallback
contract F {
fallback() external payable {
}
}
// ----

View File

@ -0,0 +1,17 @@
contract C {
function f() public {
address payable a = address(new D());
// This conversion makes no sense anyway.
address payable b = address(D);
}
}
contract D {
receive() external payable {
}
}
// ----
// TypeError 9574: (47-83): Type address is not implicitly convertible to expected type address payable.
// TypeError 9640: (164-174): Explicit type conversion not allowed from "type(contract D)" to "address".
// TypeError 9574: (144-174): Type address is not implicitly convertible to expected type address payable.

View File

@ -0,0 +1,8 @@
contract C {
function f() public pure returns (C c) {
c = C(payable(2));
}
receive() external payable {
}
}
// ----

View File

@ -1,5 +1,5 @@
contract C { contract C {
function f(uint x) public pure returns (address payable) { function f(uint x) public pure returns (address payable) {
return address(uint160(x)); return payable(uint160(x));
} }
} }

View File

@ -41,7 +41,7 @@ contract C
// TypeError 9640: (183-213): Explicit type conversion not allowed from "uint16" to "int8". // TypeError 9640: (183-213): Explicit type conversion not allowed from "uint16" to "int8".
// TypeError 9640: (270-277): Explicit type conversion not allowed from "uint16" to "int8". // TypeError 9640: (270-277): Explicit type conversion not allowed from "uint16" to "int8".
// TypeError 9640: (300-329): Explicit type conversion not allowed from "uint256" to "address". // TypeError 9640: (300-329): Explicit type conversion not allowed from "uint256" to "address".
// TypeError 9640: (349-365): Explicit type conversion not allowed from "address payable" to "uint256". // TypeError 9640: (349-365): Explicit type conversion not allowed from "address" to "uint256".
// TypeError 9640: (421-431): Explicit type conversion not allowed from "uint256" to "address". // TypeError 9640: (421-431): Explicit type conversion not allowed from "uint256" to "address".
// TypeError 9640: (452-471): Explicit type conversion not allowed from "bytes10" to "int80". // TypeError 9640: (452-471): Explicit type conversion not allowed from "bytes10" to "int80".
// TypeError 9640: (493-511): Explicit type conversion not allowed from "int80" to "bytes10". // TypeError 9640: (493-511): Explicit type conversion not allowed from "int80" to "bytes10".

View File

@ -1,8 +1,8 @@
contract C { contract C {
function f() public { function f() public {
address(this).transfer(1); payable(this).transfer(1);
require(address(this).send(2)); require(payable(this).send(2));
selfdestruct(address(this)); selfdestruct(payable(this));
(bool success,) = address(this).delegatecall(""); (bool success,) = address(this).delegatecall("");
require(success); require(success);
(success,) = address(this).call(""); (success,) = address(this).call("");

View File

@ -1,12 +1,12 @@
contract C { contract C {
function f() view public { function f() view public {
address(this).transfer(1); payable(this).transfer(1);
} }
function g() view public { function g() view public {
require(address(this).send(2)); require(payable(this).send(2));
} }
function h() view public { function h() view public {
selfdestruct(address(this)); selfdestruct(payable(this));
} }
function i() view public { function i() view public {
(bool success,) = address(this).delegatecall(""); (bool success,) = address(this).delegatecall("");