There is a re-entrancy vulnerability in the nonReentrant modifier used by the contract. The modifier never sets locked = true before executing the function body, which renders the re-entrancy check ineffective. This can allow malicious contracts to repeatedly call functions like refund() and drain user balances.
Because locked is never set to true before _;, re-entrant calls are never blocked.
A malicious contract can deposit funds, then call refund(). When receiving Ether (or a token transfer), the contract’s fallback can re-enter refund() again, bypassing the guard check. The contract’s internal balances are only set to zero at the end of the transaction, letting multiple refunds happen in the same transaction.
An attacker can drain funds by exploiting the vulnerability. This includes ETH and any whitelisted ERC20 tokens.
Other participants’ deposits could also be at risk if the logic allows attackers to claim more than their fair share, creating a significant financial loss.
Manual code review
1. Fix the Non-Reentrant Modifier:
2. Use existing battle-tested libraries
OpenZeppelin offers ReentrancyGuard's that can be imported and be used instead of writing code that has not been battle-tested in production.
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.