The upgradability of the TransparentUpgradeableProxy is effectively bricked due to the unexpected inputs provided to its constructor. This creates a critical vulnerability, rendering the contract's upgradeability non-functional. The issue arises because the constructor deploys a new ProxyAdmin instance, while an existing ProxyAdmin instance is also passed as an input. This results in a conflict where the ownership and administrative control mechanisms are misaligned, ultimately making it impossible to upgrade the contract's implementation.
The function createNewDAOMembership creates a new DAO membership by deploying a TransparentUpgradeableProxy. The TransparentUpgradeableProxy constructor accepts three parameters: address _logic, address initialOwner, and bytes memory _data. The constructor implementation is as follows:
As shown in the code, the TransparentUpgradeableProxy constructor deploys a new instance of the ProxyAdmin contract, with the specified initialOwner as its owner.
The createNewDAOMembership function, however, contains the following logic:
Here, the createNewDAOMembership function passes an existing ProxyAdmin instance (proxyAdmin) to the constructor of TransparentUpgradeableProxy. However, the TransparentUpgradeableProxy constructor also deploys its own ProxyAdmin instance. As a result, the following issues arise:
The admin of the TransparentUpgradeableProxy is a newly deployed ProxyAdmin instance.
The owner of this new ProxyAdmin instance is another ProxyAdmin instance, as the owner of the ProxyAdmin contract is set during its construction.
Consequently:
The deployer of the MembershipFactory contract indirectly owns the ProxyAdmin controlling the proxy, as they own the initial ProxyAdmin instance.
Since the ownership of the ProxyAdmin contract is itself assigned to another ProxyAdmin, there is no direct mechanism to update the ownership of the controlling ProxyAdmin.
This design flaw creates a situation where the TransparentUpgradeableProxy's implementation contract cannot be upgraded, as there is no accessible mechanism to change the admin or update the logic.
This issue highlights a critical gap in the contract design, as the ownership hierarchy inadvertently renders the upgradeability of the proxy non-functional. To resolve this, the contract design must be adjusted to avoid redundant or conflicting ownership assignments.
Upgrade to a new implementation is not possible
Manual review
Input initialOwner instead of instance of ProxyAdmin in createNewDAOMembership
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.