@openzeppelin/upgrades-core 1.9.0 → 1.11.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 (196) 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/ast-dereferencer.js +2 -2
  10. package/dist/ast-dereferencer.js.map +1 -1
  11. package/dist/beacon.d.ts +8 -0
  12. package/dist/beacon.d.ts.map +1 -0
  13. package/dist/beacon.js +25 -0
  14. package/dist/beacon.js.map +1 -0
  15. package/dist/deployment.js +18 -18
  16. package/dist/deployment.js.map +1 -1
  17. package/dist/deployment.test.js +39 -39
  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 +22 -15
  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.map +1 -1
  32. package/dist/impl-store.js +8 -6
  33. package/dist/impl-store.js.map +1 -1
  34. package/dist/impl-store.test.js +18 -18
  35. package/dist/impl-store.test.js.map +1 -1
  36. package/dist/index.d.ts +7 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +23 -3
  39. package/dist/index.js.map +1 -1
  40. package/dist/levenshtein.test.js +14 -14
  41. package/dist/levenshtein.test.js.map +1 -1
  42. package/dist/link-refs.test.js +4 -4
  43. package/dist/link-refs.test.js.map +1 -1
  44. package/dist/manifest-storage-layout.js +8 -8
  45. package/dist/manifest-storage-layout.js.map +1 -1
  46. package/dist/manifest-storage-layout.test.js +16 -16
  47. package/dist/manifest-storage-layout.test.js.map +1 -1
  48. package/dist/manifest.d.ts +1 -1
  49. package/dist/manifest.d.ts.map +1 -1
  50. package/dist/manifest.js +6 -6
  51. package/dist/manifest.js.map +1 -1
  52. package/dist/manifest.test.js +2 -2
  53. package/dist/manifest.test.js.map +1 -1
  54. package/dist/provider.d.ts +2 -0
  55. package/dist/provider.d.ts.map +1 -1
  56. package/dist/provider.js +11 -1
  57. package/dist/provider.js.map +1 -1
  58. package/dist/provider.test.js +12 -12
  59. package/dist/provider.test.js.map +1 -1
  60. package/dist/proxy-kind.d.ts +12 -0
  61. package/dist/proxy-kind.d.ts.map +1 -0
  62. package/dist/proxy-kind.js +50 -0
  63. package/dist/proxy-kind.js.map +1 -0
  64. package/dist/scripts/migrate-oz-cli-project.js +1 -1
  65. package/dist/scripts/migrate-oz-cli-project.js.map +1 -1
  66. package/dist/scripts/migrate-oz-cli-project.test.js +9 -9
  67. package/dist/scripts/migrate-oz-cli-project.test.js.map +1 -1
  68. package/dist/src-decoder.test.js +2 -3
  69. package/dist/src-decoder.test.js.map +1 -1
  70. package/dist/standalone.d.ts +19 -0
  71. package/dist/standalone.d.ts.map +1 -0
  72. package/dist/standalone.js +24 -0
  73. package/dist/standalone.js.map +1 -0
  74. package/dist/standalone.test.d.ts +2 -0
  75. package/dist/standalone.test.d.ts.map +1 -0
  76. package/dist/standalone.test.js +33 -0
  77. package/dist/standalone.test.js.map +1 -0
  78. package/dist/storage/compare.js +7 -7
  79. package/dist/storage/compare.js.map +1 -1
  80. package/dist/storage/extract.js +9 -9
  81. package/dist/storage/extract.js.map +1 -1
  82. package/dist/storage/index.d.ts +7 -0
  83. package/dist/storage/index.d.ts.map +1 -1
  84. package/dist/storage/index.js +22 -23
  85. package/dist/storage/index.js.map +1 -1
  86. package/dist/storage/layout.js +1 -1
  87. package/dist/storage/layout.js.map +1 -1
  88. package/dist/storage/report.d.ts +3 -2
  89. package/dist/storage/report.d.ts.map +1 -1
  90. package/dist/storage/report.js +17 -11
  91. package/dist/storage/report.js.map +1 -1
  92. package/dist/storage/report.test.js +5 -5
  93. package/dist/storage/report.test.js.map +1 -1
  94. package/dist/storage.test.js +32 -32
  95. package/dist/storage.test.js.map +1 -1
  96. package/dist/stub-provider.d.ts.map +1 -1
  97. package/dist/stub-provider.js +0 -1
  98. package/dist/stub-provider.js.map +1 -1
  99. package/dist/usage-error.d.ts +21 -0
  100. package/dist/usage-error.d.ts.map +1 -0
  101. package/dist/usage-error.js +51 -0
  102. package/dist/usage-error.js.map +1 -0
  103. package/dist/utils/address.d.ts +8 -0
  104. package/dist/utils/address.d.ts.map +1 -0
  105. package/dist/utils/address.js +20 -0
  106. package/dist/utils/address.js.map +1 -0
  107. package/dist/utils/debug.js +1 -1
  108. package/dist/utils/debug.js.map +1 -1
  109. package/dist/utils/deep-array.test.js +12 -12
  110. package/dist/utils/deep-array.test.js.map +1 -1
  111. package/dist/utils/function.js +5 -5
  112. package/dist/utils/function.js.map +1 -1
  113. package/dist/utils/function.test.js +4 -4
  114. package/dist/utils/function.test.js.map +1 -1
  115. package/dist/utils/is-nullish.test.js +6 -6
  116. package/dist/utils/is-nullish.test.js.map +1 -1
  117. package/dist/utils/itemize.js +1 -1
  118. package/dist/utils/itemize.js.map +1 -1
  119. package/dist/utils/log.d.ts +2 -0
  120. package/dist/utils/log.d.ts.map +1 -1
  121. package/dist/utils/log.js +22 -4
  122. package/dist/utils/log.js.map +1 -1
  123. package/dist/utils/make-non-enumerable.d.ts +1 -1
  124. package/dist/utils/make-non-enumerable.d.ts.map +1 -1
  125. package/dist/utils/make-non-enumerable.js +0 -1
  126. package/dist/utils/make-non-enumerable.js.map +1 -1
  127. package/dist/utils/parse-type-id.js +1 -1
  128. package/dist/utils/parse-type-id.js.map +1 -1
  129. package/dist/utils/parse-type-id.test.js +2 -2
  130. package/dist/utils/parse-type-id.test.js.map +1 -1
  131. package/dist/utils/type-id.js +1 -1
  132. package/dist/utils/type-id.js.map +1 -1
  133. package/dist/validate/error.d.ts.map +1 -1
  134. package/dist/validate/error.js +2 -67
  135. package/dist/validate/error.js.map +1 -1
  136. package/dist/validate/index.d.ts +4 -2
  137. package/dist/validate/index.d.ts.map +1 -1
  138. package/dist/validate/index.js +7 -2
  139. package/dist/validate/index.js.map +1 -1
  140. package/dist/validate/overrides.d.ts +1 -2
  141. package/dist/validate/overrides.d.ts.map +1 -1
  142. package/dist/validate/overrides.js +7 -18
  143. package/dist/validate/overrides.js.map +1 -1
  144. package/dist/validate/query.d.ts +3 -1
  145. package/dist/validate/query.d.ts.map +1 -1
  146. package/dist/validate/query.js +45 -19
  147. package/dist/validate/query.js.map +1 -1
  148. package/dist/validate/query.test.js +4 -4
  149. package/dist/validate/query.test.js.map +1 -1
  150. package/dist/validate/report.d.ts +8 -0
  151. package/dist/validate/report.d.ts.map +1 -0
  152. package/dist/validate/report.js +79 -0
  153. package/dist/validate/report.js.map +1 -0
  154. package/dist/validate/run.js +15 -15
  155. package/dist/validate/run.js.map +1 -1
  156. package/dist/validate.test.js +7 -6
  157. package/dist/validate.test.js.map +1 -1
  158. package/dist/version.d.ts +3 -3
  159. package/dist/version.d.ts.map +1 -1
  160. package/dist/version.js +14 -8
  161. package/dist/version.js.map +1 -1
  162. package/dist/version.test.js +11 -11
  163. package/dist/version.test.js.map +1 -1
  164. package/package.json +11 -6
  165. package/src/beacon.ts +20 -0
  166. package/src/eip-1967-type.ts +35 -0
  167. package/src/eip-1967.ts +16 -12
  168. package/src/impl-address.ts +76 -0
  169. package/src/impl-store.ts +2 -0
  170. package/src/index.ts +18 -1
  171. package/src/manifest.ts +2 -2
  172. package/src/provider.ts +16 -0
  173. package/src/proxy-kind.ts +59 -0
  174. package/src/src-decoder.test.ts +0 -2
  175. package/src/standalone.test.ts +40 -0
  176. package/src/standalone.ts +41 -0
  177. package/src/storage/index.ts +23 -20
  178. package/src/storage/report.ts +10 -5
  179. package/src/stub-provider.ts +0 -1
  180. package/src/usage-error.ts +68 -0
  181. package/src/utils/address.ts +16 -0
  182. package/src/utils/log.ts +23 -2
  183. package/src/utils/make-non-enumerable.ts +1 -2
  184. package/src/validate/error.ts +5 -69
  185. package/src/validate/index.ts +6 -1
  186. package/src/validate/overrides.ts +5 -17
  187. package/src/validate/query.ts +38 -9
  188. package/src/validate/report.ts +78 -0
  189. package/src/validate.test.ts +1 -0
  190. package/src/version.ts +14 -6
  191. package/CHANGELOG.md +0 -106
  192. package/dist/set-proxy-kind.d.ts +0 -5
  193. package/dist/set-proxy-kind.d.ts.map +0 -1
  194. package/dist/set-proxy-kind.js +0 -25
  195. package/dist/set-proxy-kind.js.map +0 -1
  196. package/src/set-proxy-kind.ts +0 -27
@@ -7,7 +7,7 @@ const ava_1 = __importDefault(require("ava"));
7
7
  const hardhat_1 = require("hardhat");
8
8
  const version_1 = require("./version");
9
9
  const contractBytecode = '01234567890abcdef';
10
- ava_1.default('same code different formatting produces different metadata', async (t) => {
10
+ (0, ava_1.default)('same code different formatting produces different metadata', async (t) => {
11
11
  async function getBytecodeByContractName(contractName) {
12
12
  const buildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/Version.sol:Greeter');
13
13
  if (buildInfo === undefined) {
@@ -18,17 +18,17 @@ ava_1.default('same code different formatting produces different metadata', asyn
18
18
  }
19
19
  const GreeterBytecode = await getBytecodeByContractName('Greeter');
20
20
  const GreeterDifferentFormattingBytecode = await getBytecodeByContractName('GreeterDifferentFormatting');
21
- t.not(version_1.hashBytecode(GreeterBytecode), version_1.hashBytecode(GreeterDifferentFormattingBytecode));
22
- t.is(version_1.hashBytecodeWithoutMetadata(GreeterBytecode), version_1.hashBytecodeWithoutMetadata(GreeterDifferentFormattingBytecode));
21
+ t.not((0, version_1.hashBytecode)(GreeterBytecode), (0, version_1.hashBytecode)(GreeterDifferentFormattingBytecode));
22
+ t.is((0, version_1.hashBytecodeWithoutMetadata)(GreeterBytecode), (0, version_1.hashBytecodeWithoutMetadata)(GreeterDifferentFormattingBytecode));
23
23
  });
24
- ava_1.default('removes metadata from Solidity 0.4 bytecode', t => {
24
+ (0, ava_1.default)('removes metadata from Solidity 0.4 bytecode', t => {
25
25
  const swarmHash = '69b1869ae52f674ffccdd8f6d35de04d578a778e919a1b41b7a2177668e08e1a';
26
26
  const swarmHashWrapper = `65627a7a72305820${swarmHash}`;
27
27
  const metadata = `a1${swarmHashWrapper}0029`;
28
28
  const bytecode = `0x${contractBytecode}${metadata}`;
29
- t.is(version_1.hashBytecodeWithoutMetadata(bytecode), version_1.hashBytecode(`0x${contractBytecode}`));
29
+ t.is((0, version_1.hashBytecodeWithoutMetadata)(bytecode), (0, version_1.hashBytecode)(`0x${contractBytecode}`));
30
30
  });
31
- ava_1.default('removes metadata from Solidity ^0.5.9 bytecode', t => {
31
+ (0, ava_1.default)('removes metadata from Solidity ^0.5.9 bytecode', t => {
32
32
  // Solidity 0.5.9 includes solc version into the CBOR encoded metadata
33
33
  // https://github.com/ethereum/solidity/releases/tag/v0.5.9
34
34
  const swarmHash = '69b1869ae52f674ffccdd8f6d35de04d578a778e919a1b41b7a2177668e08e1a';
@@ -36,18 +36,18 @@ ava_1.default('removes metadata from Solidity ^0.5.9 bytecode', t => {
36
36
  const solcVersionWrapper = '64736f6c6343000509';
37
37
  const metadata = `a2${swarmHashWrapper}${solcVersionWrapper}0032`;
38
38
  const bytecode = `0x${contractBytecode}${metadata}`;
39
- t.is(version_1.hashBytecodeWithoutMetadata(bytecode), version_1.hashBytecode(`0x${contractBytecode}`));
39
+ t.is((0, version_1.hashBytecodeWithoutMetadata)(bytecode), (0, version_1.hashBytecode)(`0x${contractBytecode}`));
40
40
  });
41
- ava_1.default('does not change the bytecode if metadata encoding is invalid', t => {
41
+ (0, ava_1.default)('does not change the bytecode if metadata encoding is invalid', t => {
42
42
  const swarmHash = '69b1869ae52f674ffccdd8f6d35de04d578a778e919a1b41b7a2177668e08e1a';
43
43
  const invalidSwarmHashWrapper = `a165627a7a72305821${swarmHash}0029`;
44
44
  const bytecode = `0x${contractBytecode}${invalidSwarmHashWrapper}`;
45
- t.is(version_1.hashBytecodeWithoutMetadata(bytecode), version_1.hashBytecode(bytecode));
45
+ t.is((0, version_1.hashBytecodeWithoutMetadata)(bytecode), (0, version_1.hashBytecode)(bytecode));
46
46
  });
47
- ava_1.default('does not change the bytecode if metadata length is not reliable', t => {
47
+ (0, ava_1.default)('does not change the bytecode if metadata length is not reliable', t => {
48
48
  const swarmHash = '69b1869ae52f674ffccdd8f6d35de04d578a778e919a1b41b7a2177668e08e1a';
49
49
  const invalidSwarmHashWrapper = `a165627a7a72305821${swarmHash}9929`;
50
50
  const bytecode = `0x${contractBytecode}${invalidSwarmHashWrapper}`;
51
- t.is(version_1.hashBytecodeWithoutMetadata(bytecode), version_1.hashBytecode(bytecode));
51
+ t.is((0, version_1.hashBytecodeWithoutMetadata)(bytecode), (0, version_1.hashBytecode)(bytecode));
52
52
  });
53
53
  //# sourceMappingURL=version.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.test.js","sourceRoot":"","sources":["../src/version.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version.test.js","sourceRoot":"","sources":["../src/version.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AACvB,qCAAoC;AACpC,uCAAsE;AAEtE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,IAAA,aAAI,EAAC,4DAA4D,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IAC3E,KAAK,UAAU,yBAAyB,CAAC,YAAoB;QAC3D,MAAM,SAAS,GAAG,MAAM,mBAAS,CAAC,YAAY,CAAC,oCAAoC,CAAC,CAAC;QACrF,IAAI,SAAS,KAAK,SAAS,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QACD,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;QACpC,OAAO,UAAU,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9F,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,kCAAkC,GAAG,MAAM,yBAAyB,CAAC,4BAA4B,CAAC,CAAC;IAEzG,CAAC,CAAC,GAAG,CAAC,IAAA,sBAAY,EAAC,eAAe,CAAC,EAAE,IAAA,sBAAY,EAAC,kCAAkC,CAAC,CAAC,CAAC;IACvF,CAAC,CAAC,EAAE,CAAC,IAAA,qCAA2B,EAAC,eAAe,CAAC,EAAE,IAAA,qCAA2B,EAAC,kCAAkC,CAAC,CAAC,CAAC;AACtH,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,6CAA6C,EAAE,CAAC,CAAC,EAAE;IACtD,MAAM,SAAS,GAAG,kEAAkE,CAAC;IACrF,MAAM,gBAAgB,GAAG,mBAAmB,SAAS,EAAE,CAAC;IACxD,MAAM,QAAQ,GAAG,KAAK,gBAAgB,MAAM,CAAC;IAC7C,MAAM,QAAQ,GAAG,KAAK,gBAAgB,GAAG,QAAQ,EAAE,CAAC;IAEpD,CAAC,CAAC,EAAE,CAAC,IAAA,qCAA2B,EAAC,QAAQ,CAAC,EAAE,IAAA,sBAAY,EAAC,KAAK,gBAAgB,EAAE,CAAC,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,gDAAgD,EAAE,CAAC,CAAC,EAAE;IACzD,sEAAsE;IACtE,2DAA2D;IAC3D,MAAM,SAAS,GAAG,kEAAkE,CAAC;IACrF,MAAM,gBAAgB,GAAG,mBAAmB,SAAS,EAAE,CAAC;IACxD,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;IAChD,MAAM,QAAQ,GAAG,KAAK,gBAAgB,GAAG,kBAAkB,MAAM,CAAC;IAClE,MAAM,QAAQ,GAAG,KAAK,gBAAgB,GAAG,QAAQ,EAAE,CAAC;IAEpD,CAAC,CAAC,EAAE,CAAC,IAAA,qCAA2B,EAAC,QAAQ,CAAC,EAAE,IAAA,sBAAY,EAAC,KAAK,gBAAgB,EAAE,CAAC,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,8DAA8D,EAAE,CAAC,CAAC,EAAE;IACvE,MAAM,SAAS,GAAG,kEAAkE,CAAC;IACrF,MAAM,uBAAuB,GAAG,qBAAqB,SAAS,MAAM,CAAC;IACrE,MAAM,QAAQ,GAAG,KAAK,gBAAgB,GAAG,uBAAuB,EAAE,CAAC;IAEnE,CAAC,CAAC,EAAE,CAAC,IAAA,qCAA2B,EAAC,QAAQ,CAAC,EAAE,IAAA,sBAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,iEAAiE,EAAE,CAAC,CAAC,EAAE;IAC1E,MAAM,SAAS,GAAG,kEAAkE,CAAC;IACrF,MAAM,uBAAuB,GAAG,qBAAqB,SAAS,MAAM,CAAC;IACrE,MAAM,QAAQ,GAAG,KAAK,gBAAgB,GAAG,uBAAuB,EAAE,CAAC;IAEnE,CAAC,CAAC,EAAE,CAAC,IAAA,qCAA2B,EAAC,QAAQ,CAAC,EAAE,IAAA,sBAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/upgrades-core",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "",
5
5
  "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
6
6
  "license": "MIT",
@@ -13,14 +13,17 @@
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"
19
21
  ],
20
22
  "scripts": {
21
- "prepublish": "rimraf artifacts cache dist *.tsbuildinfo",
22
- "prepare": "tsc -b && yarn prepare:contracts",
23
- "prepare:contracts": "hardhat compile",
23
+ "clean": "hardhat clean && rimraf dist *.tsbuildinfo",
24
+ "compile": "tsc -b && yarn compile:contracts",
25
+ "compile:contracts": "hardhat compile",
26
+ "prepare": "yarn clean && yarn compile",
24
27
  "prepublishOnly": "bash scripts/copy-artifacts.sh",
25
28
  "test": "tsc -b && hardhat compile --force && ava",
26
29
  "test:watch": "hardhat compile --force && fgbg 'ava --watch' 'tsc -b --watch' --",
@@ -31,6 +34,7 @@
31
34
  "@nomiclabs/hardhat-ethers": "^2.0.2",
32
35
  "@nomiclabs/hardhat-etherscan": "^2.1.0",
33
36
  "@openzeppelin/contracts": "4.1.0",
37
+ "@openzeppelin/contracts-upgradeable": "4.1.0",
34
38
  "@types/bn.js": "^5.0.0",
35
39
  "@types/cbor": "^5.0.0",
36
40
  "@types/debug": "^4.1.5",
@@ -49,10 +53,11 @@
49
53
  "bn.js": "^5.1.2",
50
54
  "cbor": "^8.0.0",
51
55
  "chalk": "^4.1.0",
52
- "compare-versions": "^3.6.0",
56
+ "compare-versions": "^4.0.0",
53
57
  "debug": "^4.1.1",
54
58
  "ethereumjs-util": "^7.0.3",
55
59
  "proper-lockfile": "^4.1.1",
56
60
  "solidity-ast": "^0.4.15"
57
- }
61
+ },
62
+ "gitHead": "a32bd11a82ede9136d18de4cf0a1d18f44127103"
58
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
+ }
@@ -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('Transaction 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
+ }
package/src/impl-store.ts CHANGED
@@ -3,6 +3,7 @@ import { Manifest, ManifestData, ImplDeployment } from './manifest';
3
3
  import { EthereumProvider, isDevelopmentNetwork } from './provider';
4
4
  import { Deployment, InvalidDeployment, resumeOrDeploy, waitAndValidateDeployment } from './deployment';
5
5
  import type { Version } from './version';
6
+ import assert from 'assert';
6
7
 
7
8
  interface ManifestLens<T> {
8
9
  description: string;
@@ -46,6 +47,7 @@ async function fetchOrDeployGeneric<T extends Deployment>(
46
47
  // If we run into a deployment error, we remove it from the manifest.
47
48
  if (e instanceof InvalidDeployment) {
48
49
  await manifest.lockedRun(async () => {
50
+ assert(e instanceof InvalidDeployment); // Not sure why this is needed but otherwise doesn't type
49
51
  const data = await manifest.read();
50
52
  const deployment = lens(data);
51
53
  const stored = deployment.get();
package/src/index.ts CHANGED
@@ -9,10 +9,27 @@ export * from './src-decoder';
9
9
  export * from './solc-api';
10
10
  export * from './deployment';
11
11
  export * from './link-refs';
12
+ export * from './error';
12
13
 
13
14
  export { getStorageLayoutForAddress } from './manifest-storage-layout';
14
15
 
15
16
  export * from './scripts/migrate-oz-cli-project';
16
17
 
17
18
  export { logWarning } from './utils/log';
18
- export { setProxyKind } from './set-proxy-kind';
19
+ export { setProxyKind, processProxyKind } from './proxy-kind';
20
+
21
+ export { UpgradeableContract } from './standalone';
22
+
23
+ export { isTransparentOrUUPSProxy, isBeaconProxy } from './eip-1967-type';
24
+ export { getImplementationAddressFromBeacon, getImplementationAddressFromProxy } from './impl-address';
25
+ export { isBeacon } from './beacon';
26
+
27
+ export {
28
+ BeaconProxyUnsupportedError,
29
+ LoadProxyUnsupportedError,
30
+ PrepareUpgradeUnsupportedError,
31
+ DeployBeaconProxyUnsupportedError,
32
+ DeployBeaconProxyImplUnknownError,
33
+ DeployBeaconProxyKindError,
34
+ assertNotProxy,
35
+ } from './usage-error';
package/src/manifest.ts CHANGED
@@ -25,7 +25,7 @@ export interface ImplDeployment extends Deployment {
25
25
  }
26
26
 
27
27
  export interface ProxyDeployment extends Deployment {
28
- kind: 'uups' | 'transparent';
28
+ kind: 'uups' | 'transparent' | 'beacon';
29
29
  }
30
30
 
31
31
  function defaultManifest(): ManifestData {
@@ -90,7 +90,7 @@ export class Manifest {
90
90
  try {
91
91
  const data = JSON.parse(await fs.readFile(this.file, 'utf8')) as ManifestData;
92
92
  return validateOrUpdateManifestVersion(data);
93
- } catch (e) {
93
+ } catch (e: any) {
94
94
  if (e.code === 'ENOENT') {
95
95
  return defaultManifest();
96
96
  } else {
package/src/provider.ts CHANGED
@@ -5,6 +5,7 @@ export interface EthereumProvider {
5
5
  send(method: 'net_version', params: []): Promise<string>;
6
6
  send(method: 'eth_chainId', params: []): Promise<string>;
7
7
  send(method: 'eth_getCode', params: [string, string]): Promise<string>;
8
+ send(method: 'eth_call', params: unknown[]): Promise<string>;
8
9
  send(method: 'eth_getStorageAt', params: [string, string, string]): Promise<string>;
9
10
  send(method: 'eth_getTransactionByHash', params: [string]): Promise<null | EthereumTransaction>;
10
11
  send(method: 'eth_getTransactionReceipt', params: [string]): Promise<null | EthereumTransactionReceipt>;
@@ -53,6 +54,21 @@ export async function getCode(provider: EthereumProvider, address: string, block
53
54
  return provider.send('eth_getCode', [address, block]);
54
55
  }
55
56
 
57
+ export async function call(
58
+ provider: EthereumProvider,
59
+ address: string,
60
+ data: string,
61
+ block = 'latest',
62
+ ): Promise<string> {
63
+ return provider.send('eth_call', [
64
+ {
65
+ to: address,
66
+ data: data,
67
+ },
68
+ block,
69
+ ]);
70
+ }
71
+
56
72
  export async function hasCode(provider: EthereumProvider, address: string, block?: string): Promise<boolean> {
57
73
  const code = await getCode(provider, address, block);
58
74
  return code !== '0x';
@@ -0,0 +1,59 @@
1
+ import { EthereumProvider } from './provider';
2
+ import { inferProxyKind, ValidationData, ValidationOptions } from './validate';
3
+ import { Manifest, DeploymentNotFound, ProxyDeployment } from './manifest';
4
+ import { isBeaconProxy } from './eip-1967-type';
5
+ import { Version } from './version';
6
+ import { BeaconProxyUnsupportedError } from './usage-error';
7
+
8
+ export async function setProxyKind(
9
+ provider: EthereumProvider,
10
+ proxyAddress: string,
11
+ opts: ValidationOptions,
12
+ ): Promise<ProxyDeployment['kind']> {
13
+ const manifest = await Manifest.forNetwork(provider);
14
+
15
+ const manifestDeployment = await manifest.getProxyFromAddress(proxyAddress).catch(e => {
16
+ if (e instanceof DeploymentNotFound) {
17
+ return undefined;
18
+ } else {
19
+ throw e;
20
+ }
21
+ });
22
+
23
+ if (opts.kind === undefined) {
24
+ opts.kind = manifestDeployment?.kind ?? 'transparent';
25
+ } else if (manifestDeployment && opts.kind !== manifestDeployment.kind) {
26
+ throw new Error(`Requested an upgrade of kind ${opts.kind} but proxy is ${manifestDeployment.kind}`);
27
+ }
28
+
29
+ return opts.kind;
30
+ }
31
+
32
+ /**
33
+ * Processes opts.kind when deploying the implementation for a UUPS or Transparent proxy.
34
+ *
35
+ * @throws {BeaconProxyUnsupportedError} If this function is called for a Beacon proxy.
36
+ */
37
+ export async function processProxyKind(
38
+ provider: EthereumProvider,
39
+ proxyAddress: string | undefined,
40
+ opts: ValidationOptions,
41
+ data: ValidationData,
42
+ version: Version,
43
+ ) {
44
+ if (opts.kind === undefined) {
45
+ if (proxyAddress !== undefined && (await isBeaconProxy(provider, proxyAddress))) {
46
+ opts.kind = 'beacon';
47
+ } else {
48
+ opts.kind = inferProxyKind(data, version);
49
+ }
50
+ }
51
+
52
+ if (proxyAddress !== undefined) {
53
+ await setProxyKind(provider, proxyAddress, opts);
54
+ }
55
+
56
+ if (opts.kind === 'beacon') {
57
+ throw new BeaconProxyUnsupportedError();
58
+ }
59
+ }
@@ -1,5 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
1
  import test from 'ava';
4
2
 
5
3
  import { SolcInput, SolcOutput } from './solc-api';
@@ -0,0 +1,40 @@
1
+ import _test, { TestInterface } from 'ava';
2
+ import { artifacts } from 'hardhat';
3
+
4
+ import { SolcInput, SolcOutput } from './solc-api';
5
+ import { UpgradeableContract } from './standalone';
6
+
7
+ interface Context {
8
+ solcInput: SolcInput;
9
+ solcOutput: SolcOutput;
10
+ }
11
+
12
+ const test = _test as TestInterface<Context>;
13
+
14
+ test.before(async t => {
15
+ const buildInfo = await artifacts.getBuildInfo('contracts/test/Standalone.sol:StandaloneV1');
16
+ if (buildInfo === undefined) {
17
+ throw new Error('Build info not found');
18
+ }
19
+ t.context.solcInput = buildInfo.input;
20
+ t.context.solcOutput = buildInfo.output;
21
+ });
22
+
23
+ test('reports unsafe operation', t => {
24
+ const impl = new UpgradeableContract('StandaloneV1', t.context.solcInput, t.context.solcOutput);
25
+ const report = impl.getErrorReport();
26
+ t.false(report.ok);
27
+ t.true(report.errors[0].kind === 'delegatecall');
28
+ });
29
+
30
+ test('reports storage upgrade errors', t => {
31
+ const v1 = new UpgradeableContract('StandaloneV1', t.context.solcInput, t.context.solcOutput);
32
+
33
+ const v2Good = new UpgradeableContract('StandaloneV2Good', t.context.solcInput, t.context.solcOutput);
34
+ const goodReport = v1.getStorageUpgradeReport(v2Good);
35
+ t.true(goodReport.ok);
36
+
37
+ const v2Bad = new UpgradeableContract('StandaloneV2Bad', t.context.solcInput, t.context.solcOutput);
38
+ const badReport = v1.getStorageUpgradeReport(v2Bad);
39
+ t.false(badReport.ok);
40
+ });
@@ -0,0 +1,41 @@
1
+ import { SolcOutput, SolcInput } from './solc-api';
2
+ import { solcInputOutputDecoder } from './src-decoder';
3
+ import {
4
+ getContractVersion,
5
+ getErrors,
6
+ getStorageLayout,
7
+ UpgradeableContractErrorReport,
8
+ validate,
9
+ ValidationOptions,
10
+ withValidationDefaults,
11
+ } from './validate';
12
+ import { getStorageUpgradeReport, StorageLayout } from './storage';
13
+ import { Version } from './version';
14
+ import { ValidationError } from './validate/run';
15
+
16
+ export interface Report {
17
+ ok: boolean;
18
+ explain(color?: boolean): string;
19
+ }
20
+
21
+ export class UpgradeableContract {
22
+ readonly version: Version;
23
+ readonly errors: ValidationError[];
24
+ readonly layout: StorageLayout;
25
+
26
+ constructor(readonly name: string, solcInput: SolcInput, solcOutput: SolcOutput, opts: ValidationOptions = {}) {
27
+ const decodeSrc = solcInputOutputDecoder(solcInput, solcOutput);
28
+ const validation = validate(solcOutput, decodeSrc);
29
+ this.version = getContractVersion(validation, name);
30
+ this.errors = getErrors(validation, this.version, opts);
31
+ this.layout = getStorageLayout(validation, this.version);
32
+ }
33
+
34
+ getErrorReport() {
35
+ return new UpgradeableContractErrorReport(this.errors);
36
+ }
37
+
38
+ getStorageUpgradeReport(newVersion: UpgradeableContract, opts: ValidationOptions = {}) {
39
+ return getStorageUpgradeReport(this.layout, newVersion.layout, withValidationDefaults(opts));
40
+ }
41
+ }
@@ -1,13 +1,11 @@
1
- import chalk from 'chalk';
2
-
3
1
  export * from './compat';
4
2
 
5
3
  import { UpgradesError } from '../error';
6
4
  import { StorageLayout, getDetailedLayout } from './layout';
7
5
  import { StorageOperation, StorageItem, StorageLayoutComparator } from './compare';
8
6
  import { LayoutCompatibilityReport } from './report';
9
- import { ValidationOptions, isSilencingWarnings, withValidationDefaults } from '../validate/overrides';
10
- import { logWarning } from '../utils/log';
7
+ import { ValidationOptions, withValidationDefaults } from '../validate/overrides';
8
+ import { logNote, logWarning } from '../utils/log';
11
9
 
12
10
  export function assertStorageUpgradeSafe(
13
11
  original: StorageLayout,
@@ -31,31 +29,36 @@ export function assertStorageUpgradeSafe(
31
29
  opts = withValidationDefaults({ unsafeAllowCustomTypes });
32
30
  }
33
31
 
32
+ const report = getStorageUpgradeReport(original, updated, opts);
33
+
34
+ if (!report.pass) {
35
+ throw new StorageUpgradeErrors(report);
36
+ }
37
+ }
38
+
39
+ export function getStorageUpgradeReport(
40
+ original: StorageLayout,
41
+ updated: StorageLayout,
42
+ opts: Required<ValidationOptions>,
43
+ ): LayoutCompatibilityReport {
34
44
  const originalDetailed = getDetailedLayout(original);
35
45
  const updatedDetailed = getDetailedLayout(updated);
36
46
  const comparator = new StorageLayoutComparator(opts.unsafeAllowCustomTypes, opts.unsafeAllowRenames);
37
47
  const report = comparator.compareLayouts(originalDetailed, updatedDetailed);
38
48
 
39
- if (!isSilencingWarnings()) {
40
- if (comparator.hasAllowedUncheckedCustomTypes) {
41
- logWarning(`Potentially unsafe deployment`, [
42
- `You are using \`unsafeAllowCustomTypes\` to force approve structs or enums with missing data.`,
43
- `Make sure you have manually checked the storage layout for incompatibilities.`,
44
- ]);
45
- } else if (opts.unsafeAllowCustomTypes) {
46
- console.error(
47
- chalk.yellow.bold('Note:') +
48
- ` \`unsafeAllowCustomTypes\` is no longer necessary. Structs are enums are automatically checked.\n`,
49
- );
50
- }
49
+ if (comparator.hasAllowedUncheckedCustomTypes) {
50
+ logWarning(`Potentially unsafe deployment`, [
51
+ `You are using \`unsafeAllowCustomTypes\` to force approve structs or enums with missing data.`,
52
+ `Make sure you have manually checked the storage layout for incompatibilities.`,
53
+ ]);
54
+ } else if (opts.unsafeAllowCustomTypes) {
55
+ logNote(`\`unsafeAllowCustomTypes\` is no longer necessary. Structs are enums are automatically checked.\n`);
51
56
  }
52
57
 
53
- if (!report.pass) {
54
- throw new StorageUpgradeErrors(report);
55
- }
58
+ return report;
56
59
  }
57
60
 
58
- class StorageUpgradeErrors extends UpgradesError {
61
+ export class StorageUpgradeErrors extends UpgradesError {
59
62
  constructor(readonly report: LayoutCompatibilityReport) {
60
63
  super(`New storage layout is incompatible`, () => report.explain());
61
64
  }
@@ -1,4 +1,4 @@
1
- import chalk from 'chalk';
1
+ import _chalk from 'chalk';
2
2
 
3
3
  import type { BasicOperation } from '../levenshtein';
4
4
  import type { ParsedTypeDetailed } from './layout';
@@ -8,13 +8,18 @@ import { indent } from '../utils/indent';
8
8
  import { assert } from '../utils/assert';
9
9
 
10
10
  export class LayoutCompatibilityReport {
11
- readonly pass: boolean;
11
+ constructor(readonly ops: StorageOperation<StorageItem>[]) {}
12
12
 
13
- constructor(readonly ops: StorageOperation<StorageItem>[]) {
14
- this.pass = ops.length === 0;
13
+ get ok(): boolean {
14
+ return this.pass;
15
15
  }
16
16
 
17
- explain(): string {
17
+ get pass(): boolean {
18
+ return this.ops.length === 0;
19
+ }
20
+
21
+ explain(color = true): string {
22
+ const chalk = new _chalk.Instance({ level: color && _chalk.supportsColor ? _chalk.supportsColor.level : 0 });
18
23
  const res = [];
19
24
 
20
25
  for (const op of this.ops) {