@openzeppelin/upgrades-core 1.13.1 → 1.14.2

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 (48) hide show
  1. package/dist/proxy-kind.d.ts +4 -0
  2. package/dist/proxy-kind.d.ts.map +1 -1
  3. package/dist/proxy-kind.js +4 -0
  4. package/dist/proxy-kind.js.map +1 -1
  5. package/dist/standalone.test.js +9 -0
  6. package/dist/standalone.test.js.map +1 -1
  7. package/dist/storage/compare.d.ts +15 -4
  8. package/dist/storage/compare.d.ts.map +1 -1
  9. package/dist/storage/compare.js +49 -4
  10. package/dist/storage/compare.js.map +1 -1
  11. package/dist/storage/extract.d.ts.map +1 -1
  12. package/dist/storage/extract.js +27 -3
  13. package/dist/storage/extract.js.map +1 -1
  14. package/dist/storage/layout.d.ts +14 -0
  15. package/dist/storage/layout.d.ts.map +1 -1
  16. package/dist/storage/layout.js +6 -2
  17. package/dist/storage/layout.js.map +1 -1
  18. package/dist/storage/report-rename-retype.test.d.ts +2 -0
  19. package/dist/storage/report-rename-retype.test.d.ts.map +1 -0
  20. package/dist/storage/report-rename-retype.test.js +93 -0
  21. package/dist/storage/report-rename-retype.test.js.map +1 -0
  22. package/dist/storage/report.d.ts.map +1 -1
  23. package/dist/storage/report.js +32 -2
  24. package/dist/storage/report.js.map +1 -1
  25. package/dist/storage/report.test.js +6 -0
  26. package/dist/storage/report.test.js.map +1 -1
  27. package/dist/storage.test.js +1 -1
  28. package/dist/utils/execall.d.ts +2 -0
  29. package/dist/utils/execall.d.ts.map +1 -0
  30. package/dist/utils/execall.js +17 -0
  31. package/dist/utils/execall.js.map +1 -0
  32. package/package.json +2 -2
  33. package/src/proxy-kind.ts +4 -0
  34. package/src/standalone.test.ts +12 -0
  35. package/src/storage/compare.ts +61 -8
  36. package/src/storage/extract.ts +31 -5
  37. package/src/storage/layout.ts +17 -2
  38. package/src/storage/report-rename-retype.test.ts +106 -0
  39. package/src/storage/report-rename-retype.test.ts.md +44 -0
  40. package/src/storage/report-rename-retype.test.ts.snap +0 -0
  41. package/src/storage/report.test.ts +7 -0
  42. package/src/storage/report.test.ts.md +11 -0
  43. package/src/storage/report.test.ts.snap +0 -0
  44. package/src/storage/report.ts +39 -4
  45. package/src/storage.test.ts +1 -1
  46. package/src/storage.test.ts.md +146 -0
  47. package/src/storage.test.ts.snap +0 -0
  48. package/src/utils/execall.ts +11 -0
@@ -21,8 +21,12 @@ class LayoutCompatibilityReport {
21
21
  explain(color = true) {
22
22
  const chalk = new chalk_1.default.Instance({ level: color && chalk_1.default.supportsColor ? chalk_1.default.supportsColor.level : 0 });
23
23
  const res = [];
24
- for (const op of this.ops) {
24
+ for (const [i, op] of this.ops.entries()) {
25
25
  const src = 'updated' in op ? op.updated.src : op.original.contract;
26
+ // Only print layoutchange if it's the first op, otherwise we assume it will be explained by previous ops.
27
+ if (op.kind === 'layoutchange' && i !== 0) {
28
+ continue;
29
+ }
26
30
  res.push(chalk.bold(src) + ':' + (0, indent_1.indent)(explainStorageOperation(op, { kind: 'layout', allowAppend: true }), 2, 1));
27
31
  }
28
32
  return res.join('\n\n');
@@ -44,6 +48,11 @@ function explainStorageOperation(op, ctx) {
44
48
  return `Renamed ${label(op.original)} to ${label(op.updated)}`;
45
49
  case 'replace':
46
50
  return `Replaced ${label(op.original)} with ${label(op.updated)} of incompatible type`;
51
+ case 'layoutchange': {
52
+ return (`Layout ${op.change.uncertain ? 'could have changed' : 'changed'} for ${label(op.updated)} ` +
53
+ `(${op.original.type.item.label} -> ${op.updated.type.item.label})\n` +
54
+ describeLayoutTransition(op.change)).trimEnd();
55
+ }
47
56
  default: {
48
57
  const title = explainBasicOperation(op, t => t.label);
49
58
  const hints = [];
@@ -73,6 +82,8 @@ function explainStorageOperation(op, ctx) {
73
82
  }
74
83
  function explainTypeChange(ch) {
75
84
  switch (ch.kind) {
85
+ case 'visibility change':
86
+ return `Bad upgrade ${describeTransition(ch.original, ch.updated)}\nDifferent visibility`;
76
87
  case 'obvious mismatch':
77
88
  case 'struct members':
78
89
  case 'enum members':
@@ -141,7 +152,15 @@ function explainTypeChangeDetails(ch) {
141
152
  case 'struct members': {
142
153
  const { allowAppend } = ch;
143
154
  return (`In ${ch.updated.item.label}\n` +
144
- (0, itemize_1.itemize)(...ch.ops.map(op => explainStorageOperation(op, { kind: 'struct', allowAppend }))));
155
+ (0, itemize_1.itemize)(...ch.ops.flatMap((op, i) => {
156
+ if (op.kind === 'layoutchange' && i !== 0) {
157
+ // Only print layoutchange if it's the first op, otherwise we assume it will be explained by previous ops.
158
+ return [];
159
+ }
160
+ else {
161
+ return [explainStorageOperation(op, { kind: 'struct', allowAppend })];
162
+ }
163
+ })));
145
164
  }
146
165
  case 'enum members':
147
166
  return `In ${ch.updated.item.label}\n` + (0, itemize_1.itemize)(...ch.ops.map(explainEnumOperation));
@@ -175,6 +194,17 @@ function describeTransition(original, updated) {
175
194
  return `from ${originalLabel} to ${updatedLabel}`;
176
195
  }
177
196
  }
197
+ function describeLayoutTransition(change) {
198
+ const res = [];
199
+ for (const k of ['slot', 'offset', 'bytes']) {
200
+ const ch = change[k];
201
+ if (ch) {
202
+ const label = (k === 'bytes' ? 'number of bytes' : k).replace(/^./, c => c.toUpperCase());
203
+ res.push(`${label} changed from ${ch.from} to ${ch.to}`);
204
+ }
205
+ }
206
+ return (0, itemize_1.itemize)(...res);
207
+ }
178
208
  function label(variable) {
179
209
  return '`' + variable.label + '`';
180
210
  }
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/storage/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/storage/report.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,12 @@ test('obvious mismatch', t => {
49
49
  const report = getReport(v1, v2);
50
50
  t.snapshot(report.explain());
51
51
  });
52
+ test('function visibility change', t => {
53
+ const v1 = t.context.extractStorageLayout('StorageUpgrade_FunctionType_Visibility_V1');
54
+ const v2 = t.context.extractStorageLayout('StorageUpgrade_FunctionType_Visibility_V2_Bad');
55
+ const report = getReport(v1, v2);
56
+ t.snapshot(report.explain());
57
+ });
52
58
  test('array', t => {
53
59
  const v1 = t.context.extractStorageLayout('StorageUpgrade_Array_V1');
54
60
  const v2 = t.context.extractStorageLayout('StorageUpgrade_Array_V2_Bad');
@@ -1 +1 @@
1
- {"version":3,"file":"report.test.js","sourceRoot":"","sources":["../../src/storage/report.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.test.js","sourceRoot":"","sources":["../../src/storage/report.test.ts"],"names":[],"mappings":"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"}
@@ -160,7 +160,7 @@ test('storage upgrade with structs', t => {
160
160
  change: {
161
161
  kind: 'struct members',
162
162
  ops: {
163
- length: 1,
163
+ length: 2,
164
164
  0: { kind: 'delete' },
165
165
  },
166
166
  },
@@ -0,0 +1,2 @@
1
+ export declare function execall(re: RegExp, text: string): Generator<RegExpExecArray, void, unknown>;
2
+ //# sourceMappingURL=execall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execall.d.ts","sourceRoot":"","sources":["../../src/utils/execall.ts"],"names":[],"mappings":"AAAA,wBAAiB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,6CAUhD"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.execall = void 0;
4
+ function* execall(re, text) {
5
+ re = new RegExp(re, re.flags + (re.sticky ? '' : 'y'));
6
+ while (true) {
7
+ const match = re.exec(text);
8
+ if (match && match[0] !== '') {
9
+ yield match;
10
+ }
11
+ else {
12
+ break;
13
+ }
14
+ }
15
+ }
16
+ exports.execall = execall;
17
+ //# sourceMappingURL=execall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execall.js","sourceRoot":"","sources":["../../src/utils/execall.ts"],"names":[],"mappings":";;;AAAA,QAAe,CAAC,CAAC,OAAO,CAAC,EAAU,EAAE,IAAY;IAC/C,EAAE,GAAG,IAAI,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,OAAO,IAAI,EAAE;QACX,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5B,MAAM,KAAK,CAAC;SACb;aAAM;YACL,MAAM;SACP;KACF;AACH,CAAC;AAVD,0BAUC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/upgrades-core",
3
- "version": "1.13.1",
3
+ "version": "1.14.2",
4
4
  "description": "",
5
5
  "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
6
6
  "license": "MIT",
@@ -59,5 +59,5 @@
59
59
  "proper-lockfile": "^4.1.1",
60
60
  "solidity-ast": "^0.4.15"
61
61
  },
62
- "gitHead": "986cfff65ecbe4706ff62391ddc22ba31c547eb8"
62
+ "gitHead": "c33ebd898c989fa96c858b14ea6ead63427d5e55"
63
63
  }
package/src/proxy-kind.ts CHANGED
@@ -62,6 +62,10 @@ export async function processProxyKind(
62
62
  /**
63
63
  * Detects the kind of proxy at an address by reading its ERC 1967 storage slots.
64
64
  *
65
+ * @deprecated Not reliable since UUPS proxies can have admin storage slot set, which causes
66
+ * this function to treat it as transparent. Instead, if implementation contract signatures are
67
+ * available, infer the proxy kind using `inferProxyKind` instead.
68
+ *
65
69
  * @param provider the Ethereum provider
66
70
  * @param proxyAddress the proxy address
67
71
  * @returns the proxy kind
@@ -38,3 +38,15 @@ test('reports storage upgrade errors', t => {
38
38
  const badReport = v1.getStorageUpgradeReport(v2Bad);
39
39
  t.false(badReport.ok);
40
40
  });
41
+
42
+ test('dont report renamed version update', t => {
43
+ const v1 = new UpgradeableContract('StandaloneRenameV1', t.context.solcInput, t.context.solcOutput);
44
+
45
+ const v2 = new UpgradeableContract('StandaloneRenameV2', t.context.solcInput, t.context.solcOutput);
46
+ const goodReport = v1.getStorageUpgradeReport(v2);
47
+ t.true(goodReport.ok);
48
+
49
+ const v3 = new UpgradeableContract('StandaloneRenameV3', t.context.solcInput, t.context.solcOutput);
50
+ const goodReport2 = v2.getStorageUpgradeReport(v3);
51
+ t.true(goodReport2.ok);
52
+ });
@@ -1,7 +1,7 @@
1
1
  import { levenshtein, Operation } from '../levenshtein';
2
- import { ParsedTypeDetailed, StorageItem as _StorageItem } from './layout';
2
+ import { hasLayout, ParsedTypeDetailed, isEnumMembers, isStructMembers } from './layout';
3
3
  import { UpgradesError } from '../error';
4
- import { StructMember as _StructMember, isEnumMembers, isStructMembers } from './layout';
4
+ import { StorageItem as _StorageItem, StructMember as _StructMember, StorageField as _StorageField } from './layout';
5
5
  import { LayoutCompatibilityReport } from './report';
6
6
  import { assert } from '../utils/assert';
7
7
  import { isValueType } from '../utils/is-value-type';
@@ -9,7 +9,7 @@ import { isValueType } from '../utils/is-value-type';
9
9
  export type StorageItem = _StorageItem<ParsedTypeDetailed>;
10
10
  type StructMember = _StructMember<ParsedTypeDetailed>;
11
11
 
12
- export type StorageField = StorageItem | StructMember;
12
+ export type StorageField = _StorageField<ParsedTypeDetailed>;
13
13
  export type StorageOperation<F extends StorageField> = Operation<F, StorageFieldChange<F>>;
14
14
 
15
15
  export type EnumOperation = Operation<string, { kind: 'replace'; original: string; updated: string }>;
@@ -17,6 +17,7 @@ export type EnumOperation = Operation<string, { kind: 'replace'; original: strin
17
17
  type StorageFieldChange<F extends StorageField> = (
18
18
  | { kind: 'replace' | 'rename' }
19
19
  | { kind: 'typechange'; change: TypeChange }
20
+ | { kind: 'layoutchange'; change: LayoutChange }
20
21
  ) & {
21
22
  original: F;
22
23
  updated: F;
@@ -28,6 +29,7 @@ export type TypeChange = (
28
29
  | 'obvious mismatch'
29
30
  | 'unknown'
30
31
  | 'array grow'
32
+ | 'visibility change'
31
33
  | 'array shrink'
32
34
  | 'array dynamic'
33
35
  | 'enum resize'
@@ -51,6 +53,13 @@ export type TypeChange = (
51
53
  updated: ParsedTypeDetailed;
52
54
  };
53
55
 
56
+ export interface LayoutChange {
57
+ uncertain?: boolean;
58
+ slot?: Record<'from' | 'to', string>;
59
+ offset?: Record<'from' | 'to', number>;
60
+ bytes?: Record<'from' | 'to', string>;
61
+ }
62
+
54
63
  export class StorageLayoutComparator {
55
64
  hasAllowedUncheckedCustomTypes = false;
56
65
 
@@ -78,16 +87,57 @@ export class StorageLayoutComparator {
78
87
  }
79
88
  }
80
89
 
81
- getFieldChange<F extends StorageField>(original: F, updated: F): StorageFieldChange<F> | undefined {
82
- const nameChange = !this.unsafeAllowRenames && original.label !== updated.label;
83
- const typeChange = this.getTypeChange(original.type, updated.type, { allowAppend: false });
90
+ getVisibilityChange(original: ParsedTypeDetailed, updated: ParsedTypeDetailed): TypeChange | undefined {
91
+ const re = /^t_function_(internal|external)/;
92
+ const originalVisibility = original.head.match(re);
93
+ const updatedVisibility = updated.head.match(re);
94
+ assert(originalVisibility && updatedVisibility);
95
+ if (originalVisibility[0] !== updatedVisibility[0]) {
96
+ return { kind: 'visibility change', original, updated };
97
+ }
98
+ }
84
99
 
85
- if (typeChange && nameChange) {
100
+ getFieldChange<F extends StorageField>(original: F, updated: F): StorageFieldChange<F> | undefined {
101
+ const nameChange =
102
+ !this.unsafeAllowRenames &&
103
+ original.label !== updated.renamedFrom &&
104
+ (updated.label !== original.label ||
105
+ (updated.renamedFrom !== undefined && updated.renamedFrom !== original.renamedFrom));
106
+ const retypedFromOriginal = original.type.item.label === updated.retypedFrom?.trim();
107
+ const typeChange = !retypedFromOriginal && this.getTypeChange(original.type, updated.type, { allowAppend: false });
108
+ const layoutChange = this.getLayoutChange(original, updated);
109
+
110
+ if (updated.retypedFrom && layoutChange) {
111
+ return { kind: 'layoutchange', original, updated, change: layoutChange };
112
+ } else if (typeChange && nameChange) {
86
113
  return { kind: 'replace', original, updated };
87
114
  } else if (nameChange) {
88
115
  return { kind: 'rename', original, updated };
89
116
  } else if (typeChange) {
90
117
  return { kind: 'typechange', change: typeChange, original, updated };
118
+ } else if (layoutChange && !layoutChange.uncertain) {
119
+ // Any layout change should be caught earlier as a type change, but we
120
+ // add this check as a safety fallback.
121
+ return { kind: 'layoutchange', original, updated, change: layoutChange };
122
+ }
123
+ }
124
+
125
+ getLayoutChange(original: StorageField, updated: StorageField): LayoutChange | undefined {
126
+ const validPair = ['uint8', 'bool'];
127
+ const knownCompatibleTypes =
128
+ validPair.includes(original.type.item.label) && validPair.includes(updated.type.item.label);
129
+ if (original.type.item.label == updated.type.item.label || knownCompatibleTypes) {
130
+ return undefined;
131
+ } else if (hasLayout(original) && hasLayout(updated)) {
132
+ const change = <T>(from: T, to: T) => (from === to ? undefined : { from, to });
133
+ const slot = change(original.slot, updated.slot);
134
+ const offset = change(original.offset, updated.offset);
135
+ const bytes = change(original.type.item.numberOfBytes, updated.type.item.numberOfBytes);
136
+ if (slot || offset || bytes) {
137
+ return { slot, offset, bytes };
138
+ }
139
+ } else {
140
+ return { uncertain: true };
91
141
  }
92
142
  }
93
143
 
@@ -97,7 +147,6 @@ export class StorageLayoutComparator {
97
147
  { allowAppend }: { allowAppend: boolean },
98
148
  ): TypeChange | undefined {
99
149
  const key = JSON.stringify({ original: original.id, updated: updated.id, allowAppend });
100
-
101
150
  if (this.cache.has(key)) {
102
151
  return this.cache.get(key);
103
152
  }
@@ -121,6 +170,10 @@ export class StorageLayoutComparator {
121
170
  updated: ParsedTypeDetailed,
122
171
  { allowAppend }: { allowAppend: boolean },
123
172
  ): TypeChange | undefined {
173
+ if (updated.head.startsWith('t_function')) {
174
+ return this.getVisibilityChange(original, updated);
175
+ }
176
+
124
177
  if (original.head !== updated.head) {
125
178
  return { kind: 'obvious mismatch', original, updated };
126
179
  }
@@ -13,6 +13,7 @@ import { SrcDecoder } from '../src-decoder';
13
13
  import { ASTDereferencer } from '../ast-dereferencer';
14
14
  import { mapValues } from '../utils/map-values';
15
15
  import { pick } from '../utils/pick';
16
+ import { execall } from '../utils/execall';
16
17
 
17
18
  const currentLayoutVersion = '1.1';
18
19
 
@@ -31,7 +32,10 @@ export function extractStorageLayout(
31
32
  layout.types = mapValues(storageLayout.types, m => {
32
33
  return {
33
34
  label: m.label,
34
- members: m.members?.map(m => (typeof m === 'string' ? m : pick(m, ['label', 'type']))) as TypeItem['members'],
35
+ members: m.members?.map(m =>
36
+ typeof m === 'string' ? m : pick(m, ['label', 'type', 'offset', 'slot']),
37
+ ) as TypeItem['members'],
38
+ numberOfBytes: m.numberOfBytes,
35
39
  };
36
40
  });
37
41
 
@@ -39,11 +43,12 @@ export function extractStorageLayout(
39
43
  const origin = getOriginContract(contractDef, storage.astId, deref);
40
44
  assert(origin, `Did not find variable declaration node for '${storage.label}'`);
41
45
  const { varDecl, contract } = origin;
46
+ const { renamedFrom, retypedFrom } = getRetypedRenamed(varDecl);
42
47
  // Solc layout doesn't bring members for enums so we get them using the ast method
43
48
  loadLayoutType(varDecl, layout, deref);
44
49
  const { label, offset, slot, type } = storage;
45
50
  const src = decodeSrc(varDecl);
46
- layout.storage.push({ label, offset, slot, type, contract, src });
51
+ layout.storage.push({ label, offset, slot, type, contract, src, retypedFrom, renamedFrom });
47
52
  layout.flat = true;
48
53
  }
49
54
  } else {
@@ -51,12 +56,14 @@ export function extractStorageLayout(
51
56
  if (isNodeType('VariableDeclaration', varDecl)) {
52
57
  if (!varDecl.constant && varDecl.mutability !== 'immutable') {
53
58
  const type = normalizeTypeIdentifier(typeDescriptions(varDecl).typeIdentifier);
54
-
59
+ const { renamedFrom, retypedFrom } = getRetypedRenamed(varDecl);
55
60
  layout.storage.push({
56
61
  contract: contractDef.name,
57
62
  label: varDecl.name,
58
63
  type,
59
64
  src: decodeSrc(varDecl),
65
+ retypedFrom,
66
+ renamedFrom,
60
67
  });
61
68
 
62
69
  loadLayoutType(varDecl, layout, deref);
@@ -101,9 +108,8 @@ function getTypeMembers(typeDef: StructDefinition | EnumDefinition): TypeItem['m
101
108
  }
102
109
 
103
110
  function getOriginContract(contract: ContractDefinition, astId: number | undefined, deref: ASTDereferencer) {
104
- for (const id of contract.linearizedBaseContracts.reverse()) {
111
+ for (const id of contract.linearizedBaseContracts) {
105
112
  const parentContract = deref(['ContractDefinition'], id);
106
-
107
113
  const varDecl = parentContract.nodes.find(n => n.id == astId);
108
114
  if (varDecl && isNodeType('VariableDeclaration', varDecl)) {
109
115
  return { varDecl, contract: parentContract.name };
@@ -141,3 +147,23 @@ function loadLayoutType(varDecl: VariableDeclaration, layout: StorageLayout, der
141
147
  }
142
148
  }
143
149
  }
150
+
151
+ function getRetypedRenamed(varDecl: VariableDeclaration) {
152
+ let retypedFrom, renamedFrom;
153
+ if ('documentation' in varDecl) {
154
+ const docs = typeof varDecl.documentation === 'string' ? varDecl.documentation : varDecl.documentation?.text ?? '';
155
+ for (const { groups } of execall(
156
+ /^\s*(?:@(?<title>\w+)(?::(?<tag>[a-z][a-z-]*))? )?(?<args>(?:(?!^\s@\w+)[^])*)/m,
157
+ docs,
158
+ )) {
159
+ if (groups?.title === 'custom') {
160
+ if (groups.tag === 'oz-retyped-from') {
161
+ retypedFrom = groups.args;
162
+ } else if (groups.tag === 'oz-renamed-from') {
163
+ renamedFrom = groups.args;
164
+ }
165
+ }
166
+ }
167
+ }
168
+ return { retypedFrom, renamedFrom };
169
+ }
@@ -12,6 +12,8 @@ export interface StorageLayout {
12
12
  flat?: boolean;
13
13
  }
14
14
 
15
+ export type StorageField<Type = string> = StorageItem<Type> | StructMember<Type>;
16
+
15
17
  export interface StorageItem<Type = string> {
16
18
  astId?: number;
17
19
  contract: string;
@@ -20,11 +22,14 @@ export interface StorageItem<Type = string> {
20
22
  src: string;
21
23
  offset?: number;
22
24
  slot?: string;
25
+ retypedFrom?: string;
26
+ renamedFrom?: string;
23
27
  }
24
28
 
25
29
  export interface TypeItem<Type = string> {
26
30
  label: string;
27
31
  members?: TypeItemMembers<Type>;
32
+ numberOfBytes?: string;
28
33
  }
29
34
 
30
35
  export type TypeItemMembers<Type = string> = StructMember<Type>[] | EnumMember[];
@@ -32,6 +37,10 @@ export type TypeItemMembers<Type = string> = StructMember<Type>[] | EnumMember[]
32
37
  export interface StructMember<Type = string> {
33
38
  label: string;
34
39
  type: Type;
40
+ retypedFrom?: string;
41
+ renamedFrom?: string;
42
+ offset?: number;
43
+ slot?: string;
35
44
  }
36
45
 
37
46
  export type EnumMember = string;
@@ -46,7 +55,6 @@ type Replace<T, K extends string, V> = Omit<T, K> & Record<K, V>;
46
55
 
47
56
  export function getDetailedLayout(layout: StorageLayout): StorageItem<ParsedTypeDetailed>[] {
48
57
  const cache: Record<string, ParsedTypeDetailed> = {};
49
-
50
58
  return layout.storage.map(parseWithDetails);
51
59
 
52
60
  function parseWithDetails<I extends { type: string }>(item: I): Replace<I, 'type', ParsedTypeDetailed> {
@@ -75,7 +83,7 @@ export function getDetailedLayout(layout: StorageLayout): StorageItem<ParsedType
75
83
  cache[parsed.id] = detailed;
76
84
 
77
85
  detailed.args = parsed.args?.map(addDetailsToParsedType);
78
- detailed.rets = parsed.args?.map(addDetailsToParsedType);
86
+ detailed.rets = parsed.rets?.map(addDetailsToParsedType);
79
87
  detailed.item.members =
80
88
  item?.members && (isStructMembers(item?.members) ? item.members.map(parseWithDetails) : item?.members);
81
89
 
@@ -90,3 +98,10 @@ export function isEnumMembers<T>(members: TypeItemMembers<T>): members is EnumMe
90
98
  export function isStructMembers<T>(members: TypeItemMembers<T>): members is StructMember<T>[] {
91
99
  return members.length === 0 || typeof members[0] === 'object';
92
100
  }
101
+
102
+ export type StorageFieldWithLayout = StorageField<ParsedTypeDetailed> &
103
+ Required<Pick<StorageField, 'offset' | 'slot'>> & { type: { item: Required<Pick<TypeItem, 'numberOfBytes'>> } };
104
+
105
+ export function hasLayout(field: StorageField<ParsedTypeDetailed>): field is StorageFieldWithLayout {
106
+ return field.offset !== undefined && field.slot !== undefined && field.type.item.numberOfBytes !== undefined;
107
+ }
@@ -0,0 +1,106 @@
1
+ import _test, { TestFn } from 'ava';
2
+ import { ContractDefinition } from 'solidity-ast';
3
+ import { ASTDereferencer, findAll } from 'solidity-ast/utils';
4
+ import { artifacts } from 'hardhat';
5
+ import { astDereferencer } from '../ast-dereferencer';
6
+ import { extractStorageLayout } from './extract';
7
+ import { StorageLayoutComparator } from './compare';
8
+ import { StorageLayout, getDetailedLayout } from './layout';
9
+
10
+ interface Context {
11
+ extractStorageLayout: (contract: string) => ReturnType<typeof extractStorageLayout>;
12
+ }
13
+
14
+ const test = _test as TestFn<Context>;
15
+
16
+ const dummyDecodeSrc = () => 'file.sol:1';
17
+ const testContracts = [
18
+ 'contracts/test/RenamedRetyped.sol:RenameV1',
19
+ 'contracts/test/RenamedRetyped.sol:RenameV2',
20
+ 'contracts/test/RenamedRetyped.sol:RetypeV1',
21
+ 'contracts/test/RenamedRetyped.sol:RetypeV2',
22
+ 'contracts/test/RenamedRetyped.sol:WronglyReportedRetypeV3',
23
+ 'contracts/test/RenamedRetyped.sol:MissmatchingTypeRetypeV4',
24
+ 'contracts/test/RenamedRetyped.sol:ConfusingRetypeV1',
25
+ 'contracts/test/RenamedRetyped.sol:ConfusingRetypeV2',
26
+ 'contracts/test/RenamedRetyped.sol:NonHardcodedRetypeV1',
27
+ 'contracts/test/RenamedRetyped.sol:NonHardcodedRetypeV2',
28
+ ];
29
+
30
+ test.before(async t => {
31
+ const contracts: Record<string, ContractDefinition> = {};
32
+ const deref: Record<string, ASTDereferencer> = {};
33
+ const storageLayout: Record<string, StorageLayout> = {};
34
+ for (const contract of testContracts) {
35
+ const buildInfo = await artifacts.getBuildInfo(contract);
36
+ if (buildInfo === undefined) {
37
+ throw new Error(`Build info not found for contract ${contract}`);
38
+ }
39
+ const solcOutput = buildInfo.output;
40
+ for (const def of findAll('ContractDefinition', solcOutput.sources['contracts/test/RenamedRetyped.sol'].ast)) {
41
+ contracts[def.name] = def;
42
+ deref[def.name] = astDereferencer(solcOutput);
43
+ storageLayout[def.name] = (
44
+ solcOutput.contracts['contracts/test/RenamedRetyped.sol'][def.name] as any
45
+ ).storageLayout;
46
+ }
47
+ }
48
+
49
+ t.context.extractStorageLayout = name =>
50
+ extractStorageLayout(contracts[name], dummyDecodeSrc, deref[name], storageLayout[name]);
51
+ });
52
+
53
+ function getReport(original: StorageLayout, updated: StorageLayout) {
54
+ const originalDetailed = getDetailedLayout(original);
55
+ const updatedDetailed = getDetailedLayout(updated);
56
+ const comparator = new StorageLayoutComparator();
57
+ return comparator.compareLayouts(originalDetailed, updatedDetailed);
58
+ }
59
+
60
+ test('succesful rename', t => {
61
+ const v1 = t.context.extractStorageLayout('RenameV1');
62
+ const v2 = t.context.extractStorageLayout('RenameV2');
63
+ const report = getReport(v1, v2);
64
+ t.true(report.ok);
65
+ t.snapshot(report.explain());
66
+ });
67
+
68
+ test('succesful retype', t => {
69
+ const v1 = t.context.extractStorageLayout('RetypeV1');
70
+ const v2 = t.context.extractStorageLayout('RetypeV2');
71
+ const report = getReport(v1, v2);
72
+ t.true(report.ok);
73
+ t.snapshot(report.explain());
74
+ });
75
+
76
+ test('wrongly reported retype', t => {
77
+ const v1 = t.context.extractStorageLayout('RetypeV1');
78
+ const v2 = t.context.extractStorageLayout('WronglyReportedRetypeV3');
79
+ const report = getReport(v1, v2);
80
+ t.false(report.ok);
81
+ t.snapshot(report.explain());
82
+ });
83
+
84
+ test('rightly reported retype but incompatible new type', t => {
85
+ const v1 = t.context.extractStorageLayout('RetypeV1');
86
+ const v2 = t.context.extractStorageLayout('MissmatchingTypeRetypeV4');
87
+ const report = getReport(v1, v2);
88
+ t.false(report.ok);
89
+ t.snapshot(report.explain());
90
+ });
91
+
92
+ test('confusing bad retype', t => {
93
+ const v1 = t.context.extractStorageLayout('ConfusingRetypeV1');
94
+ const v2 = t.context.extractStorageLayout('ConfusingRetypeV2');
95
+ const report = getReport(v1, v2);
96
+ t.false(report.ok);
97
+ t.snapshot(report.explain());
98
+ });
99
+
100
+ test('non-hardcoded retype', t => {
101
+ const v1 = t.context.extractStorageLayout('NonHardcodedRetypeV1');
102
+ const v2 = t.context.extractStorageLayout('NonHardcodedRetypeV2');
103
+ const report = getReport(v1, v2);
104
+ t.true(report.ok);
105
+ t.snapshot(report.explain());
106
+ });
@@ -0,0 +1,44 @@
1
+ # Snapshot report for `src/storage/report-rename-retype.test.ts`
2
+
3
+ The actual snapshot is saved in `report-rename-retype.test.ts.snap`.
4
+
5
+ Generated by [AVA](https://avajs.dev).
6
+
7
+ ## succesful rename
8
+
9
+ > Snapshot 1
10
+
11
+ ''
12
+
13
+ ## succesful retype
14
+
15
+ > Snapshot 1
16
+
17
+ ''
18
+
19
+ ## wrongly reported retype
20
+
21
+ > Snapshot 1
22
+
23
+ `file.sol:1: Upgraded \`x\` to an incompatible type␊
24
+ - Bad upgrade from bool to uint8`
25
+
26
+ ## rightly reported retype but incompatible new type
27
+
28
+ > Snapshot 1
29
+
30
+ `file.sol:1: Layout changed for \`x\` (bool -> bytes32)␊
31
+ - Number of bytes changed from 1 to 32`
32
+
33
+ ## confusing bad retype
34
+
35
+ > Snapshot 1
36
+
37
+ `file.sol:1: Upgraded \`x\` to an incompatible type␊
38
+ - Bad upgrade from bool to uint8`
39
+
40
+ ## non-hardcoded retype
41
+
42
+ > Snapshot 1
43
+
44
+ ''