synthetix-v3
synthetix-v3 copied to clipboard
isContract() may behave unexpectedly
isContract() in AddressUtil is used to determine whether the account is a contract or an externally owned account (EOA). However, in Solidity, there is no reliable way to definitively determine whether a given address is a contract, as there are several edge cases in which the underlying extcodesize function can return unexpected results.
library AddressUtil {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
}
Solidity 0.8.1 implements a shortcut for account.code.length that avoids copying code to memory. Therefore, the above code should be equivalent.
Recommendations Consider changes below:
function isContract(address account) internal view returns (bool) {
- uint256 size;
-
- assembly {
- size := extcodesize(account)
- }
-
- return size > 0;
+ return account.code.length > 0;
}
Link for reference:
- https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3417
- https://github.com/AmazingAng/WTF-Solidity/pull/721