The refund() fucntion is vulnerable to Re-entrancy attacks by a malicious user. The vulnerability is caused by an incorrect implementation of the nonReentrant modifier and failure to follow the Checks-Effects-Interactions pattern.
The nonReentrant modifier is implemented incorrectly and so state changes will occur after external calls, allowing for reentrancy. Specifically:
The modifier never sets locked = true, only checks and sets it to false:
2.The refund() function performs external calls before state changes:
3.The _refundETH() function makes external calls before updating state:
This allows a malicious contract to:
Make an initial deposit to become a participant
Call refund()
When receiving ETH in the fallback function, call refund() again
Repeat step 3 until the contract is drained
A malicious user/contract can drain the entire ETH balance from our contract. This is a critical severity issue because
It allows unauthorized withdrawal of funds
Can drain 100% of the contract's ETH balance
Requires minimal upfront capital to execute
Can be executed by any participant
Slither, Remix IDE
Follow CEI pattern (do necessary checks first, change the state, then do the interaction)
Use Openzeppelin's Reentrancy Guard contract
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.