Tadle

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

All the `core/` smart contracts cannot be upgdaded

Summary

Inability to Upgrade Core Smart Contracts

Vulnerability Details

The TadleFactory contract is designed to deploy upgradeable proxies using the OpenZeppelin Transparent Proxy pattern. However, it currently lacks a function to upgrade the implementation of these proxies. This limitation prevents the TadleFactory from utilizing its admin role to perform upgrades on the deployed proxies, thereby restricting the system's flexibility and maintainability.

The TadleFactory contract deploys upgradeable proxies using the OpenZeppelin Transparent Proxy pattern. However, the admin for these proxies is set to the TadleFactory contract itself (address(this)). To perform an upgrade using the upgradeToAndCall or upgradeAndCall functions from the TransparentUpgradeableProxy, the caller must be the TadleFactory contract, not an externally owned account (EOA). Due to this restriction, the core contracts cannot be upgraded.

Detailed Explanation:

  • In TadleFactory.sol lines 61-67, the UpgradeableProxy is deployed with the admin set to address(this), which refers to the TadleFactory contract.

  • In UpgradeableProxy.sol lines 28-35, the constructor sets the admin to the provided address, which is TadleFactory.

  • To utilize the upgrade functionality (upgradeToAndCall or upgradeAndCall), the caller must be the TadleFactory contract itself.

  • Since the current implementation does not allow an EOA to trigger these upgrade functions, the core contracts remain non-upgradable.

function deployUpgradeableProxy(
uint8 _relatedContractIndex,
address _logic,
bytes memory _data
) external onlyGuardian returns (address) {
/// @dev the logic address must be a contract
if (!_logic.isContract()) {
revert LogicAddrIsNotContract(_logic);
}
/// @dev deploy proxy
UpgradeableProxy _proxy = new UpgradeableProxy(
_logic,
guardian,
address(this),//here as we can see the proxy admin is set to address(this)
_data
);
relatedContracts[_relatedContractIndex] = address(_proxy);
emit RelatedContractDeployed(_relatedContractIndex, address(_proxy));
return address(_proxy);
}

Impact

no one can upgrade the contracts

Tools Used

Manual Analysis

Recommendations

  • Implement an upgradeProxy function within the TadleFactory contract to enable it to call upgradeToAndCall on the UpgradeableProxy. This function would allow the TadleFactory to perform upgrades as needed.

Updates

Lead Judging Commences

0xnevi Lead Judge
about 1 year ago
0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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