Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rename / retype inside structs #722

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion packages/core/contracts/test/RenamedRetyped.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,79 @@ contract LayoutChangeV2 {

/// @custom:oz-retyped-from bool
uint8 b;
}
}

contract RenameStructV1 {
struct History {
Checkpoint[] _checkpoints;
}

struct Checkpoint {
uint32 _blockNumber;
uint224 _value;
}

History history;
}

contract RenameStructV2a {
struct Trace224 {
Checkpoint224[] _checkpoints;
}

struct Checkpoint224 {
uint32 _blockNumber;
uint224 _value;
}

Trace224 history;
}

contract RenameStructV2b {
struct Trace224 {
Checkpoint224[] _checkpoints;
}

struct Checkpoint224 {
uint32 _key;
uint224 _value;
}

/// @custom:oz-retyped-from RenameStructV1.History
Trace224 history;
}

contract InnerRetypeV1 {
struct ProposalCore {
BlockNumber key;
bool flag;
}

struct BlockNumber {
uint32 blockNumber;
}

ProposalCore core;
}

contract InnerRetypeV2Good {
struct ProposalCore {
uint256 blockNumber;
bool flag;
}

/// @custom:oz-retyped-from InnerRetypeV1.ProposalCore
ProposalCore core;
}

contract InnerRetypeV2Bad {
struct ProposalCore {
uint16 a;
uint224 b;
uint16 c;
bool flag;
}

/// @custom:oz-retyped-from InnerRetypeV1.ProposalCore
ProposalCore core;
}
27 changes: 27 additions & 0 deletions packages/core/src/storage/report-rename-retype.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const testContracts = [
'contracts/test/RenamedRetyped.sol:NonHardcodedRetypeV2',
'contracts/test/RenamedRetyped.sol:LayoutChangeV1',
'contracts/test/RenamedRetyped.sol:LayoutChangeV2',
'contracts/test/RenamedRetyped.sol:RenameStructV1',
'contracts/test/RenamedRetyped.sol:RenameStructV2a',
'contracts/test/RenamedRetyped.sol:RenameStructV2b',
'contracts/test/RenamedRetyped.sol:InnerRetypeV1',
'contracts/test/RenamedRetyped.sol:InnerRetypeV2Good',
'contracts/test/RenamedRetyped.sol:InnerRetypeV2Bad',
];

test.before(async t => {
Expand Down Expand Up @@ -131,3 +137,24 @@ test('retype with layout change', t => {
t.false(report.ok);
t.snapshot(report.explain());
});

test('storage upgrade with struct renaming/replacing', t => {
const v1 = t.context.extractStorageLayout('RenameStructV1');
const v2a = t.context.extractStorageLayout('RenameStructV2a');
const v2b = t.context.extractStorageLayout('RenameStructV2b');

t.deepEqual(getStorageUpgradeErrors(v1, v2a), []);
t.deepEqual(getStorageUpgradeErrors(v1, v2b), []);
});

test('storage upgrade with internal struct changes', t => {
const v1 = t.context.extractStorageLayout('InnerRetypeV1');
const v2Good = t.context.extractStorageLayout('InnerRetypeV2Good');
const v2Bad = t.context.extractStorageLayout('InnerRetypeV2Bad');

t.deepEqual(getStorageUpgradeErrors(v1, v2Good), []);

t.like(getStorageUpgradeErrors(v1, v2Bad), {
length: 1,
});
});