matchRewards — Latent ExploitabilityLikeRegistry.sol
matchRewards() performs an external low-level call multiSigWallet.call{value: rewards}() without a nonReentrant modifier on likeUser(). While userBalances is zeroed before the call (partial CEI), there is no reentrancy guard on the entry function. Currently latent because rewards = 0 (H-01), but becomes exploitable if H-01 is fixed without adding reentrancy protection.
Likelihood: Low — Requires H-01 to be fixed first. The MultiSig wallet's receive() is benign.
Impact: High — If triggered, could drain user balances via repeated matchRewards calls.
Severity: Medium
SWC: SWC-107 (Reentrancy)
CWE: CWE-841
Evidence Grade: B (pattern confirmed, economic impact latent)
Assume H-01 is fixed and userBalances is properly tracked. Alice and Bob each deposit 1 ETH. When Bob likes Alice (creating a mutual match), matchRewards() executes. It zeroes userBalances for both users, then performs multiSigWallet.call{value: rewards}(""). If the MultiSig wallet's receive() were replaced with a malicious contract that re-enters likeUser() (via a third account that also likes one of the matched users), the attacker could re-trigger matchRewards() before the first call completes. Currently dormant because rewards = 0 due to H-01.
OpenZeppelin's ReentrancyGuard adds a mutex lock that prevents any external call from re-entering the protected function. Applying nonReentrant to likeUser() ensures that even if matchRewards() triggers a callback (via the MultiSig wallet's receive() or a malicious contract), the re-entrant likeUser() call will revert. This closes the reentrancy window regardless of how H-01 is fixed in the future.
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.