@openzeppelin/upgrades-core 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.dbg.json +1 -1
- package/dist/add-proxy-to-manifest.d.ts +3 -0
- package/dist/add-proxy-to-manifest.d.ts.map +1 -0
- package/dist/add-proxy-to-manifest.js +15 -0
- package/dist/add-proxy-to-manifest.js.map +1 -0
- package/dist/deployment.d.ts +21 -1
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +65 -15
- package/dist/deployment.js.map +1 -1
- package/dist/eip-1967-type.d.ts +1 -0
- package/dist/eip-1967-type.d.ts.map +1 -1
- package/dist/eip-1967-type.js +6 -1
- package/dist/eip-1967-type.js.map +1 -1
- package/dist/eip-1967.d.ts +1 -0
- package/dist/eip-1967.d.ts.map +1 -1
- package/dist/eip-1967.js +3 -2
- package/dist/eip-1967.js.map +1 -1
- package/dist/impl-address.js +1 -1
- package/dist/impl-address.js.map +1 -1
- package/dist/impl-store.d.ts +22 -2
- package/dist/impl-store.d.ts.map +1 -1
- package/dist/impl-store.js +59 -15
- package/dist/impl-store.js.map +1 -1
- package/dist/impl-store.test.js +24 -0
- package/dist/impl-store.test.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest-storage-layout.d.ts.map +1 -1
- package/dist/manifest-storage-layout.js +3 -2
- package/dist/manifest-storage-layout.js.map +1 -1
- package/dist/manifest-storage-layout.test.js.map +1 -1
- package/dist/manifest.d.ts +2 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +6 -4
- package/dist/manifest.js.map +1 -1
- package/dist/manifest.test.js +32 -0
- package/dist/manifest.test.js.map +1 -1
- package/dist/provider.d.ts +1 -0
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +6 -2
- package/dist/provider.js.map +1 -1
- package/dist/proxy-kind.d.ts +9 -0
- package/dist/proxy-kind.d.ts.map +1 -1
- package/dist/proxy-kind.js +27 -1
- package/dist/proxy-kind.js.map +1 -1
- package/dist/scripts/migrate-oz-cli-project.test.js +1 -1
- package/dist/scripts/migrate-oz-cli-project.test.js.map +1 -1
- package/dist/solc-api.d.ts +5 -0
- package/dist/solc-api.d.ts.map +1 -1
- package/dist/standalone.test.js.map +1 -1
- package/dist/storage/extract.d.ts +1 -1
- package/dist/storage/extract.d.ts.map +1 -1
- package/dist/storage/extract.js +76 -38
- package/dist/storage/extract.js.map +1 -1
- package/dist/storage/layout.d.ts +4 -0
- package/dist/storage/layout.d.ts.map +1 -1
- package/dist/storage/layout.js.map +1 -1
- package/dist/storage/report.test.js.map +1 -1
- package/dist/storage.test.js +1 -1
- package/dist/storage.test.js.map +1 -1
- package/dist/usage-error.d.ts +3 -0
- package/dist/usage-error.d.ts.map +1 -1
- package/dist/usage-error.js +7 -1
- package/dist/usage-error.js.map +1 -1
- package/dist/validate/query.d.ts.map +1 -1
- package/dist/validate/query.js +10 -5
- package/dist/validate/query.js.map +1 -1
- package/dist/validate/run.d.ts.map +1 -1
- package/dist/validate/run.js +1 -1
- package/dist/validate/run.js.map +1 -1
- package/dist/validate.test.js.map +1 -1
- package/package.json +4 -4
- package/src/add-proxy-to-manifest.ts +12 -0
- package/src/deployment.ts +81 -14
- package/src/eip-1967-type.ts +7 -0
- package/src/eip-1967.ts +4 -3
- package/src/impl-address.ts +1 -1
- package/src/impl-store.test.ts +33 -1
- package/src/impl-store.ts +69 -12
- package/src/index.ts +22 -4
- package/src/manifest-storage-layout.test.ts +3 -2
- package/src/manifest-storage-layout.ts +8 -3
- package/src/manifest.test.ts +34 -1
- package/src/manifest.ts +9 -4
- package/src/provider.ts +5 -1
- package/src/proxy-kind.ts +24 -1
- package/src/scripts/migrate-oz-cli-project.test.ts +1 -1
- package/src/scripts/migrate-oz-cli-project.test.ts.snap +0 -0
- package/src/solc-api.ts +5 -0
- package/src/standalone.test.ts +2 -2
- package/src/storage/extract.ts +98 -52
- package/src/storage/layout.ts +4 -0
- package/src/storage/report.test.ts +2 -2
- package/src/storage/report.test.ts.snap +0 -0
- package/src/storage.test.ts +3 -3
- package/src/storage.test.ts.snap +0 -0
- package/src/usage-error.ts +9 -0
- package/src/utils/parse-type-id.test.ts.md +106 -106
- package/src/utils/parse-type-id.test.ts.snap +0 -0
- package/src/validate/query.ts +9 -5
- package/src/validate/run.ts +6 -1
- package/src/validate.test.ts +2 -2
package/src/standalone.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _test, {
|
|
1
|
+
import _test, { TestFn } from 'ava';
|
|
2
2
|
import { artifacts } from 'hardhat';
|
|
3
3
|
|
|
4
4
|
import { SolcInput, SolcOutput } from './solc-api';
|
|
@@ -9,7 +9,7 @@ interface Context {
|
|
|
9
9
|
solcOutput: SolcOutput;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const test = _test as
|
|
12
|
+
const test = _test as TestFn<Context>;
|
|
13
13
|
|
|
14
14
|
test.before(async t => {
|
|
15
15
|
const buildInfo = await artifacts.getBuildInfo('contracts/test/Standalone.sol:StandaloneV1');
|
package/src/storage/extract.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ContractDefinition,
|
|
4
|
+
StructDefinition,
|
|
5
|
+
EnumDefinition,
|
|
6
|
+
TypeDescriptions,
|
|
7
|
+
VariableDeclaration,
|
|
8
|
+
} from 'solidity-ast';
|
|
3
9
|
import { isNodeType, findAll } from 'solidity-ast/utils';
|
|
4
|
-
|
|
5
10
|
import { StorageLayout, TypeItem } from './layout';
|
|
6
11
|
import { normalizeTypeIdentifier } from '../utils/type-id';
|
|
7
12
|
import { SrcDecoder } from '../src-decoder';
|
|
8
13
|
import { ASTDereferencer } from '../ast-dereferencer';
|
|
14
|
+
import { mapValues } from '../utils/map-values';
|
|
15
|
+
import { pick } from '../utils/pick';
|
|
9
16
|
|
|
10
17
|
const currentLayoutVersion = '1.1';
|
|
11
18
|
|
|
@@ -17,62 +24,48 @@ export function extractStorageLayout(
|
|
|
17
24
|
contractDef: ContractDefinition,
|
|
18
25
|
decodeSrc: SrcDecoder,
|
|
19
26
|
deref: ASTDereferencer,
|
|
27
|
+
storageLayout?: StorageLayout | undefined,
|
|
20
28
|
): StorageLayout {
|
|
21
|
-
const layout: StorageLayout = { storage: [], types: {}, layoutVersion: currentLayoutVersion };
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
const layout: StorageLayout = { storage: [], types: {}, layoutVersion: currentLayoutVersion, flat: false };
|
|
30
|
+
if (storageLayout !== undefined) {
|
|
31
|
+
layout.types = mapValues(storageLayout.types, m => {
|
|
32
|
+
return {
|
|
33
|
+
label: m.label,
|
|
34
|
+
members: m.members?.map(m => (typeof m === 'string' ? m : pick(m, ['label', 'type']))) as TypeItem['members'],
|
|
35
|
+
};
|
|
36
|
+
});
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
layout
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let members;
|
|
57
|
-
|
|
58
|
-
if ('referencedDeclaration' in typeName && !/^t_contract\b/.test(type)) {
|
|
59
|
-
const typeDef = derefUserDefinedType(typeName.referencedDeclaration);
|
|
60
|
-
members = getTypeMembers(typeDef);
|
|
61
|
-
// Recursively look for the types referenced in this definition and add them to the queue.
|
|
62
|
-
for (const typeName of findTypeNames(typeDef)) {
|
|
63
|
-
const { typeIdentifier } = typeDescriptions(typeName);
|
|
64
|
-
if (!typeNames.has(typeIdentifier)) {
|
|
65
|
-
typeNames.set(typeIdentifier, typeName);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
layout.types[type] = { label, members };
|
|
38
|
+
for (const storage of storageLayout.storage) {
|
|
39
|
+
const origin = getOriginContract(contractDef, storage.astId, deref);
|
|
40
|
+
|
|
41
|
+
if (origin) {
|
|
42
|
+
const [varDecl, contract] = origin;
|
|
43
|
+
// Solc layout doesn't bring members for enums so we get them using the ast method
|
|
44
|
+
loadLayoutType(varDecl, layout, deref);
|
|
45
|
+
const { label, offset, slot, type } = storage;
|
|
46
|
+
const src = decodeSrc(varDecl);
|
|
47
|
+
layout.storage.push({ label, offset, slot, type, contract, src });
|
|
48
|
+
layout.flat = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
for (const varDecl of contractDef.nodes) {
|
|
53
|
+
if (isNodeType('VariableDeclaration', varDecl)) {
|
|
54
|
+
if (!varDecl.constant && varDecl.mutability !== 'immutable') {
|
|
55
|
+
const type = normalizeTypeIdentifier(typeDescriptions(varDecl).typeIdentifier);
|
|
56
|
+
|
|
57
|
+
layout.storage.push({
|
|
58
|
+
contract: contractDef.name,
|
|
59
|
+
label: varDecl.name,
|
|
60
|
+
type,
|
|
61
|
+
src: decodeSrc(varDecl),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
loadLayoutType(varDecl, layout, deref);
|
|
71
65
|
}
|
|
72
66
|
}
|
|
73
67
|
}
|
|
74
68
|
}
|
|
75
|
-
|
|
76
69
|
return layout;
|
|
77
70
|
}
|
|
78
71
|
|
|
@@ -108,3 +101,56 @@ function getTypeMembers(typeDef: StructDefinition | EnumDefinition): TypeItem['m
|
|
|
108
101
|
return typeDef.members.map(m => m.name);
|
|
109
102
|
}
|
|
110
103
|
}
|
|
104
|
+
|
|
105
|
+
function getOriginContract(
|
|
106
|
+
contract: ContractDefinition,
|
|
107
|
+
astId: number | undefined,
|
|
108
|
+
deref: ASTDereferencer,
|
|
109
|
+
): undefined | [VariableDeclaration, string] {
|
|
110
|
+
for (const id of contract.linearizedBaseContracts.reverse()) {
|
|
111
|
+
const parentContract = deref(['ContractDefinition'], id);
|
|
112
|
+
|
|
113
|
+
const varDecl = parentContract.nodes.find(n => n.id == astId);
|
|
114
|
+
if (varDecl && isNodeType('VariableDeclaration', varDecl)) {
|
|
115
|
+
return [varDecl, parentContract.name];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function loadLayoutType(varDecl: VariableDeclaration, layout: StorageLayout, deref: ASTDereferencer) {
|
|
121
|
+
// Note: A UserDefinedTypeName can also refer to a ContractDefinition but we won't care about those.
|
|
122
|
+
const derefUserDefinedType = deref(['StructDefinition', 'EnumDefinition']);
|
|
123
|
+
|
|
124
|
+
assert(varDecl.typeName != null);
|
|
125
|
+
|
|
126
|
+
// We will recursively look for all types involved in this variable declaration in order to store their type
|
|
127
|
+
// information. We iterate over a Map that is indexed by typeIdentifier to ensure we visit each type only once.
|
|
128
|
+
// Note that there can be recursive types.
|
|
129
|
+
const typeNames = new Map([...findTypeNames(varDecl.typeName)].map(n => [typeDescriptions(n).typeIdentifier, n]));
|
|
130
|
+
|
|
131
|
+
for (const typeName of typeNames.values()) {
|
|
132
|
+
const { typeIdentifier, typeString: label } = typeDescriptions(typeName);
|
|
133
|
+
|
|
134
|
+
const type = normalizeTypeIdentifier(typeIdentifier);
|
|
135
|
+
const hasMembers = /^t_(enum|struct)\b/.test(type);
|
|
136
|
+
if (type in layout.types && (!hasMembers || layout.types[type].members !== undefined)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let members;
|
|
141
|
+
|
|
142
|
+
if ('referencedDeclaration' in typeName && !/^t_contract\b/.test(type)) {
|
|
143
|
+
const typeDef = derefUserDefinedType(typeName.referencedDeclaration);
|
|
144
|
+
members = getTypeMembers(typeDef);
|
|
145
|
+
// Recursively look for the types referenced in this definition and add them to the queue.
|
|
146
|
+
for (const typeName of findTypeNames(typeDef)) {
|
|
147
|
+
const { typeIdentifier } = typeDescriptions(typeName);
|
|
148
|
+
if (!typeNames.has(typeIdentifier)) {
|
|
149
|
+
typeNames.set(typeIdentifier, typeName);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
layout.types[type] = { label, members };
|
|
155
|
+
}
|
|
156
|
+
}
|
package/src/storage/layout.ts
CHANGED
|
@@ -9,13 +9,17 @@ export interface StorageLayout {
|
|
|
9
9
|
layoutVersion?: string;
|
|
10
10
|
storage: StorageItem[];
|
|
11
11
|
types: Record<string, TypeItem>;
|
|
12
|
+
flat?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export interface StorageItem<Type = string> {
|
|
16
|
+
astId?: number;
|
|
15
17
|
contract: string;
|
|
16
18
|
label: string;
|
|
17
19
|
type: Type;
|
|
18
20
|
src: string;
|
|
21
|
+
offset?: number;
|
|
22
|
+
slot?: string;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export interface TypeItem<Type = string> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _test, {
|
|
1
|
+
import _test, { TestFn } from 'ava';
|
|
2
2
|
import { ContractDefinition } from 'solidity-ast';
|
|
3
3
|
import { findAll } from 'solidity-ast/utils';
|
|
4
4
|
import { artifacts } from 'hardhat';
|
|
@@ -13,7 +13,7 @@ interface Context {
|
|
|
13
13
|
extractStorageLayout: (contract: string) => ReturnType<typeof extractStorageLayout>;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const test = _test as
|
|
16
|
+
const test = _test as TestFn<Context>;
|
|
17
17
|
|
|
18
18
|
const dummyDecodeSrc = () => 'file.sol:1';
|
|
19
19
|
|
|
Binary file
|
package/src/storage.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _test, {
|
|
1
|
+
import _test, { TestFn } from 'ava';
|
|
2
2
|
import { ContractDefinition } from 'solidity-ast';
|
|
3
3
|
import { findAll } from 'solidity-ast/utils';
|
|
4
4
|
import { artifacts } from 'hardhat';
|
|
@@ -14,7 +14,7 @@ interface Context {
|
|
|
14
14
|
extractStorageLayout: (contract: string) => ReturnType<typeof extractStorageLayout>;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const test = _test as
|
|
17
|
+
const test = _test as TestFn<Context>;
|
|
18
18
|
|
|
19
19
|
test.before(async t => {
|
|
20
20
|
const buildInfo = await artifacts.getBuildInfo('contracts/test/Storage.sol:Storage1');
|
|
@@ -344,7 +344,7 @@ test('storage upgrade with recursive type', t => {
|
|
|
344
344
|
const v1 = t.context.extractStorageLayout('StorageUpgrade_Recursive_V1');
|
|
345
345
|
const v2 = t.context.extractStorageLayout('StorageUpgrade_Recursive_V2');
|
|
346
346
|
const e = t.throws(() => getStorageUpgradeErrors(v1, v2));
|
|
347
|
-
t.true(e
|
|
347
|
+
t.true(e?.message.includes('Recursion found'));
|
|
348
348
|
});
|
|
349
349
|
|
|
350
350
|
test('storage upgrade with contract type', t => {
|
package/src/storage.test.ts.snap
CHANGED
|
Binary file
|
package/src/usage-error.ts
CHANGED
|
@@ -51,6 +51,15 @@ export class PrepareUpgradeUnsupportedError extends UpgradesError {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export class ForceImportUnsupportedError extends UpgradesError {
|
|
55
|
+
constructor(proxyOrBeaconAddress: string) {
|
|
56
|
+
super(
|
|
57
|
+
`Contract at address ${proxyOrBeaconAddress} doesn't look like a supported proxy or beacon`,
|
|
58
|
+
() => `Only transparent, UUPS, or beacon proxies or beacons can be used with the forceImport() function.`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
export async function assertNotProxy(provider: EthereumProvider, address: string) {
|
|
55
64
|
if (await isTransparentOrUUPSProxy(provider, address)) {
|
|
56
65
|
throw new UpgradesError(
|
|
@@ -4,40 +4,56 @@ The actual snapshot is saved in `parse-type-id.test.ts.snap`.
|
|
|
4
4
|
|
|
5
5
|
Generated by [AVA](https://avajs.dev).
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## t_uint256
|
|
8
|
+
|
|
9
|
+
> Snapshot 1
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
args: undefined,
|
|
13
|
+
head: 't_uint256',
|
|
14
|
+
id: 't_uint256',
|
|
15
|
+
rets: undefined,
|
|
16
|
+
tail: undefined,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
## t_enum(MyEnum)
|
|
8
20
|
|
|
9
21
|
> Snapshot 1
|
|
10
22
|
|
|
11
23
|
{
|
|
12
24
|
args: [
|
|
13
25
|
{
|
|
14
|
-
args:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
id: 't_uint256',
|
|
19
|
-
rets: undefined,
|
|
20
|
-
tail: undefined,
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
head: 't_function_internal_nonpayable',
|
|
24
|
-
id: 't_function_internal_nonpayable(t_uint256)returns(t_address)',
|
|
25
|
-
rets: [
|
|
26
|
-
{
|
|
27
|
-
args: undefined,
|
|
28
|
-
head: 't_address',
|
|
29
|
-
id: 't_address',
|
|
30
|
-
rets: undefined,
|
|
31
|
-
tail: undefined,
|
|
32
|
-
},
|
|
33
|
-
],
|
|
26
|
+
args: undefined,
|
|
27
|
+
head: 'MyEnum',
|
|
28
|
+
id: 'MyEnum',
|
|
29
|
+
rets: undefined,
|
|
34
30
|
tail: undefined,
|
|
35
31
|
},
|
|
36
32
|
],
|
|
37
|
-
head: '
|
|
38
|
-
id: '
|
|
33
|
+
head: 't_enum',
|
|
34
|
+
id: 't_enum(MyEnum)',
|
|
39
35
|
rets: undefined,
|
|
40
|
-
tail:
|
|
36
|
+
tail: undefined,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
## t_struct(MyComplexStruct)storage
|
|
40
|
+
|
|
41
|
+
> Snapshot 1
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
args: [
|
|
45
|
+
{
|
|
46
|
+
args: undefined,
|
|
47
|
+
head: 'MyComplexStruct',
|
|
48
|
+
id: 'MyComplexStruct',
|
|
49
|
+
rets: undefined,
|
|
50
|
+
tail: undefined,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
head: 't_struct',
|
|
54
|
+
id: 't_struct(MyComplexStruct)storage',
|
|
55
|
+
rets: undefined,
|
|
56
|
+
tail: 'storage',
|
|
41
57
|
}
|
|
42
58
|
|
|
43
59
|
## t_array(t_uint256)3_storage
|
|
@@ -60,7 +76,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
60
76
|
tail: '3_storage',
|
|
61
77
|
}
|
|
62
78
|
|
|
63
|
-
##
|
|
79
|
+
## t_mapping(t_uint256,t_uint256)
|
|
64
80
|
|
|
65
81
|
> Snapshot 1
|
|
66
82
|
|
|
@@ -73,10 +89,44 @@ Generated by [AVA](https://avajs.dev).
|
|
|
73
89
|
rets: undefined,
|
|
74
90
|
tail: undefined,
|
|
75
91
|
},
|
|
92
|
+
{
|
|
93
|
+
args: undefined,
|
|
94
|
+
head: 't_uint256',
|
|
95
|
+
id: 't_uint256',
|
|
96
|
+
rets: undefined,
|
|
97
|
+
tail: undefined,
|
|
98
|
+
},
|
|
76
99
|
],
|
|
77
|
-
head: '
|
|
78
|
-
id: '
|
|
79
|
-
rets:
|
|
100
|
+
head: 't_mapping',
|
|
101
|
+
id: 't_mapping(t_uint256,t_uint256)',
|
|
102
|
+
rets: undefined,
|
|
103
|
+
tail: undefined,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
## t_mapping(unknown,t_uint256)
|
|
107
|
+
|
|
108
|
+
> Snapshot 1
|
|
109
|
+
|
|
110
|
+
{
|
|
111
|
+
args: [
|
|
112
|
+
{
|
|
113
|
+
args: undefined,
|
|
114
|
+
head: 'unknown',
|
|
115
|
+
id: 'unknown',
|
|
116
|
+
rets: undefined,
|
|
117
|
+
tail: undefined,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
args: undefined,
|
|
121
|
+
head: 't_uint256',
|
|
122
|
+
id: 't_uint256',
|
|
123
|
+
rets: undefined,
|
|
124
|
+
tail: undefined,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
head: 't_mapping',
|
|
128
|
+
id: 't_mapping(unknown,t_uint256)',
|
|
129
|
+
rets: undefined,
|
|
80
130
|
tail: undefined,
|
|
81
131
|
}
|
|
82
132
|
|
|
@@ -157,58 +207,12 @@ Generated by [AVA](https://avajs.dev).
|
|
|
157
207
|
tail: undefined,
|
|
158
208
|
}
|
|
159
209
|
|
|
160
|
-
##
|
|
161
|
-
|
|
162
|
-
> Snapshot 1
|
|
163
|
-
|
|
164
|
-
{
|
|
165
|
-
args: [
|
|
166
|
-
{
|
|
167
|
-
args: undefined,
|
|
168
|
-
head: 't_uint256',
|
|
169
|
-
id: 't_uint256',
|
|
170
|
-
rets: undefined,
|
|
171
|
-
tail: undefined,
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
args: undefined,
|
|
175
|
-
head: 't_uint256',
|
|
176
|
-
id: 't_uint256',
|
|
177
|
-
rets: undefined,
|
|
178
|
-
tail: undefined,
|
|
179
|
-
},
|
|
180
|
-
],
|
|
181
|
-
head: 't_mapping',
|
|
182
|
-
id: 't_mapping(t_uint256,t_uint256)',
|
|
183
|
-
rets: undefined,
|
|
184
|
-
tail: undefined,
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
## t_uint256
|
|
188
|
-
|
|
189
|
-
> Snapshot 1
|
|
190
|
-
|
|
191
|
-
{
|
|
192
|
-
args: undefined,
|
|
193
|
-
head: 't_uint256',
|
|
194
|
-
id: 't_uint256',
|
|
195
|
-
rets: undefined,
|
|
196
|
-
tail: undefined,
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
## t_mapping(unknown,t_uint256)
|
|
210
|
+
## t_function_internal_nonpayable(t_uint256)returns()
|
|
200
211
|
|
|
201
212
|
> Snapshot 1
|
|
202
213
|
|
|
203
214
|
{
|
|
204
215
|
args: [
|
|
205
|
-
{
|
|
206
|
-
args: undefined,
|
|
207
|
-
head: 'unknown',
|
|
208
|
-
id: 'unknown',
|
|
209
|
-
rets: undefined,
|
|
210
|
-
tail: undefined,
|
|
211
|
-
},
|
|
212
216
|
{
|
|
213
217
|
args: undefined,
|
|
214
218
|
head: 't_uint256',
|
|
@@ -217,48 +221,44 @@ Generated by [AVA](https://avajs.dev).
|
|
|
217
221
|
tail: undefined,
|
|
218
222
|
},
|
|
219
223
|
],
|
|
220
|
-
head: '
|
|
221
|
-
id: '
|
|
222
|
-
rets:
|
|
223
|
-
tail: undefined,
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
## t_enum(MyEnum)
|
|
227
|
-
|
|
228
|
-
> Snapshot 1
|
|
229
|
-
|
|
230
|
-
{
|
|
231
|
-
args: [
|
|
232
|
-
{
|
|
233
|
-
args: undefined,
|
|
234
|
-
head: 'MyEnum',
|
|
235
|
-
id: 'MyEnum',
|
|
236
|
-
rets: undefined,
|
|
237
|
-
tail: undefined,
|
|
238
|
-
},
|
|
239
|
-
],
|
|
240
|
-
head: 't_enum',
|
|
241
|
-
id: 't_enum(MyEnum)',
|
|
242
|
-
rets: undefined,
|
|
224
|
+
head: 't_function_internal_nonpayable',
|
|
225
|
+
id: 't_function_internal_nonpayable(t_uint256)returns()',
|
|
226
|
+
rets: [],
|
|
243
227
|
tail: undefined,
|
|
244
228
|
}
|
|
245
229
|
|
|
246
|
-
##
|
|
230
|
+
## t_array(t_function_internal_nonpayable(t_uint256)returns(t_address))10_storage
|
|
247
231
|
|
|
248
232
|
> Snapshot 1
|
|
249
233
|
|
|
250
234
|
{
|
|
251
235
|
args: [
|
|
252
236
|
{
|
|
253
|
-
args:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
237
|
+
args: [
|
|
238
|
+
{
|
|
239
|
+
args: undefined,
|
|
240
|
+
head: 't_uint256',
|
|
241
|
+
id: 't_uint256',
|
|
242
|
+
rets: undefined,
|
|
243
|
+
tail: undefined,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
head: 't_function_internal_nonpayable',
|
|
247
|
+
id: 't_function_internal_nonpayable(t_uint256)returns(t_address)',
|
|
248
|
+
rets: [
|
|
249
|
+
{
|
|
250
|
+
args: undefined,
|
|
251
|
+
head: 't_address',
|
|
252
|
+
id: 't_address',
|
|
253
|
+
rets: undefined,
|
|
254
|
+
tail: undefined,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
257
|
tail: undefined,
|
|
258
258
|
},
|
|
259
259
|
],
|
|
260
|
-
head: '
|
|
261
|
-
id: '
|
|
260
|
+
head: 't_array',
|
|
261
|
+
id: 't_array(t_function_internal_nonpayable(t_uint256)returns(t_address))10_storage',
|
|
262
262
|
rets: undefined,
|
|
263
|
-
tail: '
|
|
263
|
+
tail: '10_storage',
|
|
264
264
|
}
|
|
Binary file
|
package/src/validate/query.ts
CHANGED
|
@@ -58,13 +58,17 @@ export function getStorageLayout(data: ValidationData, version: Version): Storag
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function unfoldStorageLayout(runData: ValidationRunData, contractName: string): StorageLayout {
|
|
61
|
-
const c = runData[contractName];
|
|
62
61
|
const layout: StorageLayout = { storage: [], types: {} };
|
|
63
|
-
|
|
64
|
-
layout.storage
|
|
65
|
-
|
|
62
|
+
if (runData[contractName].layout.flat) {
|
|
63
|
+
return { storage: runData[contractName].layout.storage, types: runData[contractName].layout.types };
|
|
64
|
+
} else {
|
|
65
|
+
const c = runData[contractName];
|
|
66
|
+
for (const name of [contractName].concat(c.inherit)) {
|
|
67
|
+
layout.storage.unshift(...runData[name].layout.storage);
|
|
68
|
+
Object.assign(layout.types, runData[name].layout.types);
|
|
69
|
+
}
|
|
70
|
+
return layout;
|
|
66
71
|
}
|
|
67
|
-
return layout;
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
export function* findVersionWithoutMetadataMatches(
|
package/src/validate/run.ts
CHANGED
|
@@ -162,7 +162,12 @@ export function validate(solcOutput: SolcOutput, decodeSrc: SrcDecoder): Validat
|
|
|
162
162
|
...getLinkingErrors(contractDef, bytecode),
|
|
163
163
|
];
|
|
164
164
|
|
|
165
|
-
validation[contractDef.name].layout = extractStorageLayout(
|
|
165
|
+
validation[contractDef.name].layout = extractStorageLayout(
|
|
166
|
+
contractDef,
|
|
167
|
+
decodeSrc,
|
|
168
|
+
deref,
|
|
169
|
+
solcOutput.contracts[source][contractDef.name].storageLayout,
|
|
170
|
+
);
|
|
166
171
|
validation[contractDef.name].methods = [...findAll('FunctionDefinition', contractDef)]
|
|
167
172
|
.filter(fnDef => ['external', 'public'].includes(fnDef.visibility))
|
|
168
173
|
.map(fnDef => getFunctionSignature(fnDef, deref));
|
package/src/validate.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _test, {
|
|
1
|
+
import _test, { TestFn } from 'ava';
|
|
2
2
|
import { artifacts } from 'hardhat';
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -15,7 +15,7 @@ interface Context {
|
|
|
15
15
|
validation: RunValidation;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const test = _test as
|
|
18
|
+
const test = _test as TestFn<Context>;
|
|
19
19
|
|
|
20
20
|
test.before(async t => {
|
|
21
21
|
const contracts = [
|