Skip to content

Commit

Permalink
Ignore public initializers from parent contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
ericglau committed Dec 10, 2024
1 parent 2137d40 commit e17b5c4
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 10 deletions.
4 changes: 2 additions & 2 deletions packages/core/contracts/test/ValidationsInitializer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ contract Parent_NoInitializer {
}

contract Parent_InitializerModifier is Initializable {
function parentInit() initializer public {}
function parentInit() initializer internal {}
}

contract Parent_ReinitializerModifier is Initializable {
function parentReinit() reinitializer(2) public {}
function parentReinit() reinitializer(2) internal {}
}

contract Parent__OnlyInitializingModifier is Initializable {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/contracts/test/cli/excludes/AbstractUUPS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ abstract contract AbstractUUPS is UUPSUpgradeable, Abstract1, Abstract2 {
z = _z;
}

function initialize() onlyInitializing public {
function initialize() initializer public {
__UUPSUpgradeable_init();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,4 @@ contract UsesAbstractUUPS is AbstractUUPS {
function _authorizeUpgrade(address newImplementation) internal pure override {
revert("Upgrade disabled");
}

function initializeChild() initializer public {
super.initialize();
}
}
7 changes: 4 additions & 3 deletions packages/core/src/validate/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ function* getInitializerErrors(
deref('ContractDefinition', base.baseName.referencedDeclaration),
);
const baseContractsInitializersMap = new Map(
baseContractDefs.map(base => [base.name, getPossibleInitializers(base)]),
baseContractDefs.map(base => [base.name, getPossibleInitializers(base, { ignorePublicInitializers: true })]),
);
const baseContractsWithInitializers = baseContractDefs
.filter(base => hasInitializers(base.name, baseContractsInitializersMap))
Expand Down Expand Up @@ -773,15 +773,16 @@ function hasInitializers(baseName: string, baseContractsInitializersMap: Map<str
return initializers !== undefined && initializers.length > 0;
}

function getPossibleInitializers(contractDef: ContractDefinition) {
function getPossibleInitializers(contractDef: ContractDefinition, { ignorePublicInitializers = false } = {}) {
const fns = [...findAll('FunctionDefinition', contractDef)];
return fns.filter(
fnDef =>
(fnDef.modifiers.some(modifier =>
['initializer', 'reinitializer', 'onlyInitializing'].includes(modifier.modifierName.name),
) ||
['initialize', 'initializer', 'reinitialize', 'reinitializer'].includes(fnDef.name)) &&
!(fnDef.virtual && !fnDef.body), // Skip virtual functions without a body, since that indicates an abstract function and is not itself an initializer
!(fnDef.virtual && !fnDef.body) && // Skip virtual functions without a body, since that indicates an abstract function and is not itself an initializer
(!ignorePublicInitializers || (fnDef.visibility !== 'public' && fnDef.visibility !== 'external')), // For parent contracts, ignore public initializers since they do not strictly need to be called from the child
);
}

Expand Down

0 comments on commit e17b5c4

Please sign in to comment.