Skip to content

Commit

Permalink
Allow assignment of immutable variables (#838)
Browse files Browse the repository at this point in the history
  • Loading branch information
frangio authored Jul 10, 2023
1 parent 44d0149 commit ceeafbb
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 15 deletions.
9 changes: 6 additions & 3 deletions docs/modules/ROOT/pages/faq.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,12 @@ In some cases you may want to allow multiple errors in a single line.

[source,solidity]
----
/// @custom:oz-upgrades-unsafe-allow constructor state-variable-immutable
contract SomeOtherContract {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
uint256 immutable x = 1;
uint256 immutable x;
constructor() {
x = block.number;
}
}
----

Expand All @@ -108,7 +111,7 @@ It may be possible to safely use `delegatecall` and `selfdestruct` if they are g
[source,solidity]
----
abstract contract OnlyDelegateCall {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address private immutable self = address(this);
function checkDelegateCall() private view {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- Allow assignment of immutable variables if the `state-variable-immutable` override is present.

## 1.27.1 (2023-06-15)

- Update recommended Foundry config for CLI. ([#818](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/818))
Expand Down
6 changes: 3 additions & 3 deletions packages/core/contracts/test/ValidationsNatspec.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ contract HasStateVariableAssignmentNatspec3 {
uint y = 2;
}

/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
contract HasImmutableStateVariableNatspec1 {
uint immutable x = 1;
}

contract HasImmutableStateVariableNatspec2 {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
uint immutable x = 1;
}

contract HasImmutableStateVariableNatspec3 {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
uint immutable x = 1;
uint immutable y = 2;
}
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/validate/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ const errorInfo: ErrorDescriptions<ValidationError> = {
link: 'https://zpl.in/upgrades/error-004',
},
'state-variable-immutable': {
msg: e => `Variable \`${e.name}\` is immutable`,
hint: () => `Use a constant or mutable variable instead`,
msg: e => `Variable \`${e.name}\` is immutable and will be initialized on the implementation`,
hint: () =>
`If by design, annotate with '@custom:oz-upgrades-unsafe-allow state-variable-immutable'\n` +
`Otherwise, consider a constant variable or use a mutable variable instead`,
link: 'https://zpl.in/upgrades/error-005',
},
'external-library-linking': {
Expand Down
14 changes: 7 additions & 7 deletions packages/core/src/validate/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,19 +386,19 @@ function* getStateVariableErrors(
): Generator<ValidationErrorWithName> {
for (const varDecl of contractDef.nodes) {
if (isNodeType('VariableDeclaration', varDecl)) {
if (!varDecl.constant && !isNullish(varDecl.value)) {
if (!skipCheck('state-variable-assignment', contractDef) && !skipCheck('state-variable-assignment', varDecl)) {
if (varDecl.mutability === 'immutable') {
if (!skipCheck('state-variable-immutable', contractDef) && !skipCheck('state-variable-immutable', varDecl)) {
yield {
kind: 'state-variable-assignment',
kind: 'state-variable-immutable',
name: varDecl.name,
src: decodeSrc(varDecl),
};
}
}
if (varDecl.mutability === 'immutable') {
if (!skipCheck('state-variable-immutable', contractDef) && !skipCheck('state-variable-immutable', varDecl)) {
} else if (!varDecl.constant && !isNullish(varDecl.value)) {
// Assignments are only a concern for non-immutable variables
if (!skipCheck('state-variable-assignment', contractDef) && !skipCheck('state-variable-assignment', varDecl)) {
yield {
kind: 'state-variable-immutable',
kind: 'state-variable-assignment',
name: varDecl.name,
src: decodeSrc(varDecl),
};
Expand Down

0 comments on commit ceeafbb

Please sign in to comment.