Repository: skalenetwork/IMA (language: python)

Issue:
Merge post-deployment actions 2.2.0



Discussion / hints:

Fix patch:
diff --git a/.openzeppelin/mainnet.json b/.openzeppelin/mainnet.json
index 03326c589..845f9a3a7 100644
--- a/.openzeppelin/mainnet.json
+++ b/.openzeppelin/mainnet.json
@@ -11895,6 +11895,602 @@
           }
         }
       }
+    },
+    "a2bdaa0e1e80344000c742cd36886eb6191c331f7bde4ec13ad73ab1e7663384": {
+      "address": "0x0AE92a5105111281151b980A0aD680b890bf1944",
+      "txHash": "0x5bbab8be58ac92437310c75b0b68beeb1dae0ce191e67a73f165cf31931d3322",
+      "layout": {
+        "solcVersion": "0.8.16",
+        "storage": [
+          {
+            "label": "_initialized",
+            "offset": 0,
+            "slot": "0",
+            "type": "t_uint8",
+            "contract": "Initializable",
+            "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63",
+            "retypedFrom": "bool"
+          },
+          {
+            "label": "_initializing",
+            "offset": 1,
+            "slot": "0",
+            "type": "t_bool",
+            "contract": "Initializable",
+            "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "1",
+            "type": "t_array(t_uint256)50_storage",
+            "contract": "ContextUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:40"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "51",
+            "type": "t_array(t_uint256)50_storage",
+            "contract": "ERC165Upgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+          },
+          {
+            "label": "_roles",
+            "offset": 0,
+            "slot": "101",
+            "type": "t_mapping(t_bytes32,t_struct(RoleData)169_storage)",
+            "contract": "AccessControlUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:57"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "102",
+            "type": "t_array(t_uint256)49_storage",
+            "contract": "AccessControlUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:260"
+          },
+          {
+            "label": "_roleMembers",
+            "offset": 0,
+            "slot": "151",
+            "type": "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)",
+            "contract": "AccessControlEnumerableUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol:17"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "152",
+            "type": "t_array(t_uint256)49_storage",
+            "contract": "AccessControlEnumerableUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol:76"
+          },
+          {
+            "label": "contractManagerOfSkaleManager",
+            "offset": 0,
+            "slot": "201",
+            "type": "t_contract(IContractManager)11020",
+            "contract": "SkaleManagerClient",
+            "src": "contracts/mainnet/SkaleManagerClient.sol:37"
+          },
+          {
+            "label": "connectedChains",
+            "offset": 0,
+            "slot": "202",
+            "type": "t_mapping(t_bytes32,t_struct(ConnectedChainInfo)12064_storage)",
+            "contract": "MessageProxy",
+            "src": "contracts/MessageProxy.sol:59"
+          },
+          {
+            "label": "_deprecatedRegistryContracts",
+            "offset": 0,
+            "slot": "203",
+            "type": "t_mapping(t_bytes32,t_mapping(t_address,t_bool))",
+            "contract": "MessageProxy",
+            "src": "contracts/MessageProxy.sol:61"
+          },
+          {
+            "label": "gasLimit",
+            "offset": 0,
+            "slot": "204",
+            "type": "t_uint256",
+            "contract": "MessageProxy",
+            "src": "contracts/MessageProxy.sol:63"
+          },
+          {
+            "label": "communityPool",
+            "offset": 0,
+            "slot": "205",
+            "type": "t_contract(ICommunityPool)10226",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:72"
+          },
+          {
+            "label": "headerMessageGasCost",
+            "offset": 0,
+            "slot": "206",
+            "type": "t_uint256",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:74"
+          },
+          {
+            "label": "messageGasCost",
+            "offset": 0,
+            "slot": "207",
+            "type": "t_uint256",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:75"
+          },
+          {
+            "label": "_registryContracts",
+            "offset": 0,
+            "slot": "208",
+            "type": "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:80"
+          },
+          {
+            "label": "version",
+            "offset": 0,
+            "slot": "209",
+            "type": "t_string_storage",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:81"
+          },
+          {
+            "label": "messageInProgress",
+            "offset": 0,
+            "slot": "210",
+            "type": "t_bool",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:82"
+          },
+          {
+            "label": "pauseInfo",
+            "offset": 0,
+            "slot": "211",
+            "type": "t_mapping(t_bytes32,t_struct(Pause)20546_storage)",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:85"
+          },
+          {
+            "label": "_reimbursedContracts",
+            "offset": 0,
+            "slot": "212",
+            "type": "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)",
+            "contract": "MessageProxyForMainnet",
+            "src": "contracts/mainnet/MessageProxyForMainnet.sol:88"
+          }
+        ],
+        "types": {
+          "t_address": {
+            "label": "address",
+            "numberOfBytes": "20"
+          },
+          "t_array(t_bytes32)dyn_storage": {
+            "label": "bytes32[]",
+            "numberOfBytes": "32"
+          },
+          "t_array(t_uint256)49_storage": {
+            "label": "uint256[49]",
+            "numberOfBytes": "1568"
+          },
+          "t_array(t_uint256)50_storage": {
+            "label": "uint256[50]",
+            "numberOfBytes": "1600"
+          },
+          "t_bool": {
+            "label": "bool",
+            "numberOfBytes": "1"
+          },
+          "t_bytes32": {
+            "label": "bytes32",
+            "numberOfBytes": "32"
+          },
+          "t_contract(ICommunityPool)10226": {
+            "label": "contract ICommunityPool",
+            "numberOfBytes": "20"
+          },
+          "t_contract(IContractManager)11020": {
+            "label": "contract IContractManager",
+            "numberOfBytes": "20"
+          },
+          "t_mapping(t_address,t_bool)": {
+            "label": "mapping(address => bool)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_mapping(t_address,t_bool))": {
+            "label": "mapping(bytes32 => mapping(address => bool))",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)": {
+            "label": "mapping(bytes32 => struct EnumerableSetUpgradeable.AddressSet)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(ConnectedChainInfo)12064_storage)": {
+            "label": "mapping(bytes32 => struct MessageProxy.ConnectedChainInfo)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(Pause)20546_storage)": {
+            "label": "mapping(bytes32 => struct MessageProxyForMainnet.Pause)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(RoleData)169_storage)": {
+            "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_uint256)": {
+            "label": "mapping(bytes32 => uint256)",
+            "numberOfBytes": "32"
+          },
+          "t_string_storage": {
+            "label": "string",
+            "numberOfBytes": "32"
+          },
+          "t_struct(AddressSet)9172_storage": {
+            "label": "struct EnumerableSetUpgradeable.AddressSet",
+            "members": [
+              {
+                "label": "_inner",
+                "type": "t_struct(Set)8857_storage",
+                "offset": 0,
+                "slot": "0"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_struct(ConnectedChainInfo)12064_storage": {
+            "label": "struct MessageProxy.ConnectedChainInfo",
+            "members": [
+              {
+                "label": "incomingMessageCounter",
+                "type": "t_uint256",
+                "offset": 0,
+                "slot": "0"
+              },
+              {
+                "label": "outgoingMessageCounter",
+                "type": "t_uint256",
+                "offset": 0,
+                "slot": "1"
+              },
+              {
+                "label": "inited",
+                "type": "t_bool",
+                "offset": 0,
+                "slot": "2"
+              },
+              {
+                "label": "lastOutgoingMessageBlockId",
+                "type": "t_uint256",
+                "offset": 0,
+                "slot": "3"
+              }
+            ],
+            "numberOfBytes": "128"
+          },
+          "t_struct(Pause)20546_storage": {
+            "label": "struct MessageProxyForMainnet.Pause",
+            "members": [
+              {
+                "label": "paused",
+                "type": "t_bool",
+                "offset": 0,
+                "slot": "0"
+              }
+            ],
+            "numberOfBytes": "32"
+          },
+          "t_struct(RoleData)169_storage": {
+            "label": "struct AccessControlUpgradeable.RoleData",
+            "members": [
+              {
+                "label": "members",
+                "type": "t_mapping(t_address,t_bool)",
+                "offset": 0,
+                "slot": "0"
+              },
+              {
+                "label": "adminRole",
+                "type": "t_bytes32",
+                "offset": 0,
+                "slot": "1"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_struct(Set)8857_storage": {
+            "label": "struct EnumerableSetUpgradeable.Set",
+            "members": [
+              {
+                "label": "_values",
+                "type": "t_array(t_bytes32)dyn_storage",
+                "offset": 0,
+                "slot": "0"
+              },
+              {
+                "label": "_indexes",
+                "type": "t_mapping(t_bytes32,t_uint256)",
+                "offset": 0,
+                "slot": "1"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_uint256": {
+            "label": "uint256",
+            "numberOfBytes": "32"
+          },
+          "t_uint8": {
+            "label": "uint8",
+            "numberOfBytes": "1"
+          }
+        },
+        "namespaces": {}
+      }
+    },
+    "6a717c057e9bdaa2975701da4fd44b6532df72918813a2eb93a7bddb466b0e4e": {
+      "address": "0x3417B0DD0FBCC22c3111a083992dB8bABaB9e88a",
+      "txHash": "0xd6697919194bd5c138e3dd2ec2a1cae4dea4c1a55aa77c2b102ee9a0e49564f7",
+      "layout": {
+        "solcVersion": "0.8.16",
+        "storage": [
+          {
+            "label": "_initialized",
+            "offset": 0,
+            "slot": "0",
+            "type": "t_uint8",
+            "contract": "Initializable",
+            "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63",
+            "retypedFrom": "bool"
+          },
+          {
+            "label": "_initializing",
+            "offset": 1,
+            "slot": "0",
+            "type": "t_bool",
+            "contract": "Initializable",
+            "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "1",
+            "type": "t_array(t_uint256)50_storage",
+            "contract": "ContextUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:40"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "51",
+            "type": "t_array(t_uint256)50_storage",
+            "contract": "ERC165Upgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+          },
+          {
+            "label": "_roles",
+            "offset": 0,
+            "slot": "101",
+            "type": "t_mapping(t_bytes32,t_struct(RoleData)169_storage)",
+            "contract": "AccessControlUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:57"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "102",
+            "type": "t_array(t_uint256)49_storage",
+            "contract": "AccessControlUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:260"
+          },
+          {
+            "label": "_roleMembers",
+            "offset": 0,
+            "slot": "151",
+            "type": "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)",
+            "contract": "AccessControlEnumerableUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol:17"
+          },
+          {
+            "label": "__gap",
+            "offset": 0,
+            "slot": "152",
+            "type": "t_array(t_uint256)49_storage",
+            "contract": "AccessControlEnumerableUpgradeable",
+            "src": "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol:76"
+          },
+          {
+            "label": "contractManagerOfSkaleManager",
+            "offset": 0,
+            "slot": "201",
+            "type": "t_contract(IContractManager)11020",
+            "contract": "SkaleManagerClient",
+            "src": "contracts/mainnet/SkaleManagerClient.sol:37"
+          },
+          {
+            "label": "messageProxy",
+            "offset": 0,
+            "slot": "202",
+            "type": "t_contract(IMessageProxyForMainnet)10412",
+            "contract": "Twin",
+            "src": "contracts/mainnet/Twin.sol:38"
+          },
+          {
+            "label": "schainLinks",
+            "offset": 0,
+            "slot": "203",
+            "type": "t_mapping(t_bytes32,t_address)",
+            "contract": "Twin",
+            "src": "contracts/mainnet/Twin.sol:39"
+          },
+          {
+            "label": "_userWallets",
+            "offset": 0,
+            "slot": "204",
+            "type": "t_mapping(t_address,t_mapping(t_bytes32,t_uint256))",
+            "contract": "CommunityPool",
+            "src": "contracts/mainnet/CommunityPool.sol:44"
+          },
+          {
+            "label": "activeUsers",
+            "offset": 0,
+            "slot": "205",
+            "type": "t_mapping(t_address,t_mapping(t_bytes32,t_bool))",
+            "contract": "CommunityPool",
+            "src": "contracts/mainnet/CommunityPool.sol:47"
+          },
+          {
+            "label": "minTransactionGas",
+            "offset": 0,
+            "slot": "206",
+            "type": "t_uint256",
+            "contract": "CommunityPool",
+            "src": "contracts/mainnet/CommunityPool.sol:49"
+          },
+          {
+            "label": "multiplierNumerator",
+            "offset": 0,
+            "slot": "207",
+            "type": "t_uint256",
+            "contract": "CommunityPool",
+            "src": "contracts/mainnet/CommunityPool.sol:51"
+          },
+          {
+            "label": "multiplierDivider",
+            "offset": 0,
+            "slot": "208",
+            "type": "t_uint256",
+            "contract": "CommunityPool",
+            "src": "contracts/mainnet/CommunityPool.sol:52"
+          }
+        ],
+        "types": {
+          "t_address": {
+            "label": "address",
+            "numberOfBytes": "20"
+          },
+          "t_array(t_bytes32)dyn_storage": {
+            "label": "bytes32[]",
+            "numberOfBytes": "32"
+          },
+          "t_array(t_uint256)49_storage": {
+            "label": "uint256[49]",
+            "numberOfBytes": "1568"
+          },
+          "t_array(t_uint256)50_storage": {
+            "label": "uint256[50]",
+            "numberOfBytes": "1600"
+          },
+          "t_bool": {
+            "label": "bool",
+            "numberOfBytes": "1"
+          },
+          "t_bytes32": {
+            "label": "bytes32",
+            "numberOfBytes": "32"
+          },
+          "t_contract(IContractManager)11020": {
+            "label": "contract IContractManager",
+            "numberOfBytes": "20"
+          },
+          "t_contract(IMessageProxyForMainnet)10412": {
+            "label": "contract IMessageProxyForMainnet",
+            "numberOfBytes": "20"
+          },
+          "t_mapping(t_address,t_bool)": {
+            "label": "mapping(address => bool)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_address,t_mapping(t_bytes32,t_bool))": {
+            "label": "mapping(address => mapping(bytes32 => bool))",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_address,t_mapping(t_bytes32,t_uint256))": {
+            "label": "mapping(address => mapping(bytes32 => uint256))",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_address)": {
+            "label": "mapping(bytes32 => address)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_bool)": {
+            "label": "mapping(bytes32 => bool)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(AddressSet)9172_storage)": {
+            "label": "mapping(bytes32 => struct EnumerableSetUpgradeable.AddressSet)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_struct(RoleData)169_storage)": {
+            "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)",
+            "numberOfBytes": "32"
+          },
+          "t_mapping(t_bytes32,t_uint256)": {
+            "label": "mapping(bytes32 => uint256)",
+            "numberOfBytes": "32"
+          },
+          "t_struct(AddressSet)9172_storage": {
+            "label": "struct EnumerableSetUpgradeable.AddressSet",
+            "members": [
+              {
+                "label": "_inner",
+                "type": "t_struct(Set)8857_storage",
+                "offset": 0,
+                "slot": "0"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_struct(RoleData)169_storage": {
+            "label": "struct AccessControlUpgradeable.RoleData",
+            "members": [
+              {
+                "label": "members",
+                "type": "t_mapping(t_address,t_bool)",
+                "offset": 0,
+                "slot": "0"
+              },
+              {
+                "label": "adminRole",
+                "type": "t_bytes32",
+                "offset": 0,
+                "slot": "1"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_struct(Set)8857_storage": {
+            "label": "struct EnumerableSetUpgradeable.Set",
+            "members": [
+              {
+                "label": "_values",
+                "type": "t_array(t_bytes32)dyn_storage",
+                "offset": 0,
+                "slot": "0"
+              },
+              {
+                "label": "_indexes",
+                "type": "t_mapping(t_bytes32,t_uint256)",
+                "offset": 0,
+                "slot": "1"
+              }
+            ],
+            "numberOfBytes": "64"
+          },
+          "t_uint256": {
+            "label": "uint256",
+            "numberOfBytes": "32"
+          },
+          "t_uint8": {
+            "label": "uint8",
+            "numberOfBytes": "1"
+          }
+        },
+        "namespaces": {}
+      }
     }
   }
 }
diff --git a/DEPLOYED b/DEPLOYED
index 611689143..2171bf91e 100644
--- a/DEPLOYED
+++ b/DEPLOYED
@@ -1,1 +1,1 @@
-2.1.0-stable.0
+2.2.0-stable.0
diff --git a/migrations/generateManifest.ts b/migrations/generateManifest.ts
index 4506cf827..48e1496bb 100644
--- a/migrations/generateManifest.ts
+++ b/migrations/generateManifest.ts
@@ -1,4 +1,4 @@
-import { ethers } from "hardhat";
+import { ethers, upgrades } from "hardhat";
 import { contracts, getContractKeyInAbiFile } from "./deploySchain";
 import { networkNames } from "@openzeppelin/upgrades-core";
 import { promises as fs } from "fs";
@@ -92,6 +92,11 @@ async function readValidations() {
     }
 }
 
+async function getManifestAdmin(abi: {[ key in string ]: string | []}) {
+    const randomProxy = abi[getContractKeyInAbiFile(contracts[0]) + "_address"] as string;
+    return await upgrades.erc1967.getAdminAddress(randomProxy);
+}
+
 export async function generateManifest(addresses: Addresses) {
     const newManifest: ManifestData = emptyManifest();
     newManifest.admin = getDeployment(addresses.admin);
@@ -106,12 +111,13 @@ export async function generateManifest(addresses: Addresses) {
 }
 
 export async function importAddresses(manifest: ManifestData, abi: {[ key in string ]: string | []}) {
-    if (!manifest.admin) {
+    const manifestAdminAddress = await getManifestAdmin(abi);
+    if (!manifestAdminAddress) {
         throw Error("Proxy admin is missing in manifest file");
     }
     const addresses: Addresses = {};
-    addresses.admin = manifest.admin.address;
-    console.log("Admin address", manifest.admin.address, "imported");
+    addresses.admin = manifestAdminAddress;
+    console.log("Admin address", manifestAdminAddress, "imported");
     for (const contract of contracts) {
         const proxyAddress = abi[getContractKeyInAbiFile(contract) + "_address"];
         if (Array.isArray(proxyAddress)) {
diff --git a/migrations/upgradeMainnet.ts b/migrations/upgradeMainnet.ts
index 226646d10..4936931cf 100644
--- a/migrations/upgradeMainnet.ts
+++ b/migrations/upgradeMainnet.ts
@@ -1,7 +1,7 @@
 import chalk from "chalk";
 import { ethers } from "hardhat";
 import { promises as fs } from 'fs';
-import { Interface, Transaction } from "ethers";
+import { Transaction } from "ethers";
 import { getAbi, getVersion, Submitter, Upgrader } from "@skalenetwork/upgrade-tools";
 import { skaleContracts, Instance } from "@skalenetwork/skale-contracts-ethers-v6";
 import { MessageProxyForMainnet } from "../typechain";
@@ -60,76 +60,7 @@ class ImaMainnetUpgrader extends Upgrader {
 
     // deployNewContracts = () => { };
 
-    initialize = async () => {
-        const contractManagerAddress = await (await this.getMessageProxyForMainnet()).contractManagerOfSkaleManager();
-        const contractManagerInterface = new Interface([{
-            "type": "function",
-            "name": "getContract",
-            "constant": true,
-            "stateMutability": "view",
-            "payable": false,
-            "inputs": [
-                {
-                    "type": "string",
-                    "name": "name"
-                }
-            ],
-            "outputs": [
-                {
-                    "type": "address",
-                    "name": "contractAddress"
-                }
-            ]
-        },
-        {
-            "type": "function",
-            "name": "setContractsAddress",
-            "constant": false,
-            "payable": false,
-            "inputs": [
-                {
-                    "type": "string",
-                    "name": "contractsName"
-                },
-                {
-                    "type": "address",
-                    "name": "newContractsAddress"
-                }
-            ],
-            "outputs": []
-        }]);
-        const contractManager = new ethers.Contract(
-            contractManagerAddress,
-            contractManagerInterface,
-            ethers.provider
-        )
-        for (const contractName of contracts) {
-            try {
-                const contractAddress = await contractManager.getContract(contractName);
-                console.log(`Address of ${contractName} is set to ${contractAddress}`);
-            } catch {
-                // getContract failed because the contract is not set
-                const contractAddress = await this.instance.getContract(contractName);
-                this.transactions.push(Transaction.from(
-                    {
-                        to: await contractManager.getAddress(),
-                        data: contractManager.interface.encodeFunctionData(
-                            "setContractsAddress",
-                            [contractAddress]
-                        )
-                    }
-                ))
-                console.log(`Set ${contractName} address to ${contractAddress}`);
-            }
-        }
-    };
-
-    _getContractKeyInAbiFile(contract: string) {
-        if (contract === "MessageProxyForMainnet") {
-            return "message_proxy_mainnet";
-        }
-        return contract.replace(/([a-z0-9])(?=[A-Z])/g, '$1_').toLowerCase();
-    }
+    // initialize = async () => { };
 }
 
 async function updateAbi() {
@@ -145,16 +76,20 @@ async function updateAbi() {
         const contractInterface = (await ethers.getContractFactory(contract)).interface;
         abi[getContractKeyInAbiFile(contract) + "_abi"] = getAbi(contractInterface);
     }
-    const newAbiFilename = `mainnet-ima-${version}-${network.name}.json`;
+    const newAbiFilename = `data/mainnet-ima-${version}-${network.name}.json`;
     await fs.writeFile(newAbiFilename, JSON.stringify(abi, null, 4));
     console.log(chalk.green(`ABI updated and saved to ${newAbiFilename}`));
 }
 
 async function main() {
+    let contractNamesToUpgrade: string[] = [];
+    if (process.env.UPGRADE_ALL) {
+        contractNamesToUpgrade = contracts;
+    }
     const upgrader = new ImaMainnetUpgrader(
-        "2.1.0",
+        "2.2.0",
         await getImaMainnetInstance(),
-        contracts
+        contractNamesToUpgrade
     );
     await upgrader.upgrade();
     await updateAbi();
diff --git a/migrations/upgradeSchain.ts b/migrations/upgradeSchain.ts
index 57f8ea942..7f04d55ca 100644
--- a/migrations/upgradeSchain.ts
+++ b/migrations/upgradeSchain.ts
@@ -84,7 +84,7 @@ async function updateAbi(contracts: string[]) {
         const contractInterface = (await ethers.getContractFactory(contract)).interface;
         abi[getContractKeyInAbiFile(contract) + "_abi"] = getAbi(contractInterface);
     }
-    const newAbiFilename = `schain-ima-${version}-${network.name}.json`;
+    const newAbiFilename = `data/schain-ima-${version}-${network.name}.json`;
     await fs.writeFile(newAbiFilename, JSON.stringify(abi, null, 4));
     console.log(chalk.green(`ABI updated and saved to ${newAbiFilename}`));
 }
@@ -92,10 +92,15 @@ async function updateAbi(contracts: string[]) {
 async function main() {
     const pathToManifest: string = process.env.MANIFEST || "";
     await manifestSetup(pathToManifest);
+    let contractNamesToUpgrade: string[] = [
+    ]
+    if (process.env.UPGRADE_ALL) {
+        contractNamesToUpgrade = contracts;
+    }
     const upgrader = new ImaSchainUpgrader(
-        "2.1.0",
+        "2.2.0",
         await getImaSchainInstance(),
-        contracts
+        contractNamesToUpgrade
     );
     await upgrader.upgrade();
     updateAbi(contracts);
diff --git a/package.json b/package.json
index d290ca444..d9a0bdcac 100644
--- a/package.json
+++ b/package.json
@@ -61,5 +61,6 @@
         "ts-node": "^8.10.2",
         "typechain": "^8.3.1",
         "typescript": "^5.1.6"
-    }
+    },
+    "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
 }


Test patch:
diff --git a/contracts/test/TestContractManager.sol b/contracts/test/TestContractManager.sol
index a49128db1..5b0659560 100644
--- a/contracts/test/TestContractManager.sol
+++ b/contracts/test/TestContractManager.sol
@@ -38,6 +38,10 @@ contract ContractManager is IContractManagerTester {
 
     event ContractUpgraded(string contractsName, address contractsAddress);
 
+    error ContractNotFound(
+        string contractName
+    );
+
     constructor() {
         owner = msg.sender;
     }
@@ -64,7 +68,17 @@ contract ContractManager is IContractManagerTester {
     /**
      * @dev Returns the contract address for a given contractName.
      */
-    function getContract(string calldata contractName) external view override returns (address) {
-        return contracts[keccak256(abi.encodePacked(contractName))];
+    function getContract(
+        string memory name
+    )
+        public
+        view
+        override
+        returns (address contractAddress)
+    {
+        contractAddress = contracts[keccak256(abi.encodePacked(name))];
+        if (contractAddress == address(0)) {
+            revert ContractNotFound(name);
+        }
     }
 }
diff --git a/scripts/test_upgrade.sh b/scripts/test_upgrade.sh
index 44e691de4..89cb0788f 100755
--- a/scripts/test_upgrade.sh
+++ b/scripts/test_upgrade.sh
@@ -23,7 +23,7 @@ DEPLOYED_DIR=$GITHUB_WORKSPACE/deployed-IMA/
 
 git clone --branch "$DEPLOYED_TAG" "https://github.com/$GITHUB_REPOSITORY.git" "$DEPLOYED_DIR"
 
-ACCOUNTS_FILENAME="$DEPLOYED_DIR/proxy/generatedAccounts.json"
+ACCOUNTS_FILENAME="$DEPLOYED_DIR/generatedAccounts.json"
 GANACHE=$(npx ganache \
     --😈 \
     --miner.blockGasLimit 12000000 \
@@ -32,7 +32,7 @@ GANACHE=$(npx ganache \
     --wallet.accountKeysPath "$ACCOUNTS_FILENAME" \
 )
 
-cd "$DEPLOYED_DIR/proxy"
+cd "$DEPLOYED_DIR"
 yarn install
 PRIVATE_KEY_FOR_ETHEREUM=$(cat "$ACCOUNTS_FILENAME" | jq -r  '.private_keys | to_entries | .[8].value')
 PRIVATE_KEY_FOR_SCHAIN=$(cat "$ACCOUNTS_FILENAME" | jq -r '.private_keys | to_entries | .[0].value')
@@ -43,11 +43,8 @@ VERSION="$DEPLOYED_VERSION" \
 PRIVATE_KEY_FOR_ETHEREUM="$PRIVATE_KEY_FOR_ETHEREUM" \
 PRIVATE_KEY_FOR_SCHAIN="$PRIVATE_KEY_FOR_SCHAIN" \
 npx hardhat run migrations/deploySkaleManagerComponents.ts --network localhost
-# TODO: remove this line after upgrading to 2.2.0
-perl -0777 -i -pe 's/await contractManagerInst\.setContractsAddress\( "MessageProxyForMainnet",[^\}]*console\.log\( "Successfully registered MessageProxy in ContractManager" \);/await contractManagerInst.setContractsAddress( "MessageProxyForMainnet", deployed.get( "MessageProxyForMainnet" )?.address);\nawait contractManagerInst.setContractsAddress( "CommunityPool", deployed.get( "CommunityPool" )?.address);\nawait contractManagerInst.setContractsAddress( "Linker", deployed.get( "Linker" )?.address);\nfor (const contractName of contractsToDeploy) {\n    const contract = deployed.get(contractName);\n    if (contract === undefined) {\n        throw new Error(`\${contractName} was not found`);\n    }\n    await contractManagerInst.setContractsAddress( contractName, contract.address);\n}\nconsole.log( "Successfully registered MessageProxy in ContractManager" );/s' migrations/deployMainnet.ts
-# end of TODO
 SKALE_MANAGER=$(cat data/skaleManagerComponents.json | jq -r .skale_manager_address)
-VERSION="$DEPLOYED_VERSION" TARGET=$SKALE_MANAGER npx hardhat run migrations/deployMainnet.ts --network localhost
+VERSION="$DEPLOYED_VERSION" SKALE_MANAGER_ADDRESS=$SKALE_MANAGER npx hardhat run migrations/deployMainnet.ts --network localhost
 
 
 CHAIN_NAME_SCHAIN="Test" \
@@ -56,6 +53,7 @@ URL_W3_S_CHAIN="$URL_W3_S_CHAIN" \
 PRIVATE_KEY_FOR_SCHAIN="$PRIVATE_KEY_FOR_SCHAIN" \
 npx hardhat run migrations/deploySchain.ts --network schain
 
+cp "$GITHUB_WORKSPACE/migrations/generateManifest.ts" "$DEPLOYED_DIR/migrations/generateManifest.ts"
 ABI_FILENAME_SCHAIN="proxySchain_Test.json"
 ABI="data/$ABI_FILENAME_SCHAIN" \
 MANIFEST=".openzeppelin/unknown-1337.json" \
@@ -71,7 +69,7 @@ cd "$GITHUB_WORKSPACE"
 rm -r --interactive=never "$DEPLOYED_DIR"
 
 MESSAGE_PROXY_FOR_MAINNET=$(cat data/proxyMainnet.json | jq -r .message_proxy_mainnet_address)
-TEST_UPGRADE=true \
+UPGRADE_ALL=true \
 ABI="data/proxyMainnet.json" \
 TARGET="$MESSAGE_PROXY_FOR_MAINNET" \
 ALLOW_NOT_ATOMIC_UPGRADE="OK" \
@@ -87,6 +85,7 @@ MESSAGE_PROXY_FOR_SCHAIN=$(cat data/$ABI_FILENAME_SCHAIN | jq -r .message_proxy_
 # ABI="data/$ABI_FILENAME_SCHAIN" \
 # MANIFEST="data/ima-schain-$DEPLOYED_VERSION-manifest.json" \
 # CHAIN_NAME_SCHAIN="Test" \
+# UPGRADE_ALL=true \
 # ALLOW_NOT_ATOMIC_UPGRADE="OK" \
 # TARGET="$MESSAGE_PROXY_FOR_SCHAIN" \
 # VERSION=$VERSION_TAG \
diff --git a/test/utils/deploy/mainnet/messageProxyForMainnet.ts b/test/utils/deploy/mainnet/messageProxyForMainnet.ts
index e169c9312..a14a6b6a3 100644
--- a/test/utils/deploy/mainnet/messageProxyForMainnet.ts
+++ b/test/utils/deploy/mainnet/messageProxyForMainnet.ts
@@ -7,11 +7,12 @@ export async function deployMessageProxyForMainnet(
     contractManager: ContractManager
 ) {
     const factory = await ethers.getContractFactory(name);
-    if (await contractManager.getContract(name) !== "0x0000000000000000000000000000000000000000") {
-        return factory.attach(await contractManager.getContract(name)) as MessageProxyForMainnet;
-    } else {
+    try {
+        await contractManager.getContract(name);
+    } catch {
         const instance = await upgrades.deployProxy(factory, [await contractManager.getAddress()]) as unknown as MessageProxyForMainnet;
         await contractManager.setContractsAddress(name, instance);
         return instance;
     }
+    return factory.attach(await contractManager.getContract(name)) as MessageProxyForMainnet;
 }
diff --git a/test/utils/deploy/test/messageProxyForMainnetTester.ts b/test/utils/deploy/test/messageProxyForMainnetTester.ts
index 2a2ac35eb..0053f02e1 100644
--- a/test/utils/deploy/test/messageProxyForMainnetTester.ts
+++ b/test/utils/deploy/test/messageProxyForMainnetTester.ts
@@ -7,9 +7,9 @@ export async function deployMessageProxyForMainnetTester(
     contractManager: ContractManager
 ) {
     const factory = await ethers.getContractFactory(name);
-    if (await contractManager.getContract(name) !== "0x0000000000000000000000000000000000000000") {
-        return factory.attach(await contractManager.getContract(name)) as MessageProxyForMainnetTester;
-    } else {
+    try {
+        await contractManager.getContract(name);
+    } catch {
         const instance = await upgrades.deployProxy(
             factory,
             [await contractManager.getAddress()]
@@ -17,4 +17,5 @@ export async function deployMessageProxyForMainnetTester(
         await contractManager.setContractsAddress(name, instance);
         return instance;
     }
+    return factory.attach(await contractManager.getContract(name)) as MessageProxyForMainnetTester;
 }
diff --git a/test/utils/skale-manager-utils/contractManager.ts b/test/utils/skale-manager-utils/contractManager.ts
index 6c21724a2..5a71dd03e 100644
--- a/test/utils/skale-manager-utils/contractManager.ts
+++ b/test/utils/skale-manager-utils/contractManager.ts
@@ -13,31 +13,43 @@ export async function deployContractManager(contractManagerAddress: string) {
     if (contractManagerAddress === "0x0000000000000000000000000000000000000000") {
         instance = await contractManagerFactory.deploy() as ContractManager;
     } else {
-        instance = await contractManagerFactory.attach(contractManagerAddress) as ContractManager;
+        instance = contractManagerFactory.attach(contractManagerAddress) as ContractManager;
     }
-    if (await instance.getContract("KeyStorage") === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract("KeyStorage");
+    } catch {
         const keyStorageInstance = await (await ethers.getContractFactory("KeyStorageMock")).deploy() as KeyStorageMock;
         await instance.setContractsAddress("KeyStorage", keyStorageInstance);
     }
-    if (await instance.getContract(nameNodes) === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract(nameNodes);
+    } catch {
         const nodesInstance = await (await ethers.getContractFactory(nameNodes)).deploy() as Nodes;
         await instance.setContractsAddress(nameNodes, nodesInstance);
     }
-    if (await instance.getContract(nameSchains) === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract(nameSchains);
+    } catch {
         const schainsInstance = await (await ethers.getContractFactory(nameSchains)).deploy() as Schains;
         await schainsInstance.addContractManager(instance);
         await instance.setContractsAddress(nameSchains, schainsInstance);
     }
-    if (await instance.getContract(nameSchainsInternal) === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract(nameSchainsInternal);
+    } catch {
         const schainsInternalInstance = await (await ethers.getContractFactory(nameSchainsInternal)).deploy() as SchainsInternal;
         await schainsInternalInstance.addContractManager(instance);
         await instance.setContractsAddress(nameSchainsInternal, schainsInternalInstance);
     }
-    if (await instance.getContract(nameSkaleVerifier) === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract(nameSkaleVerifier);
+    } catch {
         const skaleVerifierInstance = await (await ethers.getContractFactory(nameSkaleVerifier)).deploy() as SkaleVerifierMock;
         await instance.setContractsAddress("SkaleVerifier", skaleVerifierInstance);
     }
-    if (await instance.getContract(nameWallets) === "0x0000000000000000000000000000000000000000") {
+    try {
+        await instance.getContract(nameWallets);
+     } catch {
         const walletsInstance = await (await ethers.getContractFactory(nameWallets)).deploy() as Wallets;
         await walletsInstance.addContractManager(instance);
         await instance.setContractsAddress(nameWallets, walletsInstance);