The proxy is deployed uninitialized
The DealManagerFactory.deployDealManager deploys an ERC1967Proxy without initialization calldata, so the proxy is left uninitialized.
function deployDealManager(bytes32 _salt) public returns (address) {
if (_salt == bytes32(0)) revert InvalidSalt();
// Create proxy deployment bytecode
bytes memory proxyBytecode = _getBytecode();
// Deploy using CREATE2
address dealManagerProxy = Create2.deploy(0, _salt, proxyBytecode);
if(dealManagerProxy == address(0)) revert DeploymentFailed();
emit DealManagerDeployed(dealManagerProxy, DealManager(DealManagerFactoryStorage.getRefImplementation()).DEPLOY_VERSION());
return dealManagerProxy;
}
function _getBytecode() private view returns (bytes memory bytecode) {
bytes memory sourceCodeBytes = type(ERC1967Proxy).creationCode;
bytecode = abi.encodePacked(sourceCodeBytes, abi.encode(DealManagerFactoryStorage.getRefImplementation(), ""));
}This is safe only if the deployment flow wraps deployDealManager and the proxy’s initialize call within a single atomic transaction.
If deployDealManager can be invoked independently, an attacker could front-run the initialization by calling initialize on the newly deployed proxy first, thereby configuring it with malicious parameters.
The same concern also exists in RoundManagerFactory.