@openzeppelin/upgrades-core 1.9.2 → 1.12.0
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.
- package/LICENSE +22 -0
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json +80 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json +113 -0
- package/artifacts/AdminUpgradeabilityProxy.json +2 -2
- package/artifacts/contracts/proxy/AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json +2 -2
- package/dist/beacon.d.ts +8 -0
- package/dist/beacon.d.ts.map +1 -0
- package/dist/beacon.js +25 -0
- package/dist/beacon.js.map +1 -0
- package/dist/deployment.d.ts +14 -3
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +20 -13
- package/dist/deployment.js.map +1 -1
- package/dist/deployment.test.js +23 -0
- package/dist/deployment.test.js.map +1 -1
- package/dist/eip-1967-type.d.ts +4 -0
- package/dist/eip-1967-type.d.ts.map +1 -0
- package/dist/eip-1967-type.js +37 -0
- package/dist/eip-1967-type.js.map +1 -0
- package/dist/eip-1967.d.ts +5 -0
- package/dist/eip-1967.d.ts.map +1 -1
- package/dist/eip-1967.js +19 -12
- package/dist/eip-1967.js.map +1 -1
- package/dist/impl-address.d.ts +19 -0
- package/dist/impl-address.d.ts.map +1 -0
- package/dist/impl-address.js +67 -0
- package/dist/impl-address.js.map +1 -0
- package/dist/impl-store.d.ts +3 -2
- package/dist/impl-store.d.ts.map +1 -1
- package/dist/impl-store.js +21 -10
- package/dist/impl-store.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/provider.d.ts +2 -0
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +11 -1
- package/dist/provider.js.map +1 -1
- package/dist/proxy-kind.d.ts +12 -0
- package/dist/proxy-kind.d.ts.map +1 -0
- package/dist/proxy-kind.js +50 -0
- package/dist/proxy-kind.js.map +1 -0
- package/dist/standalone.d.ts +19 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +24 -0
- package/dist/standalone.js.map +1 -0
- package/dist/standalone.test.d.ts +2 -0
- package/dist/standalone.test.d.ts.map +1 -0
- package/dist/standalone.test.js +33 -0
- package/dist/standalone.test.js.map +1 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +11 -5
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/report.d.ts +3 -2
- package/dist/storage/report.d.ts.map +1 -1
- package/dist/storage/report.js +9 -3
- package/dist/storage/report.js.map +1 -1
- package/dist/usage-error.d.ts +21 -0
- package/dist/usage-error.d.ts.map +1 -0
- package/dist/usage-error.js +51 -0
- package/dist/usage-error.js.map +1 -0
- package/dist/utils/address.d.ts +8 -0
- package/dist/utils/address.d.ts.map +1 -0
- package/dist/utils/address.js +20 -0
- package/dist/utils/address.js.map +1 -0
- package/dist/utils/make-non-enumerable.d.ts +1 -1
- package/dist/utils/make-non-enumerable.d.ts.map +1 -1
- package/dist/utils/make-non-enumerable.js.map +1 -1
- package/dist/validate/error.d.ts.map +1 -1
- package/dist/validate/error.js +2 -65
- package/dist/validate/error.js.map +1 -1
- package/dist/validate/index.d.ts +2 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +4 -1
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/overrides.js +1 -1
- package/dist/validate/overrides.js.map +1 -1
- package/dist/validate/query.d.ts +3 -1
- package/dist/validate/query.d.ts.map +1 -1
- package/dist/validate/query.js +23 -7
- package/dist/validate/query.js.map +1 -1
- package/dist/validate/report.d.ts +8 -0
- package/dist/validate/report.d.ts.map +1 -0
- package/dist/validate/report.js +79 -0
- package/dist/validate/report.js.map +1 -0
- package/dist/version.d.ts +3 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +12 -6
- package/dist/version.js.map +1 -1
- package/package.json +8 -5
- package/src/beacon.ts +20 -0
- package/src/deployment.test.ts +25 -0
- package/src/deployment.ts +43 -13
- package/src/eip-1967-type.ts +35 -0
- package/src/eip-1967.ts +16 -12
- package/src/impl-address.ts +76 -0
- package/src/impl-store.ts +23 -7
- package/src/index.ts +18 -1
- package/src/manifest.ts +1 -1
- package/src/provider.ts +16 -0
- package/src/proxy-kind.ts +59 -0
- package/src/standalone.test.ts +40 -0
- package/src/standalone.ts +41 -0
- package/src/storage/index.ts +14 -4
- package/src/storage/report.ts +10 -5
- package/src/usage-error.ts +68 -0
- package/src/utils/address.ts +16 -0
- package/src/utils/make-non-enumerable.ts +1 -1
- package/src/validate/error.ts +5 -67
- package/src/validate/index.ts +2 -0
- package/src/validate/overrides.ts +1 -1
- package/src/validate/query.ts +24 -6
- package/src/validate/report.ts +78 -0
- package/src/version.ts +14 -6
- package/CHANGELOG.md +0 -114
- package/dist/set-proxy-kind.d.ts +0 -5
- package/dist/set-proxy-kind.d.ts.map +0 -1
- package/dist/set-proxy-kind.js +0 -25
- package/dist/set-proxy-kind.js.map +0 -1
- package/src/set-proxy-kind.ts +0 -27
package/dist/validate/query.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isUpgradeSafe = exports.getErrors = exports.getUnlinkedBytecode = exports.findVersionWithoutMetadataMatches = exports.unfoldStorageLayout = exports.getStorageLayout = exports.getContractNameAndRunValidation = exports.getContractVersion = exports.assertUpgradeSafe = void 0;
|
|
3
|
+
exports.inferProxyKind = exports.isUpgradeSafe = exports.getErrors = exports.getUnlinkedBytecode = exports.findVersionWithoutMetadataMatches = exports.unfoldStorageLayout = exports.getStorageLayout = exports.getContractNameAndRunValidation = exports.getContractVersion = exports.assertUpgradeSafe = void 0;
|
|
4
4
|
const version_1 = require("../version");
|
|
5
5
|
const link_refs_1 = require("../link-refs");
|
|
6
6
|
const overrides_1 = require("./overrides");
|
|
7
7
|
const error_1 = require("./error");
|
|
8
8
|
const data_1 = require("./data");
|
|
9
|
+
const upgradeToSignature = 'upgradeTo(address)';
|
|
9
10
|
function assertUpgradeSafe(data, version, opts) {
|
|
10
11
|
const dataV3 = (0, data_1.normalizeValidationData)(data);
|
|
11
12
|
const [contractName] = getContractNameAndRunValidation(dataV3, version);
|
|
12
|
-
|
|
13
|
-
errors = (0, overrides_1.processExceptions)(contractName, errors, opts);
|
|
13
|
+
const errors = getErrors(dataV3, version, opts);
|
|
14
14
|
if (errors.length > 0) {
|
|
15
15
|
throw new error_1.ValidationErrors(contractName, errors);
|
|
16
16
|
}
|
|
@@ -86,21 +86,25 @@ function getUnlinkedBytecode(data, bytecode) {
|
|
|
86
86
|
return bytecode;
|
|
87
87
|
}
|
|
88
88
|
exports.getUnlinkedBytecode = getUnlinkedBytecode;
|
|
89
|
-
function getErrors(data, version) {
|
|
89
|
+
function getErrors(data, version, opts = {}) {
|
|
90
90
|
const dataV3 = (0, data_1.normalizeValidationData)(data);
|
|
91
91
|
const [contractName, runValidation] = getContractNameAndRunValidation(dataV3, version);
|
|
92
92
|
const c = runValidation[contractName];
|
|
93
93
|
const errors = getUsedContractsAndLibraries(contractName, runValidation).flatMap(name => runValidation[name].errors);
|
|
94
|
-
const selfAndInheritedMethods =
|
|
95
|
-
if (!selfAndInheritedMethods.includes(
|
|
94
|
+
const selfAndInheritedMethods = getAllMethods(runValidation, contractName);
|
|
95
|
+
if (!selfAndInheritedMethods.includes(upgradeToSignature)) {
|
|
96
96
|
errors.push({
|
|
97
97
|
src: c.src,
|
|
98
98
|
kind: 'missing-public-upgradeto',
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
|
-
return errors;
|
|
101
|
+
return (0, overrides_1.processExceptions)(contractName, errors, opts);
|
|
102
102
|
}
|
|
103
103
|
exports.getErrors = getErrors;
|
|
104
|
+
function getAllMethods(runValidation, contractName) {
|
|
105
|
+
const c = runValidation[contractName];
|
|
106
|
+
return c.methods.concat(...c.inherit.map(name => runValidation[name].methods));
|
|
107
|
+
}
|
|
104
108
|
function getUsedContractsAndLibraries(contractName, runValidation) {
|
|
105
109
|
const c = runValidation[contractName];
|
|
106
110
|
// Add current contract and all of its parents
|
|
@@ -118,4 +122,16 @@ function isUpgradeSafe(data, version) {
|
|
|
118
122
|
return getErrors(dataV3, version).length == 0;
|
|
119
123
|
}
|
|
120
124
|
exports.isUpgradeSafe = isUpgradeSafe;
|
|
125
|
+
function inferProxyKind(data, version) {
|
|
126
|
+
const dataV3 = (0, data_1.normalizeValidationData)(data);
|
|
127
|
+
const [contractName, runValidation] = getContractNameAndRunValidation(dataV3, version);
|
|
128
|
+
const methods = getAllMethods(runValidation, contractName);
|
|
129
|
+
if (methods.includes(upgradeToSignature)) {
|
|
130
|
+
return 'uups';
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
return 'transparent';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.inferProxyKind = inferProxyKind;
|
|
121
137
|
//# sourceMappingURL=query.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/validate/query.ts"],"names":[],"mappings":";;;AAAA,wCAAiD;AAGjD,4CAA8C;AAC9C,2CAAmE;AACnE,mCAA2C;AAC3C,iCAAiE;
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/validate/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ValidationError } from './run';
|
|
2
|
+
export declare class UpgradeableContractErrorReport {
|
|
3
|
+
readonly errors: ValidationError[];
|
|
4
|
+
constructor(errors: ValidationError[]);
|
|
5
|
+
get ok(): boolean;
|
|
6
|
+
explain(color?: boolean): string;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/validate/report.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAExC,qBAAa,8BAA8B;IAC7B,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE;gBAAzB,MAAM,EAAE,eAAe,EAAE;IAE9C,IAAI,EAAE,IAAI,OAAO,CAEhB;IAED,OAAO,CAAC,KAAK,UAAO,GAAG,MAAM;CAG9B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UpgradeableContractErrorReport = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
class UpgradeableContractErrorReport {
|
|
9
|
+
constructor(errors) {
|
|
10
|
+
this.errors = errors;
|
|
11
|
+
}
|
|
12
|
+
get ok() {
|
|
13
|
+
return this.errors.length === 0;
|
|
14
|
+
}
|
|
15
|
+
explain(color = true) {
|
|
16
|
+
return this.errors.map(e => describeError(e, color)).join('\n\n');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.UpgradeableContractErrorReport = UpgradeableContractErrorReport;
|
|
20
|
+
const errorInfo = {
|
|
21
|
+
constructor: {
|
|
22
|
+
msg: e => `Contract \`${e.contract}\` has a constructor`,
|
|
23
|
+
hint: () => 'Define an initializer instead',
|
|
24
|
+
link: 'https://zpl.in/upgrades/error-001',
|
|
25
|
+
},
|
|
26
|
+
delegatecall: {
|
|
27
|
+
msg: () => `Use of delegatecall is not allowed`,
|
|
28
|
+
link: 'https://zpl.in/upgrades/error-002',
|
|
29
|
+
},
|
|
30
|
+
selfdestruct: {
|
|
31
|
+
msg: () => `Use of selfdestruct is not allowed`,
|
|
32
|
+
link: 'https://zpl.in/upgrades/error-003',
|
|
33
|
+
},
|
|
34
|
+
'state-variable-assignment': {
|
|
35
|
+
msg: e => `Variable \`${e.name}\` is assigned an initial value`,
|
|
36
|
+
hint: () => 'Move the assignment to the initializer',
|
|
37
|
+
link: 'https://zpl.in/upgrades/error-004',
|
|
38
|
+
},
|
|
39
|
+
'state-variable-immutable': {
|
|
40
|
+
msg: e => `Variable \`${e.name}\` is immutable`,
|
|
41
|
+
hint: () => `Use a constant or mutable variable instead`,
|
|
42
|
+
link: 'https://zpl.in/upgrades/error-005',
|
|
43
|
+
},
|
|
44
|
+
'external-library-linking': {
|
|
45
|
+
msg: e => `Linking external libraries like \`${e.name}\` is not yet supported`,
|
|
46
|
+
hint: () => `Use libraries with internal functions only, or skip this check with the \`unsafeAllowLinkedLibraries\` flag \n` +
|
|
47
|
+
` if you have manually checked that the libraries are upgrade safe`,
|
|
48
|
+
link: 'https://zpl.in/upgrades/error-006',
|
|
49
|
+
},
|
|
50
|
+
'struct-definition': {
|
|
51
|
+
msg: e => `Structs like \`${e.name}\` are supported in the latest version of the plugin`,
|
|
52
|
+
hint: () => `Update your dependency and run again`,
|
|
53
|
+
},
|
|
54
|
+
'enum-definition': {
|
|
55
|
+
msg: e => `Enums like \`${e.name}\` are supported in the latest version of the plugin`,
|
|
56
|
+
hint: () => `Update your dependency and run again`,
|
|
57
|
+
},
|
|
58
|
+
'missing-public-upgradeto': {
|
|
59
|
+
msg: () => `Implementation is missing a public \`upgradeTo(address)\` function`,
|
|
60
|
+
hint: () => `Inherit UUPSUpgradeable to include this function in your contract\n` +
|
|
61
|
+
` @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol`,
|
|
62
|
+
link: 'https://zpl.in/upgrades/error-008',
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
function describeError(e, color = true) {
|
|
66
|
+
var _a;
|
|
67
|
+
const chalk = new chalk_1.default.Instance({ level: color && chalk_1.default.supportsColor ? chalk_1.default.supportsColor.level : 0 });
|
|
68
|
+
const info = errorInfo[e.kind];
|
|
69
|
+
const log = [chalk.bold(e.src) + ': ' + info.msg(e)];
|
|
70
|
+
const hint = (_a = info.hint) === null || _a === void 0 ? void 0 : _a.call(info, e);
|
|
71
|
+
if (hint) {
|
|
72
|
+
log.push(hint);
|
|
73
|
+
}
|
|
74
|
+
if (info.link) {
|
|
75
|
+
log.push(chalk.dim(info.link));
|
|
76
|
+
}
|
|
77
|
+
return log.join('\n ');
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/validate/report.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface Version {
|
|
|
3
3
|
withoutMetadata: string;
|
|
4
4
|
linkedWithoutMetadata: string;
|
|
5
5
|
}
|
|
6
|
-
export declare function getVersion(bytecode: string, linkedBytecode?: string): Version;
|
|
7
|
-
export declare function hashBytecode(bytecode: string): string;
|
|
8
|
-
export declare function hashBytecodeWithoutMetadata(bytecode: string): string;
|
|
6
|
+
export declare function getVersion(bytecode: string, linkedBytecode?: string, constructorArgs?: string): Version;
|
|
7
|
+
export declare function hashBytecode(bytecode: string, constructorArgs?: string): string;
|
|
8
|
+
export declare function hashBytecodeWithoutMetadata(bytecode: string, constructorArgs?: string): string;
|
|
9
9
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,eAAe,SAAK,GAAG,OAAO,CAUnG;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,SAAK,GAAG,MAAM,CAsB3E;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,SAAK,GAAG,MAAM,CAE1F"}
|
package/dist/version.js
CHANGED
|
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.hashBytecodeWithoutMetadata = exports.hashBytecode = exports.getVersion = void 0;
|
|
7
7
|
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
8
8
|
const cbor_1 = __importDefault(require("cbor"));
|
|
9
|
-
function getVersion(bytecode, linkedBytecode) {
|
|
9
|
+
function getVersion(bytecode, linkedBytecode, constructorArgs = '') {
|
|
10
10
|
if (bytecode !== '') {
|
|
11
11
|
return {
|
|
12
12
|
withMetadata: hashBytecode(bytecode),
|
|
13
13
|
withoutMetadata: hashBytecodeWithoutMetadata(bytecode),
|
|
14
|
-
linkedWithoutMetadata: hashBytecodeWithoutMetadata(linkedBytecode !== null && linkedBytecode !== void 0 ? linkedBytecode : bytecode),
|
|
14
|
+
linkedWithoutMetadata: hashBytecodeWithoutMetadata(linkedBytecode !== null && linkedBytecode !== void 0 ? linkedBytecode : bytecode, constructorArgs),
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
else {
|
|
@@ -19,7 +19,7 @@ function getVersion(bytecode, linkedBytecode) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.getVersion = getVersion;
|
|
22
|
-
function hashBytecode(bytecode) {
|
|
22
|
+
function hashBytecode(bytecode, constructorArgs = '') {
|
|
23
23
|
bytecode = bytecode
|
|
24
24
|
.replace(/__\$([0-9a-fA-F]{34})\$__/g, (_, placeholder) => `000${placeholder}000`)
|
|
25
25
|
.replace(/__\w{36}__/g, placeholder => (0, ethereumjs_util_1.keccak256)(Buffer.from(placeholder)).toString('hex', 0, 20));
|
|
@@ -29,12 +29,18 @@ function hashBytecode(bytecode) {
|
|
|
29
29
|
if (!/^(0x)?[0-9a-fA-F]*$/.test(bytecode)) {
|
|
30
30
|
throw new Error('Bytecode is not a valid hex string');
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
if (!/^(0x)?[0-9a-fA-F]*$/.test(constructorArgs)) {
|
|
33
|
+
throw new Error('Constructor arguments are not a valid hex string');
|
|
34
|
+
}
|
|
35
|
+
const buf = Buffer.concat([
|
|
36
|
+
Buffer.from(bytecode.replace(/^0x/, ''), 'hex'),
|
|
37
|
+
Buffer.from(constructorArgs.replace(/^0x/, ''), 'hex'),
|
|
38
|
+
]);
|
|
33
39
|
return (0, ethereumjs_util_1.keccak256)(buf).toString('hex');
|
|
34
40
|
}
|
|
35
41
|
exports.hashBytecode = hashBytecode;
|
|
36
|
-
function hashBytecodeWithoutMetadata(bytecode) {
|
|
37
|
-
return hashBytecode(trimBytecodeMetadata(bytecode));
|
|
42
|
+
function hashBytecodeWithoutMetadata(bytecode, constructorArgs = '') {
|
|
43
|
+
return hashBytecode(trimBytecodeMetadata(bytecode), constructorArgs);
|
|
38
44
|
}
|
|
39
45
|
exports.hashBytecodeWithoutMetadata = hashBytecodeWithoutMetadata;
|
|
40
46
|
function trimBytecodeMetadata(bytecode) {
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;;;;AAAA,qDAA4C;AAC5C,gDAAwB;AAQxB,SAAgB,UAAU,CAAC,QAAgB,EAAE,cAAuB;
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/upgrades-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"/artifacts/contracts/proxy/AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json",
|
|
14
14
|
"/artifacts/contracts/proxy/ProxyAdmin.sol/ProxyAdmin.json",
|
|
15
15
|
"/contracts/Initializable.sol",
|
|
16
|
+
"/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol",
|
|
17
|
+
"/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol",
|
|
16
18
|
"/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol",
|
|
17
19
|
"/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json ",
|
|
18
20
|
"/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"
|
|
@@ -30,7 +32,7 @@
|
|
|
30
32
|
"devDependencies": {
|
|
31
33
|
"@ava/typescript": "^2.0.0",
|
|
32
34
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
|
33
|
-
"@nomiclabs/hardhat-etherscan": "^
|
|
35
|
+
"@nomiclabs/hardhat-etherscan": "^3.0.0",
|
|
34
36
|
"@openzeppelin/contracts": "4.1.0",
|
|
35
37
|
"@openzeppelin/contracts-upgradeable": "4.1.0",
|
|
36
38
|
"@types/bn.js": "^5.0.0",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"@types/proper-lockfile": "^4.1.1",
|
|
42
44
|
"@types/rimraf": "^3.0.0",
|
|
43
45
|
"ava": "^3.9.0",
|
|
44
|
-
"dotenv": "^
|
|
46
|
+
"dotenv": "^14.0.0",
|
|
45
47
|
"fgbg": "^0.1.4",
|
|
46
48
|
"hardhat": "^2.0.2",
|
|
47
49
|
"rimraf": "^3.0.2",
|
|
@@ -51,10 +53,11 @@
|
|
|
51
53
|
"bn.js": "^5.1.2",
|
|
52
54
|
"cbor": "^8.0.0",
|
|
53
55
|
"chalk": "^4.1.0",
|
|
54
|
-
"compare-versions": "^
|
|
56
|
+
"compare-versions": "^4.0.0",
|
|
55
57
|
"debug": "^4.1.1",
|
|
56
58
|
"ethereumjs-util": "^7.0.3",
|
|
57
59
|
"proper-lockfile": "^4.1.1",
|
|
58
60
|
"solidity-ast": "^0.4.15"
|
|
59
|
-
}
|
|
61
|
+
},
|
|
62
|
+
"gitHead": "aff3cdacedb7265f5b54cdb8408e9517bb009e7f"
|
|
60
63
|
}
|
package/src/beacon.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { InvalidBeacon, getImplementationAddressFromBeacon } from './impl-address';
|
|
2
|
+
import { EthereumProvider } from './provider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks if the address looks like a beacon.
|
|
6
|
+
*
|
|
7
|
+
* @returns true if the address has an implementation() function that returns an address, false otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export async function isBeacon(provider: EthereumProvider, beaconAddress: string): Promise<boolean> {
|
|
10
|
+
try {
|
|
11
|
+
await getImplementationAddressFromBeacon(provider, beaconAddress);
|
|
12
|
+
return true;
|
|
13
|
+
} catch (e: any) {
|
|
14
|
+
if (e instanceof InvalidBeacon) {
|
|
15
|
+
return false;
|
|
16
|
+
} else {
|
|
17
|
+
throw e;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/deployment.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
|
+
import { TransactionMinedTimeout } from '.';
|
|
3
4
|
|
|
4
5
|
import { Deployment, resumeOrDeploy, waitAndValidateDeployment } from './deployment';
|
|
5
6
|
import { stubProvider } from './stub-provider';
|
|
@@ -96,3 +97,27 @@ test('waits for a deployment to return contract code', async t => {
|
|
|
96
97
|
provider.addContract(deployment.address);
|
|
97
98
|
await waitAndValidateDeployment(provider, deployment);
|
|
98
99
|
});
|
|
100
|
+
|
|
101
|
+
test('tx mined timeout - no params', async t => {
|
|
102
|
+
const provider = stubProvider();
|
|
103
|
+
const deployment = await resumeOrDeploy(provider, undefined, provider.deploy);
|
|
104
|
+
try {
|
|
105
|
+
throw new TransactionMinedTimeout(deployment);
|
|
106
|
+
} catch (e: any) {
|
|
107
|
+
const EXPECTED =
|
|
108
|
+
/Timed out waiting for contract deployment to address \S+ with transaction \S+\n\nRun the function again to continue waiting for the transaction confirmation./;
|
|
109
|
+
t.true(EXPECTED.test(e.message), e.message);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('tx mined timeout - params', async t => {
|
|
114
|
+
const provider = stubProvider();
|
|
115
|
+
const deployment = await resumeOrDeploy(provider, undefined, provider.deploy);
|
|
116
|
+
try {
|
|
117
|
+
throw new TransactionMinedTimeout(deployment, 'implementation', true);
|
|
118
|
+
} catch (e: any) {
|
|
119
|
+
const EXPECTED =
|
|
120
|
+
/Timed out waiting for implementation contract deployment to address \S+ with transaction \S+\n\nRun the function again to continue waiting for the transaction confirmation. If the problem persists, adjust the polling parameters with the timeout and pollingInterval options./;
|
|
121
|
+
t.true(EXPECTED.test(e.message), e.message);
|
|
122
|
+
}
|
|
123
|
+
});
|
package/src/deployment.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isDevelopmentNetwork,
|
|
11
11
|
isReceiptSuccessful,
|
|
12
12
|
} from './provider';
|
|
13
|
+
import { UpgradesError } from './error';
|
|
13
14
|
|
|
14
15
|
const sleep = promisify(setTimeout);
|
|
15
16
|
|
|
@@ -18,6 +19,18 @@ export interface Deployment {
|
|
|
18
19
|
txHash?: string;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
export interface DeployOpts {
|
|
23
|
+
/**
|
|
24
|
+
* Timeout in milliseconds to wait for the transaction confirmation when deploying an implementation contract or proxy admin contract. Use `0` to wait indefinitely.
|
|
25
|
+
*/
|
|
26
|
+
timeout?: number;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Polling interval in milliseconds between checks for the transaction confirmation when deploying an implementation contract or proxy admin contract.
|
|
30
|
+
*/
|
|
31
|
+
pollingInterval?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
export async function resumeOrDeploy<T extends Deployment>(
|
|
22
35
|
provider: EthereumProvider,
|
|
23
36
|
cached: T | undefined,
|
|
@@ -51,24 +64,25 @@ export async function resumeOrDeploy<T extends Deployment>(
|
|
|
51
64
|
return deployment;
|
|
52
65
|
}
|
|
53
66
|
|
|
54
|
-
export async function waitAndValidateDeployment(
|
|
67
|
+
export async function waitAndValidateDeployment(
|
|
68
|
+
provider: EthereumProvider,
|
|
69
|
+
deployment: Deployment,
|
|
70
|
+
type?: string,
|
|
71
|
+
opts?: DeployOpts,
|
|
72
|
+
): Promise<void> {
|
|
55
73
|
const { txHash, address } = deployment;
|
|
56
74
|
|
|
57
|
-
// Poll for 60 seconds with a 5 second poll interval.
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
75
|
+
// Poll for 60 seconds with a 5 second poll interval by default.
|
|
76
|
+
const pollTimeout = opts?.timeout ?? 60e3;
|
|
77
|
+
const pollInterval = opts?.pollingInterval ?? 5e3;
|
|
78
|
+
|
|
79
|
+
debug('polling timeout', pollTimeout, 'polling interval', pollInterval);
|
|
61
80
|
|
|
62
81
|
if (txHash !== undefined) {
|
|
63
82
|
const startTime = Date.now();
|
|
64
83
|
|
|
65
84
|
// eslint-disable-next-line no-constant-condition
|
|
66
85
|
while (true) {
|
|
67
|
-
const elapsedTime = Date.now() - startTime;
|
|
68
|
-
if (elapsedTime >= pollTimeout) {
|
|
69
|
-
// A timeout is NOT an InvalidDeployment
|
|
70
|
-
throw new TransactionMinedTimeout(deployment);
|
|
71
|
-
}
|
|
72
86
|
debug('verifying deployment tx mined', txHash);
|
|
73
87
|
const receipt = await getTransactionReceipt(provider, txHash);
|
|
74
88
|
if (receipt && isReceiptSuccessful(receipt)) {
|
|
@@ -81,6 +95,13 @@ export async function waitAndValidateDeployment(provider: EthereumProvider, depl
|
|
|
81
95
|
debug('waiting for deployment tx mined', txHash);
|
|
82
96
|
await sleep(pollInterval);
|
|
83
97
|
}
|
|
98
|
+
if (pollTimeout != 0) {
|
|
99
|
+
const elapsedTime = Date.now() - startTime;
|
|
100
|
+
if (elapsedTime >= pollTimeout) {
|
|
101
|
+
// A timeout is NOT an InvalidDeployment
|
|
102
|
+
throw new TransactionMinedTimeout(deployment, type, !!opts);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
84
105
|
}
|
|
85
106
|
}
|
|
86
107
|
|
|
@@ -96,9 +117,18 @@ export async function waitAndValidateDeployment(provider: EthereumProvider, depl
|
|
|
96
117
|
debug('code in target address found', address);
|
|
97
118
|
}
|
|
98
119
|
|
|
99
|
-
export class TransactionMinedTimeout extends
|
|
100
|
-
constructor(readonly deployment: Deployment) {
|
|
101
|
-
super(
|
|
120
|
+
export class TransactionMinedTimeout extends UpgradesError {
|
|
121
|
+
constructor(readonly deployment: Deployment, type?: string, configurableTimeout?: boolean) {
|
|
122
|
+
super(
|
|
123
|
+
`Timed out waiting for ${type ? type + ' ' : ''}contract deployment to address ${
|
|
124
|
+
deployment.address
|
|
125
|
+
} with transaction ${deployment.txHash}`,
|
|
126
|
+
() =>
|
|
127
|
+
'Run the function again to continue waiting for the transaction confirmation.' +
|
|
128
|
+
(configurableTimeout
|
|
129
|
+
? ' If the problem persists, adjust the polling parameters with the timeout and pollingInterval options.'
|
|
130
|
+
: ''),
|
|
131
|
+
);
|
|
102
132
|
}
|
|
103
133
|
}
|
|
104
134
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EIP1967BeaconNotFound,
|
|
3
|
+
EIP1967ImplementationNotFound,
|
|
4
|
+
getBeaconAddress,
|
|
5
|
+
getImplementationAddress,
|
|
6
|
+
} from './eip-1967';
|
|
7
|
+
import { EthereumProvider } from './provider';
|
|
8
|
+
|
|
9
|
+
export async function isTransparentOrUUPSProxy(provider: EthereumProvider, address: string): Promise<boolean> {
|
|
10
|
+
try {
|
|
11
|
+
await getImplementationAddress(provider, address);
|
|
12
|
+
// if an exception was not encountered above, then this address is a transparent/uups proxy
|
|
13
|
+
return true;
|
|
14
|
+
} catch (e: any) {
|
|
15
|
+
if (e instanceof EIP1967ImplementationNotFound) {
|
|
16
|
+
return false;
|
|
17
|
+
} else {
|
|
18
|
+
throw e;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function isBeaconProxy(provider: EthereumProvider, address: string): Promise<boolean> {
|
|
24
|
+
try {
|
|
25
|
+
await getBeaconAddress(provider, address);
|
|
26
|
+
// if an exception was not encountered above, then this address is a beacon proxy
|
|
27
|
+
return true;
|
|
28
|
+
} catch (e: any) {
|
|
29
|
+
if (e instanceof EIP1967BeaconNotFound) {
|
|
30
|
+
return false;
|
|
31
|
+
} else {
|
|
32
|
+
throw e;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/eip-1967.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { toChecksumAddress, keccak256 } from 'ethereumjs-util';
|
|
2
1
|
import BN from 'bn.js';
|
|
3
|
-
|
|
2
|
+
import { keccak256 } from 'ethereumjs-util';
|
|
3
|
+
import { UpgradesError } from './error';
|
|
4
4
|
import { EthereumProvider, getStorageAt } from './provider';
|
|
5
|
+
import { parseAddress } from './utils/address';
|
|
6
|
+
|
|
7
|
+
export class EIP1967ImplementationNotFound extends UpgradesError {}
|
|
8
|
+
|
|
9
|
+
export class EIP1967BeaconNotFound extends UpgradesError {}
|
|
5
10
|
|
|
6
11
|
export async function getAdminAddress(provider: EthereumProvider, address: string): Promise<string> {
|
|
7
12
|
const storage = await getStorageFallback(
|
|
@@ -11,7 +16,7 @@ export async function getAdminAddress(provider: EthereumProvider, address: strin
|
|
|
11
16
|
toFallbackEip1967Hash('org.zeppelinos.proxy.admin'),
|
|
12
17
|
);
|
|
13
18
|
|
|
14
|
-
return
|
|
19
|
+
return parseAddressFromStorage(storage);
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
export async function getImplementationAddress(provider: EthereumProvider, address: string): Promise<string> {
|
|
@@ -23,20 +28,20 @@ export async function getImplementationAddress(provider: EthereumProvider, addre
|
|
|
23
28
|
);
|
|
24
29
|
|
|
25
30
|
if (isEmptySlot(storage)) {
|
|
26
|
-
throw new
|
|
31
|
+
throw new EIP1967ImplementationNotFound(`Contract at ${address} doesn't look like an administered ERC 1967 proxy`);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
return
|
|
34
|
+
return parseAddressFromStorage(storage);
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
export async function getBeaconAddress(provider: EthereumProvider, address: string): Promise<string> {
|
|
33
38
|
const storage = await getStorageFallback(provider, address, toEip1967Hash('eip1967.proxy.beacon'));
|
|
34
39
|
|
|
35
40
|
if (isEmptySlot(storage)) {
|
|
36
|
-
throw new
|
|
41
|
+
throw new EIP1967BeaconNotFound(`Contract at ${address} doesn't look like an ERC 1967 beacon proxy`);
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
return
|
|
44
|
+
return parseAddressFromStorage(storage);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
async function getStorageFallback(provider: EthereumProvider, address: string, ...slots: string[]): Promise<string> {
|
|
@@ -67,11 +72,10 @@ function isEmptySlot(storage: string): boolean {
|
|
|
67
72
|
return new BN(storage, 'hex').isZero();
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
75
|
+
function parseAddressFromStorage(storage: string): string {
|
|
76
|
+
const address = parseAddress(storage);
|
|
77
|
+
if (address === undefined) {
|
|
73
78
|
throw new Error(`Value in storage is not an address (${storage})`);
|
|
74
79
|
}
|
|
75
|
-
|
|
76
|
-
return toChecksumAddress(address);
|
|
80
|
+
return address;
|
|
77
81
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { keccak256 } from 'ethereumjs-util';
|
|
2
|
+
import {
|
|
3
|
+
call,
|
|
4
|
+
EIP1967BeaconNotFound,
|
|
5
|
+
EIP1967ImplementationNotFound,
|
|
6
|
+
getBeaconAddress,
|
|
7
|
+
getImplementationAddress,
|
|
8
|
+
UpgradesError,
|
|
9
|
+
} from '.';
|
|
10
|
+
|
|
11
|
+
import { EthereumProvider } from './provider';
|
|
12
|
+
import { parseAddress } from './utils/address';
|
|
13
|
+
|
|
14
|
+
export class InvalidBeacon extends UpgradesError {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets the implementation address from the beacon using its implementation() function.
|
|
18
|
+
* @param provider
|
|
19
|
+
* @param beaconAddress
|
|
20
|
+
* @returns The implementation address.
|
|
21
|
+
* @throws {InvalidBeacon} If the implementation() function could not be called or does not return an address.
|
|
22
|
+
*/
|
|
23
|
+
export async function getImplementationAddressFromBeacon(
|
|
24
|
+
provider: EthereumProvider,
|
|
25
|
+
beaconAddress: string,
|
|
26
|
+
): Promise<string> {
|
|
27
|
+
const implementationFunction = '0x' + keccak256(Buffer.from('implementation()')).toString('hex').slice(0, 8);
|
|
28
|
+
let result: string | undefined;
|
|
29
|
+
try {
|
|
30
|
+
const implAddress = await call(provider, beaconAddress, implementationFunction);
|
|
31
|
+
result = parseAddress(implAddress);
|
|
32
|
+
} catch (e: any) {
|
|
33
|
+
if (
|
|
34
|
+
!(
|
|
35
|
+
e.message.includes('function selector was not recognized') ||
|
|
36
|
+
e.message.includes('invalid opcode') ||
|
|
37
|
+
e.message.includes('reverted')
|
|
38
|
+
)
|
|
39
|
+
) {
|
|
40
|
+
throw e;
|
|
41
|
+
} // otherwise fall through with no result
|
|
42
|
+
}
|
|
43
|
+
if (result === undefined) {
|
|
44
|
+
throw new InvalidBeacon(`Contract at ${beaconAddress} doesn't look like a beacon`);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets the implementation address from a UUPS/Transparent/Beacon proxy.
|
|
51
|
+
*
|
|
52
|
+
* @returns a Promise with the implementation address, or undefined if a UUPS/Transparent/Beacon proxy is not located at the address.
|
|
53
|
+
*/
|
|
54
|
+
export async function getImplementationAddressFromProxy(
|
|
55
|
+
provider: EthereumProvider,
|
|
56
|
+
proxyAddress: string,
|
|
57
|
+
): Promise<string | undefined> {
|
|
58
|
+
try {
|
|
59
|
+
return await getImplementationAddress(provider, proxyAddress);
|
|
60
|
+
} catch (e: any) {
|
|
61
|
+
if (e instanceof EIP1967ImplementationNotFound) {
|
|
62
|
+
try {
|
|
63
|
+
const beaconAddress = await getBeaconAddress(provider, proxyAddress);
|
|
64
|
+
return await getImplementationAddressFromBeacon(provider, beaconAddress);
|
|
65
|
+
} catch (e: any) {
|
|
66
|
+
if (e instanceof EIP1967BeaconNotFound) {
|
|
67
|
+
return undefined;
|
|
68
|
+
} else {
|
|
69
|
+
throw e;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|