mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow some explicit conversions to address payable
The following explicit conversions are disallowed: 1. uint160 -> address payable 2. bytes20 -> address payable 3. literals -> address payable (payable(0) is an exception)
This commit is contained in:
parent
ffaf40950a
commit
2fb191175b
@ -89,6 +89,10 @@ This section lists changes that might cause existing contracts to not compile an
|
|||||||
|
|
||||||
- ``address(uint)`` and ``uint(address)``: converting both type-category and width. Replace this by
|
- ``address(uint)`` and ``uint(address)``: converting both type-category and width. Replace this by
|
||||||
``address(uint160(uint))`` and ``uint(uint160(address))`` respectively.
|
``address(uint160(uint))`` and ``uint(uint160(address))`` respectively.
|
||||||
|
- ``payable(uint160)``, ``payable(bytes20)`` and ``payable(integer-literal)``: converting both
|
||||||
|
type-category and state-mutability. Replace this by ``payable(address(uint160))``,
|
||||||
|
``payable(address(bytes20))`` and ``payable(address(integer-literal))`` respectively. Note that
|
||||||
|
``payable(0)`` is valid and is an exception to the rule.
|
||||||
- ``int80(bytes10)`` and ``bytes10(int80)``: converting both type-category and sign. Replace this by
|
- ``int80(bytes10)`` and ``bytes10(int80)``: converting both type-category and sign. Replace this by
|
||||||
``int80(uint80(bytes10))`` and ``bytes10(uint80(int80)`` respectively.
|
``int80(uint80(bytes10))`` and ``bytes10(uint80(int80)`` respectively.
|
||||||
- ``Contract(uint)``: converting both type-category and width. Replace this by
|
- ``Contract(uint)``: converting both type-category and width. Replace this by
|
||||||
@ -126,9 +130,11 @@ This section lists changes that might cause existing contracts to not compile an
|
|||||||
payable``:
|
payable``:
|
||||||
|
|
||||||
- ``address(u)`` where ``u`` is an arbitrary variable of type ``uint160``. One can convert ``u``
|
- ``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)``.
|
into the type ``address payable`` by using two explicit conversions, i.e.,
|
||||||
|
``payable(address(u))``.
|
||||||
- ``address(b)`` where ``b`` is an arbitrary variable of type ``bytes20``. One can convert ``b``
|
- ``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)``.
|
into the type ``address payable`` by using two explicit conversions, i.e.,
|
||||||
|
``payable(address(b))``.
|
||||||
- ``address(c)`` where ``c`` is an arbitrary contract. Previously, the return type of this
|
- ``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
|
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
|
function or a payable fallback function). The conversion ``payable(c)`` has the type ``address
|
||||||
|
@ -399,13 +399,13 @@ BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return true;
|
return true;
|
||||||
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
|
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
|
||||||
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
|
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
|
||||||
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
else if (m_stateMutability == StateMutability::NonPayable)
|
||||||
|
{
|
||||||
|
if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
return (!integerType->isSigned() && integerType->numBits() == 160);
|
return (!integerType->isSigned() && integerType->numBits() == 160);
|
||||||
else if (
|
else if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))
|
||||||
(_convertTo.category() == Category::FixedBytes) &&
|
return (fixedBytesType->numBytes() == 20);
|
||||||
(160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8)
|
}
|
||||||
)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -530,8 +530,11 @@ BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return true;
|
return true;
|
||||||
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
return (numBits() == integerType->numBits()) || (isSigned() == integerType->isSigned());
|
return (numBits() == integerType->numBits()) || (isSigned() == integerType->isSigned());
|
||||||
else if (_convertTo.category() == Category::Address)
|
else if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))
|
||||||
return (!isSigned() && numBits() == 160);
|
return
|
||||||
|
(addressType->stateMutability() != StateMutability::Payable) &&
|
||||||
|
!isSigned() &&
|
||||||
|
(numBits() == 160);
|
||||||
else if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))
|
else if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))
|
||||||
return (!isSigned() && (numBits() == fixedBytesType->numBytes() * 8));
|
return (!isSigned() && (numBits() == fixedBytesType->numBytes() * 8));
|
||||||
else if (dynamic_cast<EnumType const*>(&_convertTo))
|
else if (dynamic_cast<EnumType const*>(&_convertTo))
|
||||||
@ -939,8 +942,13 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo)
|
|||||||
auto category = _convertTo.category();
|
auto category = _convertTo.category();
|
||||||
if (category == Category::FixedBytes)
|
if (category == Category::FixedBytes)
|
||||||
return false;
|
return false;
|
||||||
else if (category == Category::Address)
|
else if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))
|
||||||
return !(isNegative() || isFractional() || !integerType() || integerType()->numBits() > 160);
|
return (m_value == 0) ||
|
||||||
|
((addressType->stateMutability() != StateMutability::Payable) &&
|
||||||
|
!isNegative() &&
|
||||||
|
!isFractional() &&
|
||||||
|
integerType() &&
|
||||||
|
(integerType()->numBits() <= 160));
|
||||||
else if (category == Category::Integer)
|
else if (category == Category::Integer)
|
||||||
return false;
|
return false;
|
||||||
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
|
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
|
||||||
@ -1250,8 +1258,10 @@ BoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) con
|
|||||||
return true;
|
return true;
|
||||||
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
return (!integerType->isSigned() && integerType->numBits() == numBytes() * 8);
|
return (!integerType->isSigned() && integerType->numBits() == numBytes() * 8);
|
||||||
else if (_convertTo.category() == Category::Address && numBytes() == 20)
|
else if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))
|
||||||
return true;
|
return
|
||||||
|
(addressType->stateMutability() != StateMutability::Payable) &&
|
||||||
|
(numBytes() == 20);
|
||||||
else if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))
|
else if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))
|
||||||
return fixedPointType->numBits() == numBytes() * 8;
|
return fixedPointType->numBits() == numBytes() * 8;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user