the owner can take the reward from the proxy before the EXPIRATION_TIME is passed .
in the function distributeByOwner() the owner need to pass the proxy ,organizer, contestId , implementation , and data , and there is nothing prevent the owner from passing the organizer, contestId , implementation of one proxy and a different proxy as the parameter proxy , if the salt that is calculated in this function has smaller closetime than the salt that is used to deploy the proxy , this will allow the owner to get the reward (tokens) before the supposed time is passed .
the function distributeByOwner call the internal function _distribute() ,and then emit the event event Distributed(address indexed proxy, bytes data); , this will lead to loss of funds for the organizer and the winners .
1)imagine that the owner set two different contests the first with salt0 and the secound with salt1 by calling the function setContest() twice .
2)the salt0 has 100 seconds as saltCloseTime0 and the salt1 has 50 seconds as the saltCloseTime1.
3)the owner call the function distributeByOwner() and pass proxy0 that has been deployed by salt0 and pass the rest of the parameters (organizer, contestId , implementation) that result in the salt1 with the smaller saltCloseTime
4) finally the function will not revert since the check (saltToCloseTime[salt] + EXPIRATION_TIME > block.timestamp) will return false , and then call the internal _distribute() with proxy0 and the owner will distribute the rewards as he wants although the saltCloseTime0 + EXPIRATION_TIME has not ended yet .
the test testMismatchTheProxyWithSalt() will pass successfully and the owenr distributed the reward of the proxy2 although the CloseTime2 did not finished yet , the owner did it by using the salt1 which is corresponding to much lower closeTime .
if you change the contestId1 to be contestId2 in the last ecternal call on the function distributeByOwner() ,the test will revert .
the owner can take or distribute the rewards as he wants before the EXPIRATION_TIME + saltCloseTime has passed , which will lead to loss of funds .
manual review
instead of taking proxy as a parameter from the owner , calculate the proxyaddress by calling the function getProxyAddress() and pass the salt ,that is calculated from the (organizer, contestId , implementation) by calling the function _calculateSalt(), and the implementation address , this will ensure that the proxy will always match the salt .
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.