By the way it is programmed the withdrawFees()
function it could be possible for an bad actor to block the access to the fees for the feeAddress.
This is the first line of withdrawFees()
, if there are no players in the raffle, this line passes, but if there are any ongoing players in the raffle, the execution of the function is blocked, a bad actor could listen to the event Transfer()
which is emited after calling the _safeMint()
at the end of selectWinner()
, and enter the raffle just after this event with enterRaffle()
.
Resulting in the impossibility of withdrawing funds for the feeAddress.
High - Medium: Fund for the feeAddress could be blocked indefinitely
There are two things we can do to improve the code:
Calculate the fees and totalAmountCollected each time a player enters or exists the raffle.
Send the fees at the same time as the prizePool. (And eliminate the withdrawFees()
function)
I'll explain the process of applying both solutions down below:
This solution requires to change the way some variables are computed, and it let's us at the same time to eliminate one vulnerability of the program.
We will need to change totalAmountCollected
variable every time a player enters and exists the raffle in the functions enterRaflle()
and refund()
.
We will need to eliminate this line from selectWinner()
:
There are two reasons we do this, the first is that is wrongly calculated, in the function refund()
we are not changing the length of the players array, we are just resetting the value of where the player should be to address(0). If we leave it unchanged, if one person gets refunded the raffle will be impossible to win, as it is stated in another finding.
The following lines will need to be added to eliminate the issue:
In global scope of the contract:
In selectWinner()
:
In enterRaffle()
:
In refund()
Add a line of code to select winner that would send the fees to feeAddress
instead of having withdrawFees()
function. It would eliminate the problem of being unable to a bad actor to purposely block the feeAddress
to withdraw funds. This is the line of code in question:
with this approach we can even eliminate the variable totalFees
completely from the global scope and reduce the cost of deployment and execution, the final code for selectWinner() in this case would be:
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.