Unreachable Code warnings in initialize

After switching to the contracts-upgradeable and moving former constructor code to an initialize function, I am getting a lot of compiler warnings about unreachable code.
Both when calling super.initialize() as the first call in my initialize function as well as in the openzeppelin contracts themselves:

:1234: Code to reproduce

Compiling 25 files with 0.8.5
Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:59:17:
   |
59 |                 deadline
   |                 ^ (Relevant source part starts here and spans across multiple lines).


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:65:9:
   |
65 |         address signer = ECDSAUpgradeable.recover(hash, v, r, s);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The code is however reached and executed.

:computer: Environment

Solidity 0.8.5
@openzeppelin/contracts-upgradeable 4.1.0
@openzeppelin/hardhat-upgrades 1.8.2

I was just a bit confused by the warnings, does that have to do with my editor, solidity, hardhat, openzeppelin, … ?

1 Like

You may need to move these somehow in a way that the initializer can reach them. But this would be non-standard. In my experience I have had to move some functionality down from OZ contracts when using upgradable contracts.

This is very strange, can you share your full code?

// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

import "@openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract OZtest is ERC20PresetMinterPauserUpgradeable, ERC20PermitUpgradeable {

  address public bar;

  function initializeOZtest(
    string memory _name, 
    string memory _symbol, 
    address _bar
  ) public initializer {
    ERC20PresetMinterPauserUpgradeable.initialize(_name, _symbol);
    bar = _bar;
  }

  function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20PresetMinterPauserUpgradeable, ERC20Upgradeable) {
    super._beforeTokenTransfer(from, to, amount);
  }
}

This minimal example triggers it already.
I get a warning from my editor (VS code) on line 18 bar = _bar that it is “unreachable code” (which it isn’t, it’s being executed) and when compiling I get these warnings for the solidity contracts:

Solidity 0.8.5 is not fully supported yet. You can still use Hardhat, but some features, like stack traces, might not work correctly.

Learn more at https://hardhat.org/reference/solidity-support"

Compiling 21 files with 0.8.5
Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:59:17:
   |
59 |                 deadline
   |                 ^ (Relevant source part starts here and spans across multiple lines).


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:65:9:
   |
65 |         address signer = ECDSAUpgradeable.recover(hash, v, r, s);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:66:9:
   |
66 |         require(signer == owner, "ERC20Permit: invalid signature");
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:68:9:
   |
68 |         _approve(owner, spender, value);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:44:9:
   |
44 |         if (isTopLevelCall) {
   |         ^ (Relevant source part starts here and spans across multiple lines).


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol:54:9:
   |
54 |         _setupRole(MINTER_ROLE, _msgSender());
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Unreachable code.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol:55:9:
   |
55 |         _setupRole(PAUSER_ROLE, _msgSender());
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol:41:43:
   |
41 |     function __ERC20Permit_init_unchained(string memory name) internal initializer {
   |                                           ^^^^^^^^^^^^^^^^^^


Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol:51:55:
   |
51 |     function __ERC20PresetMinterPauser_init_unchained(string memory name, string memory symbol) internal initializer {
   |                                                       ^^^^^^^^^^^^^^^^^^


Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.
  --> @openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol:51:75:
   |
51 |     function __ERC20PresetMinterPauser_init_unchained(string memory name, string memory symbol) internal initializer {
   |                                                                           ^^^^^^^^^^^^^^^^^^^^


Compilation finished successfully

My dependencies:

{
  "devDependencies": {
    "@eth-optimism/smock": "^1.1.4",
    "@nomiclabs/hardhat-ethers": "^2.0.2",
    "@nomiclabs/hardhat-etherscan": "^2.1.2",
    "@nomiclabs/hardhat-waffle": "^2.0.1",
    "@openzeppelin/hardhat-upgrades": "^1.8.2",
    "chai": "^4.3.4",
    "ethereum-waffle": "^3.3.0",
    "ethers": "^5.3.1",
    "hardhat": "^2.3.0",
    "hardhat-gas-reporter": "^1.0.4",
    "hardhat-watcher": "^2.1.1"
  },
  "dependencies": {
    "@chainlink/contracts": "^0.1.7",
    "@openzeppelin/contracts-upgradeable": "^4.1.0"
  }
}

Let me know if you need anything else :slight_smile:

I tried a few hours ago, but the system censored it apparently.

This is a bug in 0.8.5.

As a workaround please use 0.8.4 until the Solidity team releases a fix.

1 Like

Ah, good to know, thank you!