The setContest() function in ProxyFactory is used to configure a contest's properties. The implementation parameter is used to compute a salt for counterfactual proxy contract deployment. If an incorrect implementation is used to generate a proxy address for a contest, and this mistake is not noticed by the owner or organizer, any contest rewards sent to the proxy address will be lost.
The setContest() function in ProxyFactory is used to configure a contest's properties:
The organizer, contestId and implementation parameters are used to compute a salt for counterfactual contract deployment. The resultant proxy address is then used by the organizer to post contest rewards to. Since there is no validation of the implementation address, it is possible to provide an incorrect implementation address. If this happens and goes unnoticed, contest rewards posted to the resultant proxy address will be lost forever.
Proof of Concept
owner invokes setContest() with valid values for organizer, contestId, and closeTime, but an incorrect value for implementation
owner invokes getProxyAddress() with the salt (see footnote [1] below) and the same incorrect value for implementation again, receiving a proxy address in response
owner sends the proxy address, which is linked to the incorrect implementation address, to the organizer
organizer sends rewards to the proxy address
Rewards cannot be distributed or rescued because the proxy address is irreversibly linked to the wrong implementation address
This a low risk issue because there is an opportunity for the owner to notice their mistake twice before sending the proxy address to the organizer, and the organizer could also review the event log to verify the implementation address.
Manual analysis.
Remove the implementation parameter from setContest, and instead add a currentImplemenation state variable to ProxyFactory with a 2-phase configure + commit protocol to avoid misconfiguring contests. When configuring the currentImplementation parameter, it should be validated to ensure contract code is deployed at the specified address, and a signature function should be invoked at the address to confirm that the contract at the address is conformant with the SPARKN protocol.
[1] QA: There is no easy way for owner or organizer to invoke getProxyAddress as salt is not returned by setContest(), nor emitted in the SetContest event. The contract should either return salt in setContest, or include it in the emitted SetContest event. The unit tests are constructing the proxy address by hand -- this is dangerous.
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.