Upgrade from ERC20Upgradeable to ERC20Upgradeable, EIP712Upgradeable

Hello, I'm trying to upgrade a simple ERC20Upgradeable adding EIP712Upgradeable to the inheritance chain

:1234: Code to reproduce


contract Token is ERC20Upgradeable { }


contract Token is ERC20Upgradeable, EIP712Upgradeable {}

and I'm receiving the following error when running

  await upgrades.validateUpgrade(TokenV1, TokenV2, {});
Error: New storage layout is incompatible

@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol:30: Inserted `_HASHED_NAME`
  > New variables should be placed after all existing inherited variables

Note: I also tried to add ERC2771ContextUpgradeable.sol to the inheritance chain, which gave similar issues, I'm trying to solve one at a time, but a general solution would be really useful (Final inheritance chain should be
contract Token is ERC20Upgradeable, EIP712Upgradeable, ERC2771ContextUpgradeable {}

:computer: Environment

Solidity version: "0.8.7"

"dependencies": {
        "@openzeppelin/contracts-upgradeable": "^4.5.0",
      "devDependencies": {
        "@nomiclabs/hardhat-ethers": "^2.2.0",
        "@nomiclabs/hardhat-web3": "^2.0.0",
        "@openzeppelin/hardhat-upgrades": "^1.21.0",
        "ethers": "^5.7.1",
        "hardhat": "^2.8.0",
        "web3": "^1.7.0"

Just like the error message: Error: New storage layout is incompatible

When you want to add some new variables, you had better add them at the end of all variables, in your case, original contract variables are:


And the new contract you want to upgrade:

EIP712Upgradeable_Variable // <<<<----- insert some variables, DISALLOWED

It is dangerous to upgrade your contract in your way, it will mix up the original data of the contract.

I think you can read some docs about the upgrade, e.g.
Writing Upgradeable Contracts - OpenZeppelin Docs