Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Invalid

Improper Initialization in UpgradeableProxy Using Constructor (Potential Inflexibility)

Summary

The UpgradeableProxy contract, which is based on OpenZeppelin's TransparentUpgradeableProxy, improperly uses a constructor for initialization, which is not ideal for upgradeable contracts. This practice could lead to potential inflexibility and the inability to properly upgrade the contract.

Description

The UpgradeableProxy contract inherits from OpenZeppelin’s TransparentUpgradeableProxy, and the constructor is used to set up important state variables such as tadleFactory. While this works initially, it becomes problematic in the context of upgradeable contracts where re-initialization or upgrading might be required. Constructors are only called once, during the deployment, and cannot be called again during an upgrade, which limits the flexibility of the contract.

Impact

  • Inflexibility in Upgrades: The use of a constructor means that if a contract is upgraded, there is no way to re-initialize it without redeploying the entire proxy, which defeats the purpose of using a proxy pattern.

  • Potential Misconfiguration: Future versions of the contract that need to modify or re-initialize variables set by the constructor would be unable to do so, leading to potential misconfigurations.

Root Cause

The root cause is the reliance on a constructor for initialization in a context where the contract is expected to be upgradeable. Since constructors are not re-executed on upgrades, any state changes required during an upgrade cannot be accomplished if they rely on constructor logic.

Proof of Concept

  1. Deploy the Proxy Contract: Deploy the UpgradeableProxy contract using the provided constructor.

  2. Attempt to Upgrade: Upgrade the logic contract to a new version that requires re-initialization of variables. Notice that the constructor logic is not executed during the upgrade, potentially leaving the contract in an inconsistent or uninitialized state.

  3. Observe Inflexibility: Any attempt to modify or re-initialize variables initially set by the constructor during an upgrade will fail, highlighting the inflexibility of this approach.

Recommended Mitigation

To address this issue, it's recommended to avoid using constructors in upgradeable contracts and instead use an initializer function. The initializer function should be protected with OpenZeppelin’s initializer modifier to ensure it can only be called once.Tools Used

Updates

Lead Judging Commences

0xnevi Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

[invalid] finding-Rescuable-upgradeable-initializeOwner

Valid high severity, since `initializeOwner` is not called for proxy contracts and the constructor for each `Rescuable.sol` contract will not be invoked during proxy deployment, this leaves the `owner` for each proxy unitialized allowing potential to withdraw fund from other proxy contracts inheriting `Rescuable.sol` respectively.

Appeal created

0xnevi Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[invalid] finding-Rescuable-upgradeable-initializeOwner

Valid high severity, since `initializeOwner` is not called for proxy contracts and the constructor for each `Rescuable.sol` contract will not be invoked during proxy deployment, this leaves the `owner` for each proxy unitialized allowing potential to withdraw fund from other proxy contracts inheriting `Rescuable.sol` respectively.

Support

FAQs

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