The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Initialize function in SmartVaultManagerV5.sol can be invoked multiple times from the implementation contract

Summary

Vulnerability Details

The initialization function in SmartVaultManagerV5.sol can be called multiple times from the implementation contract.

Typically, in upgradeable contracts, an initialization function is safeguarded by a modifier to prevent unauthorized calls and ensure that it can only be executed once.

Impact

This vulnerability implies that a compromised implementation has the potential to reinitialize the aforementioned contract, seizing ownership and facilitating privilege escalation to drain users' funds.

Despite using the OpenZeppelin/Initializable.sol and making the contract SmartVaultManagerV5 Initializable.

contract SmartVaultManagerV5 is ISmartVaultManager, ISmartVaultManagerV2, Initializable, ERC721Upgradeable, OwnableUpgradeable {

That provides an Initializable base contract that has an initializer modifier that takes care of preventing a contract from being initialized multiple times.

Another difference between a constructor and a regular function is that Solidity takes care of automatically invoking the constructors of all ancestors of a contract.

When writing an initializer, you need to take special care to manually call the initializers of all parent contracts.

Note that the initializer modifier can only be called once even when using inheritance, so parent contracts should use the onlyInitializing modifier:

// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract BaseContract is Initializable {
uint256 public y;
function initialize() public onlyInitializing {
y = 42;
}
}
contract MyContract is BaseContract {
uint256 public x;
function initialize(uint256 _x) public initializer {
BaseContract.initialize(); // Do not forget this call!
x = _x;
}
}

For further insights into potential risks and considerations when using initialize function, please consult the following resource:
https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializers

Tools Used

Manual Review

Recommendations

I reccomend first to protect the initialize function from being reinitiated with:

function initialize(address _owner) external onlyImpl initializer {

And, also add onlyInitializing as stated above:

function initialize() public onlyInitializing {
y = 42;
}
Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

uninitialized-variables

informational/invalid

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.