diff --git a/CHANGELOG.md b/CHANGELOG.md index 11bb5952987..71e201f6a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ ### New features: * `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773)) +### Improvements: + * `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802)) + +### Bugfixes + ## 2.3.0 (2019-05-27) ### New features: diff --git a/contracts/utils/Address.sol b/contracts/utils/Address.sol index ad2f7e72853..112839e4d28 100644 --- a/contracts/utils/Address.sol +++ b/contracts/utils/Address.sol @@ -18,11 +18,15 @@ library Address { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. - - uint256 size; + + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly - assembly { size := extcodesize(account) } - return size > 0; + assembly { codehash := extcodehash(account) } + return (codehash != 0x0 && codehash != accountHash); } /**