An attacker can front-run the createTransparentProxy call with the same salt but different constructor parameters (e.g., a different admin). This lets them deploy first and take the same final address the user intended to use. Once deployed, the address is no longer available to the legitimate user, causing denial of service or address hijacking.
The factory is fully open; anyone can call it without restrictions. Deterministic deployment here depends only on (factoryAddress, salt, fixedProxyBytecode), not on constructor arguments. Using the same salt will always yield the same final address.
Thus, an attacker can prevent valid deployments or forcibly take over a deterministic address.
It could be worse if those contracts are somehow used/listed as the deployed addresses where it would lead users/governance to interact with.
Impact Details
DoS of contract's deployment through ProxyFactory.
Potential loss of funds if users/governance/devs interact with the contract.
Recommendation
Implement an access control modifier on createTransparentProxy.
Proof of Concept
Create a file called ProxyFactoryDos.ts inside the test folder.
Paste the code below and run: npx hardhat test test/ProxyFactoryDoS.ts
Output:
Here we proof that the attacker front-run the transaction and created a proxy with the same address using a different implementation.