The TadleFactory
contract's deployUpgradeableProxy
function creates new proxy contracts for each upgrade instead of upgrading existing proxies. While the system shows preparations for upgradability (such as storage gaps and inheritance from UpgradeableStorage
), the deployUpgradeableProxy
function creates new UpgradeableProxy
instances each time it's called, overwriting the address in the relatedContracts
mapping.
This approach doesn't leverage the upgradeable design of the contracts and can lead to state loss and system inconsistencies.
Consider a scenario where an admin deploys a contract at index 1, and later, the same admin calls deployUpgradeableProxy
with index 1 again, deploying a new contract. The previous contract's state is lost, and any functionality relying on that contract will fail.
In the TadleFactory::deployUpgradeableProxy
:
This function creates a new UpgradeableProxy
each time it's called, even for existing indices, leading to state loss and potential inconsistencies.
The UpgradeableProxy
contract suggests that future variables will be added because of the __gap
variable. The curent implementation will lead to a loss of the state of these future variables, as it won’t be possible to modify the deployUpgradeableProxy
function.
Loss of State: Overwriting existing proxies can lead to the loss of all state data held by the previous contract, disrupting the functionality of the system.
Operational Disruption: If contracts are actively being used, replacing them can cause significant operational issues, leading to failures in dependent systems and processes.
Inability to Upgrade Safely: The lack of a proper upgrade mechanism prevents the system from adapting to new requirements or fixing bugs without risking data loss or service interruptions.
Manual review
Implement a true upgrade mechanism:
Modify the UpgradeableProxy
contract to include functions for upgrading the logic contract without changing the proxy address (e.g., upgradeToAndCall
).
Add an upgradeProxy
function to TadleFactory
that calls the upgrade function on the existing proxy:
Implement validation for the _relatedContractIndex
parameter to prevent overwriting existing proxies without checks.
Modify deployUpgradeableProxy
to only deploy a new proxy if one doesn't exist for the given index. If a proxy already exists, it should revert or call the upgrade function instead, ensuring that the state is preserved.
Consider using the upgrade function upgradeToAndCall
provided by TransparentUpgradeableProxy
effectively, in order to change the implementation.
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.