The BriVault contract implements a custom withdraw() function with game logic restrictions. However, the contract inherits from ERC4626 which provides unrestricted withdrawal functions.
As a result, users can still call these inherited functions directly to withdraw their underlying ERC20 assets at any time, bypassing the tournament’s event schedule and winner selection logic. This completely undermines the intended design, since users can withdraw before the event ends or after knowing partial outcomes.
Likelihood: High
This issue is trivial to exploit. Any user or bot familiar with ERC-4626’s ABI can call withdraw() or redeem() directly. No special timing or conditions are needed.
Impact:
Users can drain the vault’s assets prematurely.
The contract fails to enforce its fundamental rule: assets must remain locked until the tournament concludes.
Step 1: Users deposit for upcoming World Cup
Vault balance: 29.55 ETH (3 users × 10 ETH each minus fees)
Step 2: Event starts - World Cup begins!
Deposits should be LOCKED until event ends
Step 3: User1 tries custom withdraw() during event
Result: REVERTED (winnerNotSet) - GOOD!
Step 4: User1 uses ERC4626 redeem() during event
Result: SUCCESS - User1 withdrew during event!
Assets received: 9.85 ETH
Step 5: User2 also uses ERC4626 withdraw()
Result: SUCCESS - User2 also withdrew!
Assets received: 9.85 ETH
Vault before drain: 29.55 ETH
Vault after drain: 9.85 ETH
Amount drained: 19.7 ETH (66%)
Step 6: Event ends
Step 7: User3 (winner) tries to withdraw
Expected: 29.55 ETH (all deposits)
Actual: 9.85 ETH
Explicitly override and disable the inherited withdraw() and redeem() functions.
Or the other option is to override them with proper restrictions to perform valid withdrawals.
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.