Normal Process
Users deposit ERC20 tokens (paying a 1.5% fee), call joinEvent(countryId) once to bet on a single team, and their shares are
recorded. After the event ends, the owner sets the winning team, and winners withdraw their proportional share of the pooled
assets. Each user should only bet on one team once, maintaining fair accounting.
Vulnerability
The joinEvent() function lacks validation to prevent users from calling it multiple times. There is no check to verify whether a user has already joined the event.
Likelihood: High
Reason 1 - No Technical Barrier - The function is public with no re-entry protection. Any user can call it repeatedly.
Reason 2 - Zero Cost to Attacker - After initial deposit, re-joining costs only gas fees. No additional deposits or fees required.
Reason 3 - Easily Discoverable - Obvious from reading code or basic testing.
Impact: High
Impact 1 - Payout Dilution Exploit - Attacker on winning team joins 1000 times, causing their shares to be counted repeatedly.
Impact 2 - Attacker Can Bet on Multiple Countries Free - Attacker bets on all 48 countries with one deposit, guaranteeing they're on the winning team. Combined with Impact 1, enables payout dilution attack with certainty.
Impact 3 - Unlimited Free Re-entries - No validation prevents re-joining.
Overview
The joinEvent() function lacks validation to prevent users from calling it multiple times.
Actors
Attacker (user1):
Deposits once, then exploits missing re-entry protection by calling joinEvent()
multiple times, inflating their share count in the payout calculation.
Victim (user2):
Legitimate user who deposits, joins once as intended, and expects fair payout when their team wins.
Protocol (BriVault): Incorrectly allows multiple joins from same user, corrupting state.
Working Test Case
Include the below function test in the briVault.t.sol file.
Run it with forge test --mt test_UserCannot_joinEvent_MultipleTimes -vvvvv
This will show how user 1 is added to the pool a second time and the test will fail.
Solution: Add Re-Entry Protection
Add a validation check at the beginning of joinEvent() to verify the user hasn't already joined.
Implementation
Step 1: Add new error declaration (at line 66 in briVault.sol).
Step 2: Add validation check in joinEvent() function (line 258):
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.