Summary
getProxyAddress() is used in ProxyFactory.sol to get anticipated/calculated proxy contract address by the sponsor inorder to fund the contract.
Vulnerability Details
The _deployProxy() is used by the organizer to deploy Proxy And Distribute rewards to winners and takes organizer,contestId & implementation as arguments
function _deployProxy(address organizer, bytes32 contestId, address implementation) internal returns (address) {
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
address proxy = address(new Proxy{salt: salt}(implementation));
return proxy;
}
the getProxyAddress() is a public function which takes salt and implementation as arguments. This is where the issue might occur since the sponsor will have to come up with a correct salt otherwise funds will be sent to wrong address. The address produced by _deployProxy() will be different to getProxyAddress().
function getProxyAddress(bytes32 salt, address implementation) public view returns (address proxy) {
bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(uint160(implementation)));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, keccak256(code)));
proxy = address(uint160(uint256(hash)));
}
Impact
Funds will be sent to wrong address by sponsor/organiser.
Tools Used
Manual review
Recommendations
Modify the getProxyAddress() to the following
function getProxyAddress(address organizer, bytes32 contestId, address implementation) public view returns (address proxy) {
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
if (saltToCloseTime[salt] == 0) revert ProxyFactory__ContestIsNotRegistered();
bytes memory code = abi.encodePacked(type(Proxy).creationCode, uint256(uint160(implementation)));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, keccak256(code)));
proxy = address(uint160(uint256(hash)));
}