@skalenetwork/upgrade-tools 3.0.0-linter.9 → 3.0.0-merge-stable.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { HardhatUserConfig } from "hardhat/config";
2
- import "@typechain/hardhat";
2
+ import '@typechain/hardhat';
3
3
  import "@nomiclabs/hardhat-ethers";
4
4
  import "@openzeppelin/hardhat-upgrades";
5
5
  declare const config: HardhatUserConfig;
@@ -4,9 +4,9 @@ require("@typechain/hardhat");
4
4
  require("@nomiclabs/hardhat-ethers");
5
5
  require("@openzeppelin/hardhat-upgrades");
6
6
  const config = {
7
- "typechain": {
8
- "target": "ethers-v5",
9
- "externalArtifacts": ["node_modules/@openzeppelin/upgrades-core/artifacts/[!b]*.json"]
7
+ typechain: {
8
+ target: "ethers-v5",
9
+ externalArtifacts: ['node_modules/@openzeppelin/upgrades-core/artifacts/[!b]*.json']
10
10
  }
11
11
  };
12
12
  exports.default = config;
package/dist/src/abi.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  import { Interface } from "ethers/lib/utils";
2
- export declare const getAbi: (contractInterface: Interface) => [];
2
+ export declare function getAbi(contractInterface: Interface): [];
package/dist/src/abi.js CHANGED
@@ -1,19 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAbi = void 0;
4
- const getAbi = (contractInterface) => {
4
+ function getAbi(contractInterface) {
5
5
  const abi = JSON.parse(contractInterface.format("json"));
6
6
  abi.forEach((obj) => {
7
7
  if (obj.type === "function") {
8
8
  const func = obj;
9
9
  func.inputs.concat(func.outputs).forEach((output) => {
10
- Object.assign(output, {
11
- "name": "",
12
- ...output
13
- });
10
+ Object.assign(output, Object.assign({ name: "" }, output));
14
11
  });
15
12
  }
16
13
  });
17
14
  return abi;
18
- };
15
+ }
19
16
  exports.getAbi = getAbi;
@@ -1,4 +1,4 @@
1
- export declare const deployLibraries: (libraryNames: string[]) => Promise<Map<string, string>>;
2
- export declare const getLinkedContractFactory: (contractName: string, libraries: Map<string, string>) => Promise<import("ethers").ContractFactory>;
3
- export declare const getManifestFile: () => Promise<string>;
4
- export declare const getContractFactory: (contract: string) => Promise<import("ethers").ContractFactory>;
1
+ export declare function deployLibraries(libraryNames: string[]): Promise<Map<string, string>>;
2
+ export declare function getLinkedContractFactory(contractName: string, libraries: Map<string, string>): Promise<import("ethers").ContractFactory>;
3
+ export declare function getManifestFile(): Promise<string>;
4
+ export declare function getContractFactory(contract: string): Promise<import("ethers").ContractFactory>;
@@ -4,22 +4,21 @@ exports.getContractFactory = exports.getManifestFile = exports.getLinkedContract
4
4
  const upgrades_core_1 = require("@openzeppelin/upgrades-core");
5
5
  const hardhat_1 = require("hardhat");
6
6
  const fs_1 = require("fs");
7
- const _deployLibrary = async (libraryName) => {
8
- const Library = await hardhat_1.ethers.getContractFactory(libraryName);
9
- const library = await Library.deploy();
7
+ async function _deployLibrary(libraryName) {
8
+ const Library = await hardhat_1.ethers.getContractFactory(libraryName), library = await Library.deploy();
10
9
  await library.deployed();
11
10
  return library.address;
12
- };
13
- const deployLibraries = async (libraryNames) => {
11
+ }
12
+ async function deployLibraries(libraryNames) {
14
13
  const libraries = new Map();
15
14
  for (const libraryName of libraryNames) {
16
15
  libraries.set(libraryName, await _deployLibrary(libraryName));
17
16
  }
18
17
  return libraries;
19
- };
18
+ }
20
19
  exports.deployLibraries = deployLibraries;
21
- const _linkBytecode = (artifact, libraries) => {
22
- let { bytecode } = artifact;
20
+ function _linkBytecode(artifact, libraries) {
21
+ let bytecode = artifact.bytecode;
23
22
  for (const [, fileReferences] of Object.entries(artifact.linkReferences)) {
24
23
  for (const [libName, fixups] of Object.entries(fileReferences)) {
25
24
  const addr = libraries.get(libName);
@@ -35,28 +34,26 @@ const _linkBytecode = (artifact, libraries) => {
35
34
  }
36
35
  }
37
36
  return bytecode;
38
- };
39
- const getLinkedContractFactory = async (contractName, libraries) => {
40
- const cArtifact = await hardhat_1.artifacts.readArtifact(contractName);
41
- const linkedBytecode = _linkBytecode(cArtifact, libraries);
42
- const ContractFactory = await hardhat_1.ethers.getContractFactory(cArtifact.abi, linkedBytecode);
37
+ }
38
+ async function getLinkedContractFactory(contractName, libraries) {
39
+ const cArtifact = await hardhat_1.artifacts.readArtifact(contractName), linkedBytecode = _linkBytecode(cArtifact, libraries), ContractFactory = await hardhat_1.ethers.getContractFactory(cArtifact.abi, linkedBytecode);
43
40
  return ContractFactory;
44
- };
41
+ }
45
42
  exports.getLinkedContractFactory = getLinkedContractFactory;
46
- const getManifestFile = async () => (await upgrades_core_1.Manifest.forNetwork(hardhat_1.ethers.provider)).file;
43
+ async function getManifestFile() {
44
+ return (await upgrades_core_1.Manifest.forNetwork(hardhat_1.ethers.provider)).file;
45
+ }
47
46
  exports.getManifestFile = getManifestFile;
48
- const getContractFactory = async (contract) => {
47
+ async function getContractFactory(contract) {
49
48
  const { linkReferences } = await hardhat_1.artifacts.readArtifact(contract);
50
- if (!Object.keys(linkReferences).length) {
49
+ if (!Object.keys(linkReferences).length)
51
50
  return await hardhat_1.ethers.getContractFactory(contract);
52
- }
53
51
  const libraryNames = [];
54
52
  for (const key of Object.keys(linkReferences)) {
55
53
  const libraryName = Object.keys(linkReferences[key])[0];
56
54
  libraryNames.push(libraryName);
57
55
  }
58
- const libraries = await (0, exports.deployLibraries)(libraryNames);
59
- const libraryArtifacts = {};
56
+ const libraries = await deployLibraries(libraryNames), libraryArtifacts = {};
60
57
  for (const [libraryName, libraryAddress] of libraries.entries()) {
61
58
  const { bytecode } = await hardhat_1.artifacts.readArtifact(libraryName);
62
59
  libraryArtifacts[libraryName] = {
@@ -64,14 +61,17 @@ const getContractFactory = async (contract) => {
64
61
  "bytecodeHash": (0, upgrades_core_1.hashBytecode)(bytecode)
65
62
  };
66
63
  }
67
- const manifest = JSON.parse(await fs_1.promises.readFile(await (0, exports.getManifestFile)(), "utf-8"));
68
- if (manifest.libraries === undefined) {
69
- Object.assign(manifest, { "libraries": libraryArtifacts });
70
- }
71
- else {
64
+ let manifest;
65
+ try {
66
+ manifest = JSON.parse(await fs_1.promises.readFile(await getManifestFile(), "utf-8"));
72
67
  Object.assign(libraryArtifacts, manifest.libraries);
73
68
  }
74
- await fs_1.promises.writeFile(await (0, exports.getManifestFile)(), JSON.stringify(manifest, null, 4));
75
- return await (0, exports.getLinkedContractFactory)(contract, libraries);
76
- };
69
+ finally {
70
+ if (manifest !== undefined) {
71
+ Object.assign(manifest, { libraries: libraryArtifacts });
72
+ }
73
+ await fs_1.promises.writeFile(await getManifestFile(), JSON.stringify(manifest, null, 4));
74
+ }
75
+ return await getLinkedContractFactory(contract, libraries);
76
+ }
77
77
  exports.getContractFactory = getContractFactory;
@@ -1,2 +1,2 @@
1
1
  import { UnsignedTransaction } from "ethers";
2
- export declare const createMultiSendTransaction: (safeAddress: string, transactions: UnsignedTransaction[]) => Promise<void>;
2
+ export declare function createMultiSendTransaction(safeAddress: string, transactions: UnsignedTransaction[]): Promise<void>;
@@ -27,7 +27,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.createMultiSendTransaction = void 0;
30
- const chalk_1 = __importDefault(require("chalk"));
31
30
  const hardhat_1 = require("hardhat");
32
31
  const api_kit_1 = __importDefault(require("@safe-global/api-kit"));
33
32
  const protocol_kit_1 = __importStar(require("@safe-global/protocol-kit"));
@@ -38,107 +37,67 @@ var Network;
38
37
  Network[Network["GANACHE"] = 1337] = "GANACHE";
39
38
  Network[Network["HARDHAT"] = 31337] = "HARDHAT";
40
39
  })(Network || (Network = {}));
41
- // Constants
40
+ // constants
42
41
  const URLS = {
43
- "safe_transaction": {
42
+ safe_transaction: {
44
43
  [Network.MAINNET]: "https://safe-transaction-mainnet.safe.global",
45
- [Network.GOERLI]: "https://safe-transaction-goerli.safe.global"
44
+ [Network.GOERLI]: "https://safe-transaction-goerli.safe.global",
46
45
  }
47
46
  };
48
- // Public functions
49
- const createMultiSendTransaction = async (safeAddress, transactions) => {
47
+ // public functions
48
+ async function createMultiSendTransaction(safeAddress, transactions) {
50
49
  const safeTransactionData = [];
51
50
  for (const transaction of transactions) {
52
51
  safeTransactionData.push({
53
- "to": transaction.to
54
- ? transaction.to
55
- : hardhat_1.ethers.constants.AddressZero,
56
- "data": transaction.data
57
- ? transaction.data.toString()
58
- : "0x",
59
- "value": transaction.value
60
- ? transaction.value.toString()
61
- : "0",
62
- "operation": 0
52
+ to: transaction.to ? transaction.to : hardhat_1.ethers.constants.AddressZero,
53
+ data: transaction.data ? transaction.data.toString() : "0x",
54
+ value: transaction.value ? transaction.value.toString() : "0",
55
+ operation: 0,
63
56
  });
64
57
  }
65
- const safeService = await getSafeService();
66
- const nonce = await safeService.getNextNonce(safeAddress);
58
+ const safeService = await getSafeService(), nonce = await safeService.getNextNonce(safeAddress);
67
59
  console.log("Will send tx to Gnosis with nonce", nonce);
68
60
  const options = {
69
- // Max gas to use in the transaction
70
- "safeTxGas": "0",
71
- // Gas costs not related to the transaction execution (signature check, refund payment...)
72
- "baseGas": "0",
73
- // Gas price used for the refund calculation
74
- "gasPrice": "0",
75
- // Token address (hold by the Safe) to be used as a refund to the sender, if `null` is Ether
76
- "gasToken": hardhat_1.ethers.constants.AddressZero,
77
- // Address of receiver of gas payment (or `null` if tx.origin)
78
- "refundReceiver": hardhat_1.ethers.constants.AddressZero,
79
- // Nonce of the Safe, transaction cannot be executed until Safe's nonce is not equal to this nonce
80
- nonce
81
- };
82
- const ethAdapter = await getEthAdapter();
83
- const safeSdk = await protocol_kit_1.default.create({ ethAdapter,
84
- safeAddress });
85
- const safeTransaction = await safeSdk.createTransaction({ safeTransactionData,
86
- options });
87
- await estimateSafeTransaction(safeAddress, safeTransactionData);
61
+ safeTxGas: "0",
62
+ baseGas: "0",
63
+ gasPrice: "0",
64
+ gasToken: hardhat_1.ethers.constants.AddressZero,
65
+ refundReceiver: hardhat_1.ethers.constants.AddressZero,
66
+ nonce: nonce // Nonce of the Safe, transaction cannot be executed until Safe's nonce is not equal to this nonce
67
+ }, ethAdapter = await getEthAdapter(), safeSdk = await protocol_kit_1.default.create({ ethAdapter, safeAddress }), safeTransaction = await safeSdk.createTransaction({ safeTransactionData, options });
88
68
  await proposeTransaction(safeAddress, safeTransaction);
89
- };
69
+ }
90
70
  exports.createMultiSendTransaction = createMultiSendTransaction;
91
- // Private functions
92
- const estimateSafeTransaction = async (safeAddress, safeTransactionData) => {
93
- console.log("Estimate gas");
94
- const safeService = await getSafeService();
95
- for (const transaction of safeTransactionData) {
96
- const estimateResponse = await safeService.estimateSafeTransaction(safeAddress, {
97
- "to": transaction.to,
98
- "value": transaction.value,
99
- "data": transaction.data,
100
- "operation": transaction.operation || 0
101
- });
102
- console.log(chalk_1.default.cyan(`Recommend to set gas limit to ${parseInt(estimateResponse.safeTxGas, 10)}`));
103
- }
104
- console.log(chalk_1.default.green("Send transaction to gnosis safe"));
105
- };
106
- const proposeTransaction = async (safeAddress, safeTransaction) => {
107
- const [safeOwner] = await hardhat_1.ethers.getSigners();
108
- const ethAdapter = await getEthAdapter();
109
- const safeSdk = await protocol_kit_1.default.create({ ethAdapter,
110
- safeAddress });
111
- const safeTxHash = await safeSdk.getTransactionHash(safeTransaction);
112
- const senderSignature = await safeSdk.signTransactionHash(safeTxHash);
113
- const safeService = await getSafeService();
71
+ // private functions
72
+ async function proposeTransaction(safeAddress, safeTransaction) {
73
+ const [safeOwner] = await hardhat_1.ethers.getSigners(), ethAdapter = await getEthAdapter(), safeSdk = await protocol_kit_1.default.create({ ethAdapter, safeAddress }), safeTxHash = await safeSdk.getTransactionHash(safeTransaction), senderSignature = await safeSdk.signTransactionHash(safeTxHash), safeService = await getSafeService();
114
74
  await safeService.proposeTransaction({
115
75
  safeAddress,
116
- "safeTransactionData": safeTransaction.data,
76
+ safeTransactionData: safeTransaction.data,
117
77
  safeTxHash,
118
- "senderAddress": safeOwner.address,
119
- "senderSignature": senderSignature.data
78
+ senderAddress: safeOwner.address,
79
+ senderSignature: senderSignature.data
120
80
  });
121
- };
122
- const getEthAdapter = async () => {
123
- const [safeOwner] = await hardhat_1.ethers.getSigners();
124
- const ethAdapter = new protocol_kit_1.EthersAdapter({
81
+ }
82
+ async function getEthAdapter() {
83
+ const [safeOwner] = await hardhat_1.ethers.getSigners(), ethAdapter = new protocol_kit_1.EthersAdapter({
125
84
  ethers: hardhat_1.ethers,
126
- "signerOrProvider": safeOwner
85
+ signerOrProvider: safeOwner
127
86
  });
128
87
  return ethAdapter;
129
- };
130
- const getSafeService = async () => {
131
- const { chainId } = await hardhat_1.ethers.provider.getNetwork();
132
- const ethAdapter = await getEthAdapter();
133
- const safeService = new api_kit_1.default({
134
- "txServiceUrl": getSafeTransactionUrl(chainId),
88
+ }
89
+ async function getSafeService() {
90
+ const chainId = (await hardhat_1.ethers.provider.getNetwork()).chainId, ethAdapter = await getEthAdapter(), safeService = new api_kit_1.default({
91
+ txServiceUrl: getSafeTransactionUrl(chainId),
135
92
  ethAdapter
136
93
  });
137
94
  return safeService;
138
- };
139
- const getSafeTransactionUrl = (chainId) => {
95
+ }
96
+ function getSafeTransactionUrl(chainId) {
140
97
  if (Object.keys(URLS.safe_transaction).includes(chainId.toString())) {
141
98
  return URLS.safe_transaction[chainId];
142
99
  }
143
- throw Error(`Can't get safe-transaction url at network with chainId = ${chainId}`);
144
- };
100
+ else {
101
+ throw Error(`Can't get safe-transaction url at network with chainId = ${chainId}`);
102
+ }
103
+ }
@@ -1,2 +1,2 @@
1
1
  import { BigNumber } from "ethers";
2
- export declare const encodeTransaction: (operation: 0 | 1, to: string, value: BigNumber | number, data: string) => string;
2
+ export declare function encodeTransaction(operation: 0 | 1, to: string, value: BigNumber | number, data: string): string;
@@ -2,14 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.encodeTransaction = void 0;
4
4
  const ethers_1 = require("ethers");
5
- const padWithZeros = (value, targetLength) => ("0".repeat(targetLength) + value).slice(-targetLength);
6
- const encodeTransaction = (operation, to, value, data) => {
7
- // / operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),
8
- // / to as a address (=> 20 bytes),
9
- // / value as a uint256 (=> 32 bytes),
10
- // / data length as a uint256 (=> 32 bytes),
11
- // / data as bytes.
12
- let _operation = "";
5
+ function padWithZeros(value, targetLength) {
6
+ return ("0".repeat(targetLength) + value).slice(-targetLength);
7
+ }
8
+ function encodeTransaction(operation, to, value, data) {
9
+ /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),
10
+ /// to as a address (=> 20 bytes),
11
+ /// value as a uint256 (=> 32 bytes),
12
+ /// data length as a uint256 (=> 32 bytes),
13
+ /// data as bytes.
14
+ let _operation;
13
15
  if (operation === 0) {
14
16
  _operation = "00";
15
17
  }
@@ -17,29 +19,28 @@ const encodeTransaction = (operation, to, value, data) => {
17
19
  _operation = "01";
18
20
  }
19
21
  else {
20
- throw Error("Operation has an incorrect value");
22
+ throw Error(`Operation has an incorrect value`);
21
23
  }
22
24
  let _to = to;
23
25
  if (to.startsWith("0x")) {
24
26
  _to = _to.slice(2);
25
27
  }
26
28
  _to = padWithZeros(_to, 20 * 2);
27
- const _value = padWithZeros(ethers_1.BigNumber.from(value).toHexString().
28
- slice(2), 32 * 2);
29
+ const _value = padWithZeros(ethers_1.BigNumber.from(value).toHexString().slice(2), 32 * 2);
29
30
  let _data = data;
30
31
  if (data.startsWith("0x")) {
31
32
  _data = _data.slice(2);
32
33
  }
33
34
  if (_data.length % 2 !== 0) {
34
- _data = `0${_data}`;
35
+ _data = "0" + _data;
35
36
  }
36
37
  const _dataLength = padWithZeros((_data.length / 2).toString(16), 32 * 2);
37
- return `0x${[
38
+ return "0x" + [
38
39
  _operation,
39
40
  _to,
40
41
  _value,
41
42
  _dataLength,
42
- _data
43
- ].join("")}`;
44
- };
43
+ _data,
44
+ ].join("");
45
+ }
45
46
  exports.encodeTransaction = encodeTransaction;
@@ -1,12 +1,10 @@
1
1
  import { Transaction } from "ethers";
2
2
  import { Submitter } from "./submitter";
3
3
  export declare class AutoSubmitter extends Submitter {
4
- name: string;
5
4
  submit(transactions: Transaction[]): Promise<void>;
6
- private static getSubmitter;
7
- private static _getImaInstance;
8
- private static _getSafeAddress;
9
- private static _getSchainHash;
10
- private static _getMainnetChainId;
11
- private static _versionFunctionExists;
5
+ _getImaInstance(): Promise<import("@skalenetwork/skale-contracts/lib/instance").Instance<import("ethers").BaseContract>>;
6
+ _getSafeAddress(): string;
7
+ _getSchainHash(): string;
8
+ _getMainnetChainId(): number;
9
+ _versionFunctionExists(): Promise<boolean>;
12
10
  }
@@ -37,83 +37,73 @@ const safe_ima_legacy_marionette_submitter_1 = require("./safe-ima-legacy-marion
37
37
  const marionette_1 = require("./types/marionette");
38
38
  const skale_contracts_ethers_v5_1 = require("@skalenetwork/skale-contracts-ethers-v5");
39
39
  class AutoSubmitter extends submitter_1.Submitter {
40
- constructor() {
41
- super(...arguments);
42
- this.name = "Auto Submitter";
43
- }
44
40
  async submit(transactions) {
45
- console.log(`Submit via ${this.name}`);
46
- const submitter = await AutoSubmitter.getSubmitter();
47
- await submitter.submit(transactions);
48
- }
49
- // Private
50
- static async getSubmitter() {
41
+ let submitter;
51
42
  // TODO: remove unknown when move everything to ethers 6
52
- const proxyAdmin = await (0, admin_1.getManifestAdmin)(hardhat_1.default);
53
- const owner = await proxyAdmin.owner();
43
+ const proxyAdmin = await (0, admin_1.getManifestAdmin)(hardhat_1.default), owner = await proxyAdmin.owner();
54
44
  if (await hardhat_1.default.ethers.provider.getCode(owner) === "0x") {
55
45
  console.log("Owner is not a contract");
56
- return new eoa_submitter_1.EoaSubmitter();
46
+ submitter = new eoa_submitter_1.EoaSubmitter();
57
47
  }
58
- console.log("Owner is a contract");
59
- if (hardhat_1.ethers.utils.getAddress(owner) === hardhat_1.ethers.utils.getAddress(marionette_1.MARIONETTE_ADDRESS)) {
60
- console.log("Marionette owner is detected");
61
- const imaInstance = await AutoSubmitter._getImaInstance();
62
- const mainnetChainId = AutoSubmitter._getMainnetChainId();
63
- const safeAddress = AutoSubmitter._getSafeAddress();
64
- const schainHash = AutoSubmitter._getSchainHash();
65
- /*
66
- * TODO: after marionette has multiSend functionality
67
- * query version and properly select a submitter
68
- * based on it
69
- *
70
- * if (await this._versionFunctionExists()) {
71
- * console.log("version() function was found. Use normal Marionette")
72
- * submitter = new SafeImaMarionetteSubmitter(
73
- * safeAddress,
74
- * imaAbi,
75
- * schainHash,
76
- * mainnetChainId
77
- * )
78
- * } else {
79
- * console.log("No version() function was found. Use legacy Marionette")
80
- * submitter = new SafeImaLegacyMarionetteSubmitter(
81
- * safeAddress,
82
- * imaAbi,
83
- * schainHash,
84
- * mainnetChainId
85
- * )
86
- * }
87
- */
88
- return new safe_ima_legacy_marionette_submitter_1.SafeImaLegacyMarionetteSubmitter(safeAddress, imaInstance, schainHash, mainnetChainId);
48
+ else {
49
+ console.log("Owner is a contract");
50
+ if (hardhat_1.ethers.utils.getAddress(owner) == hardhat_1.ethers.utils.getAddress(marionette_1.MARIONETTE_ADDRESS)) {
51
+ console.log("Marionette owner is detected");
52
+ const imaInstance = await this._getImaInstance(), mainnetChainId = this._getMainnetChainId(), safeAddress = this._getSafeAddress(), schainHash = this._getSchainHash();
53
+ // TODO: after marionette has multiSend functionality
54
+ // query version and properly select a submitter
55
+ // based on it
56
+ //
57
+ // if (await this._versionFunctionExists()) {
58
+ // console.log("version() function was found. Use normal Marionette")
59
+ // submitter = new SafeImaMarionetteSubmitter(
60
+ // safeAddress,
61
+ // imaAbi,
62
+ // schainHash,
63
+ // mainnetChainId
64
+ // )
65
+ // } else {
66
+ // console.log("No version() function was found. Use legacy Marionette")
67
+ // submitter = new SafeImaLegacyMarionetteSubmitter(
68
+ // safeAddress,
69
+ // imaAbi,
70
+ // schainHash,
71
+ // mainnetChainId
72
+ // )
73
+ // }
74
+ submitter = new safe_ima_legacy_marionette_submitter_1.SafeImaLegacyMarionetteSubmitter(safeAddress, imaInstance, schainHash, mainnetChainId);
75
+ }
76
+ else {
77
+ // assuming owner is a Gnosis Safe
78
+ console.log("Using Gnosis Safe");
79
+ submitter = new safe_submitter_1.SafeSubmitter(owner);
80
+ }
89
81
  }
90
- // Assuming owner is a Gnosis Safe
91
- console.log("Using Gnosis Safe");
92
- return new safe_submitter_1.SafeSubmitter(owner);
82
+ await submitter.submit(transactions);
93
83
  }
94
- static async _getImaInstance() {
84
+ // private
85
+ async _getImaInstance() {
95
86
  if (!process.env.IMA) {
96
87
  console.log(chalk_1.default.red("Set target IMA alias to IMA environment variable"));
97
88
  process.exit(1);
98
89
  }
99
- const network = await skale_contracts_ethers_v5_1.skaleContracts.getNetworkByProvider(hardhat_1.ethers.provider);
100
- const ima = await network.getProject("ima");
90
+ const network = await skale_contracts_ethers_v5_1.skaleContracts.getNetworkByProvider(hardhat_1.ethers.provider), ima = await network.getProject("ima");
101
91
  return await ima.getInstance(process.env.IMA);
102
92
  }
103
- static _getSafeAddress() {
93
+ _getSafeAddress() {
104
94
  if (!process.env.SAFE_ADDRESS) {
105
95
  console.log(chalk_1.default.red("Set Gnosis Safe owner address to SAFE_ADDRESS environment variable"));
106
96
  process.exit(1);
107
97
  }
108
98
  return process.env.SAFE_ADDRESS;
109
99
  }
110
- static _getSchainHash() {
111
- // Query Context to get schain hash
100
+ _getSchainHash() {
101
+ // query Context to get schain hash
112
102
  if (!process.env.SCHAIN_HASH) {
113
103
  if (!process.env.SCHAIN_NAME) {
114
104
  console.log(chalk_1.default.red("Set schain name to SCHAIN_NAME environment variable"));
115
105
  console.log(chalk_1.default.red("or schain hash to SCHAIN_HASH environment variable"));
116
- throw Error("Schain is not set");
106
+ process.exit(1);
117
107
  }
118
108
  else {
119
109
  return hardhat_1.ethers.utils.solidityKeccak256(["string"], [process.env.SCHAIN_NAME]);
@@ -123,27 +113,24 @@ class AutoSubmitter extends submitter_1.Submitter {
123
113
  return process.env.SCHAIN_HASH;
124
114
  }
125
115
  }
126
- static _getMainnetChainId() {
116
+ _getMainnetChainId() {
127
117
  if (!process.env.MAINNET_CHAIN_ID) {
128
118
  console.log(chalk_1.default.red("Set chainId of mainnet to MAINNET_CHAIN_ID environment variable"));
129
119
  console.log(chalk_1.default.red("Use 1 for Ethereum mainnet or 5 for Goerli"));
130
- throw Error("Mainnet chainId is not set");
120
+ process.exit(1);
131
121
  }
132
122
  else {
133
123
  return Number.parseInt(process.env.MAINNET_CHAIN_ID);
134
124
  }
135
125
  }
136
- static async _versionFunctionExists() {
126
+ async _versionFunctionExists() {
137
127
  const bytecode = await hardhat_1.default.ethers.provider.getCode(marionette_1.MARIONETTE_ADDRESS);
138
- /*
139
- * If the bytecode doesn't include the function selector version()
140
- * is definitely not present
141
- */
128
+ // If the bytecode doesn't include the function selector version()
129
+ // is definitely not present
142
130
  if (!bytecode.includes(hardhat_1.ethers.utils.id("version()").slice(2, 10))) {
143
131
  return false;
144
132
  }
145
- const marionette = new hardhat_1.ethers.Contract(marionette_1.MARIONETTE_ADDRESS, [
146
- {
133
+ const marionette = new hardhat_1.ethers.Contract(marionette_1.MARIONETTE_ADDRESS, [{
147
134
  "inputs": [],
148
135
  "name": "version",
149
136
  "outputs": [
@@ -155,21 +142,16 @@ class AutoSubmitter extends submitter_1.Submitter {
155
142
  ],
156
143
  "stateMutability": "view",
157
144
  "type": "function"
158
- }
159
- ], hardhat_1.default.ethers.provider);
160
- /*
161
- * If gas estimation doesn't revert then an execution is possible
162
- * given the provided function selector
163
- */
145
+ }], hardhat_1.default.ethers.provider);
146
+ // If gas estimation doesn't revert then an execution is possible
147
+ // given the provided function selector
164
148
  try {
165
149
  await marionette.estimateGas.version();
166
150
  return true;
167
151
  }
168
152
  catch {
169
- /*
170
- * Otherwise (revert) we assume that there is no entry in the jump table
171
- * meaning that the contract doesn't include version()
172
- */
153
+ // Otherwise (revert) we assume that there is no entry in the jump table
154
+ // meaning that the contract doesn't include version()
173
155
  return false;
174
156
  }
175
157
  }
@@ -1,6 +1,5 @@
1
1
  import { UnsignedTransaction } from "ethers";
2
2
  import { Submitter } from "./submitter";
3
3
  export declare class EoaSubmitter extends Submitter {
4
- name: string;
5
4
  submit(transactions: UnsignedTransaction[]): Promise<void>;
6
5
  }
@@ -4,19 +4,15 @@ exports.EoaSubmitter = void 0;
4
4
  const hardhat_1 = require("hardhat");
5
5
  const submitter_1 = require("./submitter");
6
6
  class EoaSubmitter extends submitter_1.Submitter {
7
- constructor() {
8
- super(...arguments);
9
- this.name = "EOA Submitter";
10
- }
11
7
  async submit(transactions) {
12
- EoaSubmitter._atomicityWarning();
8
+ this._atomicityWarning();
13
9
  const [deployer] = await hardhat_1.ethers.getSigners();
14
10
  for (const transaction of transactions) {
15
- console.log(`Send transaction via ${this.name}`);
11
+ console.log("Send transaction");
16
12
  const response = await deployer.sendTransaction({
17
- "to": transaction.to,
18
- "value": transaction.value,
19
- "data": transaction.data
13
+ to: transaction.to,
14
+ value: transaction.value,
15
+ data: transaction.data
20
16
  });
21
17
  console.log(`Waiting for a transaction with nonce ${response.nonce}`);
22
18
  await response.wait();
@@ -41,20 +41,14 @@ class SafeImaLegacyMarionetteSubmitter extends safe_to_ima_submitter_1.SafeToIma
41
41
  }
42
42
  async submit(transactions) {
43
43
  if (transactions.length > 1) {
44
- SafeImaLegacyMarionetteSubmitter._atomicityWarning();
44
+ this._atomicityWarning();
45
45
  }
46
46
  const transactionsToMarionette = [];
47
47
  for (const transaction of transactions) {
48
48
  transactionsToMarionette.push({
49
- "to": this.marionette.address,
49
+ to: this.marionette.address,
50
50
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
51
- "data": await this.marionette.encodeFunctionCall(transaction.to
52
- ? transaction.to
53
- : hardhat_1.ethers.constants.AddressZero, transaction.value
54
- ? transaction.value
55
- : 0, transaction.data
56
- ? transaction.data
57
- : "0x")
51
+ data: await this.marionette.encodeFunctionCall(transaction.to ? transaction.to : hardhat_1.ethers.constants.AddressZero, transaction.value ? transaction.value : 0, transaction.data ? transaction.data : "0x")
58
52
  });
59
53
  }
60
54
  await super.submit(transactionsToMarionette);
@@ -50,21 +50,15 @@ class SafeImaMarionetteSubmitter extends safe_to_ima_submitter_1.SafeToImaSubmit
50
50
  const functionCalls = [];
51
51
  for (const transaction of transactions) {
52
52
  functionCalls.push({
53
- "receiver": transaction.to
54
- ? transaction.to
55
- : hardhat_1.ethers.constants.AddressZero,
56
- "value": transaction.value
57
- ? transaction.value
58
- : 0,
59
- "data": transaction.data
60
- ? transaction.data
61
- : "0x"
53
+ receiver: transaction.to ? transaction.to : hardhat_1.ethers.constants.AddressZero,
54
+ value: transaction.value ? transaction.value : 0,
55
+ data: (transaction.data ? transaction.data : "0x")
62
56
  });
63
57
  }
64
58
  await super.submit([
65
59
  {
66
- "to": this.marionette.address,
67
- "data": await this.marionette.encodeFunctionCalls(functionCalls)
60
+ to: this.marionette.address,
61
+ data: await this.marionette.encodeFunctionCalls(functionCalls)
68
62
  }
69
63
  ]);
70
64
  }
@@ -10,17 +10,14 @@ class SafeToImaSubmitter extends safe_submitter_1.SafeSubmitter {
10
10
  }
11
11
  async submit(transactions) {
12
12
  if (transactions.length > 1) {
13
- SafeToImaSubmitter._atomicityWarning();
13
+ this._atomicityWarning();
14
14
  }
15
- const messageProxyForMainnet = await this._getMessageProxyForMainnet();
16
- const transactionsToIma = transactions.map((transaction) => ({
17
- "to": messageProxyForMainnet.address,
18
- "data": messageProxyForMainnet.interface.encodeFunctionData("postOutgoingMessage", [
19
- this.targetSchainHash,
20
- transaction.to,
21
- transaction.data
22
- ])
23
- }));
15
+ const messageProxyForMainnet = await this._getMessageProxyForMainnet(), transactionsToIma = transactions.map((transaction) => {
16
+ return {
17
+ to: messageProxyForMainnet.address,
18
+ data: messageProxyForMainnet.interface.encodeFunctionData("postOutgoingMessage", [this.targetSchainHash, transaction.to, transaction.data])
19
+ };
20
+ });
24
21
  await super.submit(transactionsToIma);
25
22
  }
26
23
  async _getMessageProxyForMainnet() {
@@ -1,5 +1,5 @@
1
1
  import { UnsignedTransaction } from "ethers";
2
2
  export declare abstract class Submitter {
3
3
  abstract submit(transactions: UnsignedTransaction[]): Promise<void>;
4
- protected static _atomicityWarning(): void;
4
+ _atomicityWarning(): void;
5
5
  }
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Submitter = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  class Submitter {
9
- // Protected
10
- static _atomicityWarning() {
9
+ // private
10
+ _atomicityWarning() {
11
11
  if (!process.env.ALLOW_NOT_ATOMIC_UPGRADE) {
12
12
  console.log(chalk_1.default.red("The upgrade will consist of multiple transactions and will not be atomic"));
13
13
  console.log(chalk_1.default.red("If not atomic upgrade is OK set ALLOW_NOT_ATOMIC_UPGRADE environment variable"));
@@ -1,6 +1,6 @@
1
1
  import { ManifestData } from "@openzeppelin/upgrades-core";
2
2
  export interface SkaleManifestData extends ManifestData {
3
- libraries?: {
3
+ libraries: {
4
4
  [libraryName: string]: {
5
5
  address: string;
6
6
  bytecodeHash: string;
@@ -11,8 +11,8 @@ export declare abstract class Upgrader {
11
11
  constructor(projectName: string, targetVersion: string, instance: Instance, contractNamesToUpgrade: string[], submitter?: Submitter);
12
12
  abstract getDeployedVersion: () => Promise<string | undefined>;
13
13
  abstract setVersion: (newVersion: string) => Promise<void>;
14
- deployNewContracts?: () => Promise<void>;
15
- initialize?: () => Promise<void>;
14
+ deployNewContracts: () => Promise<void>;
15
+ initialize: () => Promise<void>;
16
16
  upgrade(): Promise<void>;
17
- private static _getContractFactoryAndUpdateManifest;
17
+ _getContractFactoryAndUpdateManifest(contract: string): Promise<import("ethers").ContractFactory>;
18
18
  }
@@ -16,9 +16,12 @@ const verification_1 = require("./verification");
16
16
  const auto_submitter_1 = require("./submitters/auto-submitter");
17
17
  class Upgrader {
18
18
  constructor(projectName, targetVersion, instance, contractNamesToUpgrade, submitter = new auto_submitter_1.AutoSubmitter()) {
19
+ // protected
20
+ this.deployNewContracts = () => { return Promise.resolve(); };
21
+ this.initialize = () => { return Promise.resolve(); };
19
22
  this.targetVersion = targetVersion;
20
- if (!targetVersion.includes("-")) {
21
- this.targetVersion = `${targetVersion}-stable.0`;
23
+ if (!targetVersion.includes('-')) {
24
+ this.targetVersion = targetVersion + '-stable.0';
22
25
  }
23
26
  this.instance = instance;
24
27
  this.contractNamesToUpgrade = contractNamesToUpgrade;
@@ -26,14 +29,14 @@ class Upgrader {
26
29
  this.transactions = [];
27
30
  this.submitter = submitter;
28
31
  }
29
- // Public
32
+ // public
30
33
  async upgrade() {
31
34
  const proxyAdmin = await (0, admin_1.getManifestAdmin)(hardhat_1.default);
32
35
  let deployedVersion = await this.getDeployedVersion();
33
36
  const version = await (0, version_1.getVersion)();
34
37
  if (deployedVersion) {
35
- if (!deployedVersion.includes("-")) {
36
- deployedVersion += "-stable.0";
38
+ if (!deployedVersion.includes('-')) {
39
+ deployedVersion = deployedVersion + '-stable.0';
37
40
  }
38
41
  if (deployedVersion !== this.targetVersion) {
39
42
  console.log(chalk_1.default.red(`This script can't upgrade version ${deployedVersion} to ${version}`));
@@ -44,26 +47,22 @@ class Upgrader {
44
47
  console.log(chalk_1.default.yellow(`Can't check currently deployed version of ${this.projectName}`));
45
48
  }
46
49
  console.log(`Will mark updated version as ${version}`);
47
- if (this.deployNewContracts !== undefined) {
48
- // Deploy new contracts
49
- await this.deployNewContracts();
50
- }
50
+ // Deploy new contracts
51
+ await this.deployNewContracts();
51
52
  // Deploy new implementations
52
53
  const contractsToUpgrade = [];
53
54
  for (const contract of this.contractNamesToUpgrade) {
54
- const contractFactory = await Upgrader._getContractFactoryAndUpdateManifest(contract);
55
- const proxyAddress = (await this.instance.getContract(contract)).address;
55
+ const contractFactory = await this._getContractFactoryAndUpdateManifest(contract), proxyAddress = (await this.instance.getContract(contract)).address;
56
56
  console.log(`Prepare upgrade of ${contract}`);
57
- const currentImplementationAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_2.network.provider, proxyAddress);
58
- const newImplementationAddress = await hardhat_2.upgrades.prepareUpgrade(proxyAddress, contractFactory, {
59
- "unsafeAllowLinkedLibraries": true,
60
- "unsafeAllowRenames": true
57
+ const currentImplementationAddress = await (0, upgrades_core_1.getImplementationAddress)(hardhat_2.network.provider, proxyAddress), newImplementationAddress = await hardhat_2.upgrades.prepareUpgrade(proxyAddress, contractFactory, {
58
+ unsafeAllowLinkedLibraries: true,
59
+ unsafeAllowRenames: true
61
60
  });
62
61
  if (newImplementationAddress !== currentImplementationAddress) {
63
62
  contractsToUpgrade.push({
64
63
  proxyAddress,
65
- "implementationAddress": newImplementationAddress,
66
- "name": contract
64
+ implementationAddress: newImplementationAddress,
65
+ name: contract
67
66
  });
68
67
  }
69
68
  else {
@@ -74,17 +73,12 @@ class Upgrader {
74
73
  for (const contract of contractsToUpgrade) {
75
74
  console.log(chalk_1.default.yellowBright(`Prepare transaction to upgrade ${contract.name} at ${contract.proxyAddress} to ${contract.implementationAddress}`));
76
75
  this.transactions.push({
77
- "to": proxyAdmin.address,
78
- "data": proxyAdmin.interface.encodeFunctionData("upgrade", [
79
- contract.proxyAddress,
80
- contract.implementationAddress
81
- ])
76
+ to: proxyAdmin.address,
77
+ data: proxyAdmin.interface.encodeFunctionData("upgrade", [contract.proxyAddress, contract.implementationAddress])
82
78
  });
83
79
  }
84
- if (this.initialize !== undefined) {
85
- await this.initialize();
86
- }
87
- // Write version
80
+ await this.initialize();
81
+ // write version
88
82
  await this.setVersion(version);
89
83
  await fs_1.promises.writeFile(`data/transactions-${version}-${hardhat_2.network.name}.json`, JSON.stringify(this.transactions, null, 4));
90
84
  await this.submitter.submit(this.transactions);
@@ -99,21 +93,17 @@ class Upgrader {
99
93
  }
100
94
  console.log("Done");
101
95
  }
102
- // Private
103
- static async _getContractFactoryAndUpdateManifest(contract) {
104
- const { linkReferences } = await hardhat_2.artifacts.readArtifact(contract);
105
- const manifest = JSON.parse(await fs_1.promises.readFile(await (0, deploy_1.getManifestFile)(), "utf-8"));
106
- if (!Object.keys(linkReferences).length) {
96
+ // private
97
+ async _getContractFactoryAndUpdateManifest(contract) {
98
+ const { linkReferences } = await hardhat_2.artifacts.readArtifact(contract), manifest = JSON.parse(await fs_1.promises.readFile(await (0, deploy_1.getManifestFile)(), "utf-8"));
99
+ if (!Object.keys(linkReferences).length)
107
100
  return await hardhat_2.ethers.getContractFactory(contract);
108
- }
109
- const librariesToUpgrade = [];
110
- const oldLibraries = {};
101
+ const librariesToUpgrade = [], oldLibraries = {};
111
102
  if (manifest.libraries === undefined) {
112
- manifest.libraries = {};
103
+ Object.assign(manifest, { libraries: {} });
113
104
  }
114
105
  for (const key of Object.keys(linkReferences)) {
115
- const libraryName = Object.keys(linkReferences[key])[0];
116
- const { bytecode } = await hardhat_2.artifacts.readArtifact(libraryName);
106
+ const libraryName = Object.keys(linkReferences[key])[0], { bytecode } = await hardhat_2.artifacts.readArtifact(libraryName);
117
107
  if (manifest.libraries[libraryName] === undefined) {
118
108
  librariesToUpgrade.push(libraryName);
119
109
  continue;
@@ -129,8 +119,7 @@ class Upgrader {
129
119
  const libraries = await (0, deploy_1.deployLibraries)(librariesToUpgrade);
130
120
  for (const [libraryName, libraryAddress] of libraries.entries()) {
131
121
  const { bytecode } = await hardhat_2.artifacts.readArtifact(libraryName);
132
- manifest.libraries[libraryName] = { "address": libraryAddress,
133
- "bytecodeHash": (0, upgrades_core_1.hashBytecode)(bytecode) };
122
+ manifest.libraries[libraryName] = { "address": libraryAddress, "bytecodeHash": (0, upgrades_core_1.hashBytecode)(bytecode) };
134
123
  }
135
124
  Object.assign(libraries, oldLibraries);
136
125
  await fs_1.promises.writeFile(await (0, deploy_1.getManifestFile)(), JSON.stringify(manifest, null, 4));
@@ -1,2 +1,2 @@
1
- export declare const verify: (contractName: string, contractAddress: string, constructorArguments: object) => Promise<void>;
2
- export declare const verifyProxy: (contractName: string, proxyAddress: string, constructorArguments: object) => Promise<void>;
1
+ export declare function verify(contractName: string, contractAddress: string, constructorArguments: object): Promise<void>;
2
+ export declare function verifyProxy(contractName: string, proxyAddress: string, constructorArguments: object): Promise<void>;
@@ -8,35 +8,35 @@ const hardhat_1 = require("hardhat");
8
8
  const chain_config_1 = require("@nomicfoundation/hardhat-verify/internal/chain-config");
9
9
  const chalk_1 = __importDefault(require("chalk"));
10
10
  const upgrades_core_1 = require("@openzeppelin/upgrades-core");
11
- const verify = async (contractName, contractAddress, constructorArguments) => {
12
- const { chainId } = await hardhat_1.ethers.provider.getNetwork();
13
- if (chain_config_1.builtinChains.find((chain) => chain.chainId === chainId) !== undefined) {
14
- for (let retry = 0; retry <= 5; retry += 1) {
11
+ async function verify(contractName, contractAddress, constructorArguments) {
12
+ const chainId = (await hardhat_1.ethers.provider.getNetwork()).chainId;
13
+ if (chain_config_1.builtinChains.find(chain => chain.chainId === chainId) !== undefined) {
14
+ for (let retry = 0; retry <= 5; ++retry) {
15
15
  try {
16
16
  await (0, hardhat_1.run)("verify:verify", {
17
- "address": contractAddress,
17
+ address: contractAddress,
18
18
  constructorArguments
19
19
  });
20
20
  break;
21
21
  }
22
- catch (error) {
23
- if (error instanceof Error) {
24
- if (error.toString().includes("Contract source code already verified")) {
22
+ catch (e) {
23
+ if (e instanceof Error) {
24
+ if (e.toString().includes("Contract source code already verified")) {
25
25
  console.log(chalk_1.default.grey(`${contractName} is already verified`));
26
26
  return;
27
27
  }
28
28
  console.log(chalk_1.default.red(`Contract ${contractName} was not verified on etherscan`));
29
- console.log(error.toString());
29
+ console.log(e.toString());
30
30
  }
31
31
  else {
32
- console.log("Unknown exception type:", error);
32
+ console.log("Unknown exception type:", e);
33
33
  }
34
34
  }
35
35
  }
36
36
  }
37
- };
37
+ }
38
38
  exports.verify = verify;
39
- const verifyProxy = async (contractName, proxyAddress, constructorArguments) => {
40
- await (0, exports.verify)(contractName, await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.network.provider, proxyAddress), constructorArguments);
41
- };
39
+ async function verifyProxy(contractName, proxyAddress, constructorArguments) {
40
+ await verify(contractName, await (0, upgrades_core_1.getImplementationAddress)(hardhat_1.network.provider, proxyAddress), constructorArguments);
41
+ }
42
42
  exports.verifyProxy = verifyProxy;
@@ -10,25 +10,21 @@ const util_1 = __importDefault(require("util"));
10
10
  const exec = util_1.default.promisify(child_process_1.exec);
11
11
  class VersionNotFound extends Error {
12
12
  }
13
- const getVersionFilename = async (folder) => {
13
+ async function getVersionFilename(folder) {
14
14
  if (folder === undefined) {
15
15
  return getVersionFilename((await exec("git rev-parse --show-toplevel")).stdout.trim());
16
16
  }
17
- const VERSION_FILENAME = "VERSION";
18
- const path = `${folder}/${VERSION_FILENAME}`;
17
+ const VERSION_FILENAME = 'VERSION', path = `${folder}/${VERSION_FILENAME}`;
19
18
  if ((0, fs_1.existsSync)(path)) {
20
19
  return path;
21
20
  }
22
- for (const entry of await fs_1.promises.readdir(folder, {
23
- "withFileTypes": true,
24
- "recursive": true
25
- })) {
21
+ for (const entry of await fs_1.promises.readdir(folder, { withFileTypes: true, recursive: true })) {
26
22
  if (entry.isFile() && entry.name === VERSION_FILENAME) {
27
23
  return `${entry.path}/${entry.name}`;
28
24
  }
29
25
  }
30
26
  throw new VersionNotFound("Can't find version file");
31
- };
27
+ }
32
28
  const getVersion = async () => {
33
29
  if (process.env.VERSION) {
34
30
  return process.env.VERSION;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skalenetwork/upgrade-tools",
3
- "version": "3.0.0-linter.9",
3
+ "version": "3.0.0-merge-stable.1",
4
4
  "description": "Scripts to support upgrades of smart contracts",
5
5
  "files": [
6
6
  "dist/**/*"
@@ -52,6 +52,6 @@
52
52
  "@openzeppelin/upgrades-core": "^1.27.1",
53
53
  "@types/mocha": "^9.1.0",
54
54
  "ethers": "^5.7.2",
55
- "hardhat": "2.8.3 - 2.16.1"
55
+ "hardhat": "^2.16.1"
56
56
  }
57
57
  }