From a8d06cf86b3fcdb115f3b3f550d677596c02e024 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Thu, 19 Dec 2024 11:22:35 -0500 Subject: [PATCH] Add testcases for transitive initialization --- .../contracts/test/ValidationsInitializer.sol | 46 ++++++++++++++++++- .../core/src/validate-initializers.test.ts | 8 ++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/packages/core/contracts/test/ValidationsInitializer.sol b/packages/core/contracts/test/ValidationsInitializer.sol index 76d8f4e5f..63741d604 100644 --- a/packages/core/contracts/test/ValidationsInitializer.sol +++ b/packages/core/contracts/test/ValidationsInitializer.sol @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; // These contracts are for testing only. They are not safe for use in production, and do not represent best practices. @@ -316,3 +320,43 @@ contract Child_Has_PrivateInitializer_Bad is Parent__OnlyInitializingModifier { __Parent_init(); } } + +// ==== Transitive initialization ==== + +contract Ownable_Ok is Initializable, ERC20Upgradeable, OwnableUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(address initialOwner) initializer public { + __ERC20_init("MyToken", "MTK"); + __Ownable_init(initialOwner); + } +} + +contract Ownable2Step_Ok is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(address initialOwner) initializer public { + __ERC20_init("MyToken", "MTK"); + __Ownable_init(initialOwner); // Transitive dependency that needs to be initialized + __Ownable2Step_init(); + } +} + +contract Ownable2Step_Bad is Initializable, ERC20Upgradeable, Ownable2StepUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize() initializer public { + __ERC20_init("MyToken", "MTK"); + // Missing Ownable, which is a transitive dependency that needs to be initialized + __Ownable2Step_init(); + } +} \ No newline at end of file diff --git a/packages/core/src/validate-initializers.test.ts b/packages/core/src/validate-initializers.test.ts index 9360fa454..53cd00c08 100644 --- a/packages/core/src/validate-initializers.test.ts +++ b/packages/core/src/validate-initializers.test.ts @@ -131,3 +131,11 @@ testRejects( testAccepts('Child_Of_ParentPrivateInitializer_Ok', 'transparent'); testAccepts('Child_Of_ParentPublicInitializer_Ok', 'transparent'); testRejects('Child_Has_PrivateInitializer_Bad', 'transparent', 'Contract is missing an initializer'); + +testAccepts('Ownable_Ok', 'transparent'); +testAccepts('Ownable2Step_Ok', 'transparent'); +testRejects( + 'Ownable2Step_Bad', + 'transparent', + 'Contract is missing initializer calls for one or more parent contracts: `OwnableUpgradeable`', +);