synthetix-v3 icon indicating copy to clipboard operation
synthetix-v3 copied to clipboard

isContract() may behave unexpectedly

Open dajneem23 opened this issue 3 weeks ago • 0 comments

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

dajneem23 avatar Oct 08 '25 03:10 dajneem23