The nonReentrant modifier in the contract, which is intended to protect against reentrancy attacks, contains a potential issue where the reentrancy lock (locked = false;) is set after the external call to safeTransferFrom. While the current logic of the deposit function prevents reentrancy due to the state update happening before the external call, this ordering of operations may still allow a small window for reentrancy under certain circumstances.
The modifier nonReentrant() is designed to prevent reentrancy attacks by setting a locked state to true when entering the function and resetting it to false after the function execution. However, the assignment of locked = false; occurs after the external call to safeTransferFrom.
Although the function logic ensures that the participant's state (participant[msg.sender] = true) is updated before the external token transfer, leaving a window between the external call and the unlocking of the contract poses a theoretical reentrancy risk.
Severity: Low
Likelihood of Exploit: Low
Exploitability: The issue is theoretical and does not present an immediate risk in the current contract setup.
Manually source code review.
To mitigate any theoretical reentrancy risk, the locked = false; line should be moved before the external call (safeTransferFrom). This ensures the contract is immediately locked and prevents any reentrancy attempts right from the start.
This change ensures that no external calls can be made until the function completes, securing the contract against potential reentrancy attacks.
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.