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.
Vulnerability Details
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
Impact
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.
Tools Used
Manual analysis.
Recommendation
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.
Footnotes
[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.
No validation of
implementation
parameter insetContest()
Severity
Low Risk
Relevant GitHub Links
https://github.com/Cyfrin/2023-08-sparkn/blob/0f139b2dc53905700dd29a01451b330f829653e9/src/ProxyFactory.sol#L105
Summary
The
setContest()
function inProxyFactory
is used to configure a contest's properties. Theimplementation
parameter is used to compute a salt for counterfactual proxy contract deployment. If an incorrectimplementation
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.Vulnerability Details
The
setContest()
function inProxyFactory
is used to configure a contest's properties:The
organizer
,contestId
andimplementation
parameters are used to compute a salt for counterfactual contract deployment. The resultant proxy address is then used by theorganizer
to post contest rewards to. Since there is no validation of theimplementation
address, it is possible to provide an incorrectimplementation
address. If this happens and goes unnoticed, contest rewards posted to the resultant proxy address will be lost forever.Proof of Concept
owner
invokessetContest()
with valid values fororganizer
,contestId
, andcloseTime
, but an incorrect value forimplementation
owner
invokesgetProxyAddress()
with thesalt
(see footnote [1] below) and the same incorrect value forimplementation
again, receiving a proxy address in responseowner
sends the proxy address, which is linked to the incorrectimplementation
address, to theorganizer
organizer
sends rewards to the proxy addressimplementation
addressImpact
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.Tools Used
Manual analysis.
Recommendation
Remove the
implementation
parameter fromsetContest
, and instead add acurrentImplemenation
state variable toProxyFactory
with a 2-phase configure + commit protocol to avoid misconfiguring contests. When configuring thecurrentImplementation
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.Footnotes
[1] QA: There is no easy way for
owner
ororganizer
to invokegetProxyAddress
assalt
is not returned bysetContest()
, nor emitted in theSetContest
event. The contract should either returnsalt
insetContest
, or include it in the emittedSetContest
event. The unit tests are constructing the proxy address by hand -- this is dangerous.