From 5407127c5a7d5dc474ce41b13ffd229cdc2f910a Mon Sep 17 00:00:00 2001 From: Evi Nova <66773372+Tranquil-Flow@users.noreply.github.com> Date: Tue, 28 Oct 2025 15:38:09 +0100 Subject: [PATCH] Feat/upgradeable root constructor (#1326) * feat: add constructor with _disableInitializers as per OZ best practices https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable#initializing-the-implementation-contract * docs: update layout and add section names * chore: run yarn prettier --- .../abstract/SelfVerificationRoot.sol | 12 +++++ .../SelfVerificationRootUpgradeable.sol | 49 ++++++++++++++----- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/contracts/contracts/abstract/SelfVerificationRoot.sol b/contracts/contracts/abstract/SelfVerificationRoot.sol index 016d500f2..6ee49e636 100644 --- a/contracts/contracts/abstract/SelfVerificationRoot.sol +++ b/contracts/contracts/abstract/SelfVerificationRoot.sol @@ -52,6 +52,10 @@ abstract contract SelfVerificationRoot is ISelfVerificationRoot { // Events // ==================================================== + // ==================================================== + // Constructor + // ==================================================== + /** * @notice Initializes the SelfVerificationRoot contract * @dev Sets up the immutable reference to the hub contract and generates scope automatically @@ -63,6 +67,10 @@ abstract contract SelfVerificationRoot is ISelfVerificationRoot { _scope = _calculateScope(address(this), scopeSeed, _getPoseidonAddress()); } + // ==================================================== + // Public Functions + // ==================================================== + /** * @notice Returns the current scope value * @dev Public view function to access the current scope setting @@ -159,6 +167,10 @@ abstract contract SelfVerificationRoot is ISelfVerificationRoot { revert("SelfVerificationRoot: getConfigId must be overridden"); } + // ==================================================== + // Internal Functions + // ==================================================== + /** * @notice Custom verification hook that can be overridden by implementing contracts * @dev This function is called after successful verification and hub address validation diff --git a/contracts/contracts/abstract/SelfVerificationRootUpgradeable.sol b/contracts/contracts/abstract/SelfVerificationRootUpgradeable.sol index 03ce17712..cd1c7ea95 100644 --- a/contracts/contracts/abstract/SelfVerificationRootUpgradeable.sol +++ b/contracts/contracts/abstract/SelfVerificationRootUpgradeable.sol @@ -14,15 +14,11 @@ import {Formatter} from "../libraries/Formatter.sol"; /** * @title SelfVerificationRootUpgradeable - * @notice Abstract upgradeable contract to be integrated with self's verification infrastructure + * @notice Abstract upgradeable base contract to be integrated with self's verification infrastructure * @dev Provides base functionality for verifying and disclosing identity credentials with proxy upgrades enabled * @author Self Team */ -abstract contract SelfVerificationRootUpgradeable is - Initializable, - ContextUpgradeable, - ISelfVerificationRoot -{ +abstract contract SelfVerificationRootUpgradeable is Initializable, ContextUpgradeable, ISelfVerificationRoot { // ==================================================== // Constants // ==================================================== @@ -38,15 +34,12 @@ abstract contract SelfVerificationRootUpgradeable is /// @notice The storage struct used to hold contract state according to the UUPSUpgradeable pattern /// @dev Used to maintain storage state across contract upgrades struct SelfVerificationRootStorage { - /// @notice The scope value that proofs must match /// @dev Used to validate that submitted proofs match the expected scope uint256 _scope; - /// @notice Reference to the identity verification hub V2 contract /// @dev Immutable reference used for bytes-based proof verification IIdentityVerificationHubV2 _identityVerificationHubV2; - } /// @notice The internal storage address for contract state. @@ -79,25 +72,51 @@ abstract contract SelfVerificationRootUpgradeable is // Events // ==================================================== + // ==================================================== + // Constructor + // ==================================================== + + /** + * @dev Prevents the implementation contract from being initialized. + * @dev The actual initialization will be done via the proxy using the `initialize()` function + * in the derived contract. + * @custom:oz-upgrades-unsafe-allow constructor + */ + constructor() { + _disableInitializers(); + } + + // ==================================================== + // Initializer + // ==================================================== + + // Implementing contracts must define an initialize function like this: + // function initialize(address hubAddress, string memory scopeSeed) public initializer { + // __SelfVerificationRoot_init(hubAddress, scopeSeed); + // // Add your own initialization logic here + // } + /** * @notice Initializes the SelfVerificationRootUpgradeable contract * @dev Sets up the immutable reference to the hub contract and generates scope automatically + * @dev Must be called from the public `initialize()` function in your derived contract * @param identityVerificationHubV2Address The address of the Identity Verification Hub V2 * @param scopeSeed The scope seed string to be hashed with contract address to generate the scope */ function __SelfVerificationRoot_init( address identityVerificationHubV2Address, string memory scopeSeed - ) - internal - onlyInitializing - { + ) internal onlyInitializing { SelfVerificationRootStorage storage $ = _getSelfVerificationRootStorage(); $._identityVerificationHubV2 = IIdentityVerificationHubV2(identityVerificationHubV2Address); $._scope = _calculateScope(address(this), scopeSeed, _getPoseidonAddress()); } + // ==================================================== + // Public Functions + // ==================================================== + /** * @notice Returns the current scope value * @dev Public view function to access the current scope setting @@ -215,6 +234,10 @@ abstract contract SelfVerificationRootUpgradeable is // Default implementation is empty - override in derived contracts to add custom logic } + // ==================================================== + // Internal Functions + // ==================================================== + /** * @notice Gets the PoseidonT3 library address for the current chain * @dev Returns hardcoded addresses of pre-deployed PoseidonT3 library on current chain