@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.
Files changed (127) hide show
  1. package/LICENSE +22 -0
  2. package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.dbg.json +1 -1
  3. package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.dbg.json +4 -0
  4. package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json +80 -0
  5. package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.dbg.json +4 -0
  6. package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json +113 -0
  7. package/artifacts/AdminUpgradeabilityProxy.json +2 -2
  8. package/artifacts/contracts/proxy/AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json +2 -2
  9. package/dist/beacon.d.ts +8 -0
  10. package/dist/beacon.d.ts.map +1 -0
  11. package/dist/beacon.js +25 -0
  12. package/dist/beacon.js.map +1 -0
  13. package/dist/deployment.d.ts +14 -3
  14. package/dist/deployment.d.ts.map +1 -1
  15. package/dist/deployment.js +20 -13
  16. package/dist/deployment.js.map +1 -1
  17. package/dist/deployment.test.js +23 -0
  18. package/dist/deployment.test.js.map +1 -1
  19. package/dist/eip-1967-type.d.ts +4 -0
  20. package/dist/eip-1967-type.d.ts.map +1 -0
  21. package/dist/eip-1967-type.js +37 -0
  22. package/dist/eip-1967-type.js.map +1 -0
  23. package/dist/eip-1967.d.ts +5 -0
  24. package/dist/eip-1967.d.ts.map +1 -1
  25. package/dist/eip-1967.js +19 -12
  26. package/dist/eip-1967.js.map +1 -1
  27. package/dist/impl-address.d.ts +19 -0
  28. package/dist/impl-address.d.ts.map +1 -0
  29. package/dist/impl-address.js +67 -0
  30. package/dist/impl-address.js.map +1 -0
  31. package/dist/impl-store.d.ts +3 -2
  32. package/dist/impl-store.d.ts.map +1 -1
  33. package/dist/impl-store.js +21 -10
  34. package/dist/impl-store.js.map +1 -1
  35. package/dist/index.d.ts +7 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +23 -3
  38. package/dist/index.js.map +1 -1
  39. package/dist/manifest.d.ts +1 -1
  40. package/dist/manifest.d.ts.map +1 -1
  41. package/dist/provider.d.ts +2 -0
  42. package/dist/provider.d.ts.map +1 -1
  43. package/dist/provider.js +11 -1
  44. package/dist/provider.js.map +1 -1
  45. package/dist/proxy-kind.d.ts +12 -0
  46. package/dist/proxy-kind.d.ts.map +1 -0
  47. package/dist/proxy-kind.js +50 -0
  48. package/dist/proxy-kind.js.map +1 -0
  49. package/dist/standalone.d.ts +19 -0
  50. package/dist/standalone.d.ts.map +1 -0
  51. package/dist/standalone.js +24 -0
  52. package/dist/standalone.js.map +1 -0
  53. package/dist/standalone.test.d.ts +2 -0
  54. package/dist/standalone.test.d.ts.map +1 -0
  55. package/dist/standalone.test.js +33 -0
  56. package/dist/standalone.test.js.map +1 -0
  57. package/dist/storage/index.d.ts +7 -0
  58. package/dist/storage/index.d.ts.map +1 -1
  59. package/dist/storage/index.js +11 -5
  60. package/dist/storage/index.js.map +1 -1
  61. package/dist/storage/report.d.ts +3 -2
  62. package/dist/storage/report.d.ts.map +1 -1
  63. package/dist/storage/report.js +9 -3
  64. package/dist/storage/report.js.map +1 -1
  65. package/dist/usage-error.d.ts +21 -0
  66. package/dist/usage-error.d.ts.map +1 -0
  67. package/dist/usage-error.js +51 -0
  68. package/dist/usage-error.js.map +1 -0
  69. package/dist/utils/address.d.ts +8 -0
  70. package/dist/utils/address.d.ts.map +1 -0
  71. package/dist/utils/address.js +20 -0
  72. package/dist/utils/address.js.map +1 -0
  73. package/dist/utils/make-non-enumerable.d.ts +1 -1
  74. package/dist/utils/make-non-enumerable.d.ts.map +1 -1
  75. package/dist/utils/make-non-enumerable.js.map +1 -1
  76. package/dist/validate/error.d.ts.map +1 -1
  77. package/dist/validate/error.js +2 -65
  78. package/dist/validate/error.js.map +1 -1
  79. package/dist/validate/index.d.ts +2 -1
  80. package/dist/validate/index.d.ts.map +1 -1
  81. package/dist/validate/index.js +4 -1
  82. package/dist/validate/index.js.map +1 -1
  83. package/dist/validate/overrides.js +1 -1
  84. package/dist/validate/overrides.js.map +1 -1
  85. package/dist/validate/query.d.ts +3 -1
  86. package/dist/validate/query.d.ts.map +1 -1
  87. package/dist/validate/query.js +23 -7
  88. package/dist/validate/query.js.map +1 -1
  89. package/dist/validate/report.d.ts +8 -0
  90. package/dist/validate/report.d.ts.map +1 -0
  91. package/dist/validate/report.js +79 -0
  92. package/dist/validate/report.js.map +1 -0
  93. package/dist/version.d.ts +3 -3
  94. package/dist/version.d.ts.map +1 -1
  95. package/dist/version.js +12 -6
  96. package/dist/version.js.map +1 -1
  97. package/package.json +8 -5
  98. package/src/beacon.ts +20 -0
  99. package/src/deployment.test.ts +25 -0
  100. package/src/deployment.ts +43 -13
  101. package/src/eip-1967-type.ts +35 -0
  102. package/src/eip-1967.ts +16 -12
  103. package/src/impl-address.ts +76 -0
  104. package/src/impl-store.ts +23 -7
  105. package/src/index.ts +18 -1
  106. package/src/manifest.ts +1 -1
  107. package/src/provider.ts +16 -0
  108. package/src/proxy-kind.ts +59 -0
  109. package/src/standalone.test.ts +40 -0
  110. package/src/standalone.ts +41 -0
  111. package/src/storage/index.ts +14 -4
  112. package/src/storage/report.ts +10 -5
  113. package/src/usage-error.ts +68 -0
  114. package/src/utils/address.ts +16 -0
  115. package/src/utils/make-non-enumerable.ts +1 -1
  116. package/src/validate/error.ts +5 -67
  117. package/src/validate/index.ts +2 -0
  118. package/src/validate/overrides.ts +1 -1
  119. package/src/validate/query.ts +24 -6
  120. package/src/validate/report.ts +78 -0
  121. package/src/version.ts +14 -6
  122. package/CHANGELOG.md +0 -114
  123. package/dist/set-proxy-kind.d.ts +0 -5
  124. package/dist/set-proxy-kind.d.ts.map +0 -1
  125. package/dist/set-proxy-kind.js +0 -25
  126. package/dist/set-proxy-kind.js.map +0 -1
  127. package/src/set-proxy-kind.ts +0 -27
@@ -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
- let errors = getErrors(dataV3, version);
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 = c.methods.concat(...c.inherit.map(name => runValidation[name].methods));
95
- if (!selfAndInheritedMethods.includes('upgradeTo(address)')) {
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":"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"}
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
@@ -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,CAU7E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcrD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpE"}
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
- const buf = Buffer.from(bytecode.replace(/^0x/, ''), 'hex');
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) {
@@ -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;IAClE,IAAI,QAAQ,KAAK,EAAE,EAAE;QACnB,OAAO;YACL,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC;YACpC,eAAe,EAAE,2BAA2B,CAAC,QAAQ,CAAC;YACtD,qBAAqB,EAAE,2BAA2B,CAAC,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,QAAQ,CAAC;SAC/E,CAAC;KACH;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;KACvD;AACH,CAAC;AAVD,gCAUC;AAED,SAAgB,YAAY,CAAC,QAAgB;IAC3C,QAAQ,GAAG,QAAQ;SAChB,OAAO,CAAC,4BAA4B,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,WAAW,KAAK,CAAC;SACjF,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,EAAE,CAAC,IAAA,2BAAS,EAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAErG,uEAAuE;IACvE,iEAAiE;IACjE,kFAAkF;IAClF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;QACzC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;KACvD;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5D,OAAO,IAAA,2BAAS,EAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC;AAdD,oCAcC;AAED,SAAgB,2BAA2B,CAAC,QAAgB;IAC1D,OAAO,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAFD,kEAEC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,yBAAyB;IACzB,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE;QACxB,OAAO,QAAQ,CAAC;KACjB;IAED,0DAA0D;IAC1D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAEnD,yCAAyC;IACzC,IAAI,cAAc,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QACxC,OAAO,QAAQ,CAAC;KACjB;IAED,0EAA0E;IAC1E,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,GAAG,cAAc,GAAG,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEpE,iDAAiD;IACjD,IAAI;QACF,cAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;KAC3C;IAAC,OAAO,GAAG,EAAE;QACZ,uCAAuC;QACvC,OAAO,QAAQ,CAAC;KACjB;IAED,6BAA6B;IAC7B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;AAC1C,CAAC"}
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.9.2",
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": "^2.1.0",
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": "^10.0.0",
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": "^3.6.0",
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
+ }
@@ -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(provider: EthereumProvider, deployment: Deployment): Promise<void> {
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
- // TODO: Make these parameters configurable.
59
- const pollTimeout = 60e3;
60
- const pollInterval = 5e3;
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 Error {
100
- constructor(readonly deployment: Deployment) {
101
- super(`Timed out waiting for transaction ${deployment.txHash}`);
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 parseAddress(storage);
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 Error(`Contract at ${address} doesn't look like an administered ERC 1967 proxy`);
31
+ throw new EIP1967ImplementationNotFound(`Contract at ${address} doesn't look like an administered ERC 1967 proxy`);
27
32
  }
28
33
 
29
- return parseAddress(storage);
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 Error(`Contract at ${address} doesn't look like an ERC 1967 beacon proxy`);
41
+ throw new EIP1967BeaconNotFound(`Contract at ${address} doesn't look like an ERC 1967 beacon proxy`);
37
42
  }
38
43
 
39
- return parseAddress(storage);
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 parseAddress(storage: string): string {
71
- const buf = Buffer.from(storage.replace(/^0x/, ''), 'hex');
72
- if (!buf.slice(0, 12).equals(Buffer.alloc(12, 0))) {
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
- const address = '0x' + buf.toString('hex', 12, 32); // grab the last 20 bytes
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
+ }