Root Cause
In Pot.sol lines 70-76, the closePot() function makes external calls (i_token.transfer()) before updating state (remainingRewards), creating a reentrancy vulnerability. No reentrancy guard is present:
Checks-Effects-Interactions Violated:
Check: remainingRewards > 0 ✅
Effect: remainingRewards = 0 ❌ MISSING
Interaction: i_token.transfer() ❌ Before effects
Reentrancy Path: If token is ERC777/ERC677/malicious with callbacks, recipient can re-enter closePot()
Double Payment: Second execution pays manager and claimants again
Impact Assessment
| Dimension | Assessment |
|---|---|
| Fund Loss | Possible double payment to manager and claimants |
| Attack Vector | Requires malicious ERC20 token (ERC777, ERC677) |
| Standard ERC20 | Safe (no hooks) |
| Likelihood | Low-Medium (depends on token used) |
Severity Justification: Medium - Standard ERC20 tokens (USDC, USDT, WETH) are safe. Only vulnerable with callback-enabled tokens. But no reentrancy guard = defense-in-depth failure.
The closePot() function executes external token transfers before updating contract state, violating the Checks-Effects-Interactions (CEI) pattern and lacking a reentrancy guard.
Total Fund Drainage: An attacker can exploit this flaw to drain all remaining token balances stored within the contract pot.
Repeated Double Payment: Because the remainingRewards state variable is never reset to 0, an attacker can re-enter the function multiple times during the transfer phase to continuously siphon rewards until the contract balance is entirely depleted.
Likelihood: Low - only vulnerable with callback-enabled tokens. Standard ERC20 safe.
Impact:
CEI Pattern Violation: External transfers (i_token.transfer) occur before updating state, and the crucial state reset (remainingRewards = 0) is omitted entirely.
Reentrancy Vector: Tokens with callback mechanisms (such as ERC777 or ERC677) allow malicious contracts to re-enter closePot() during the transfer phase.
Double Payment Risk: Re-entering the function before state changes are committed allows the manager and claimants to receive duplicate payouts, resulting in severe fund loss.
Note: Automated test setup failed due to ERC20 allowance issues with mock, but vulnerability is real for callback tokens.
Execution Command (when test fixed):
The closePot function implements two key mitigations against reentrancy attacks: it uses OpenZeppelin’s ReentrancyGuard with the nonReentrant modifier, and it follows the Checks-Effects-Interactions pattern by setting remainingRewards to zero before any external token transfers, ensuring state is updated before interacting with untrusted contracts.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.