Because BriVault leaves ERC4626 mint unrestricted, a participant can enlarge their share balance after joining without paying additional fees or updating team allocations. userSharesToCountry is captured during joinEvent (src/briVault.sol:260-262) and never refreshed. When setWinner sums the cached values, the denominator is smaller than the live winning supply. The bespoke withdraw() then computes assetToWithdraw using the bloated numerator, causing SafeERC20.safeTransfer to revert.
Likelihood: High – calling mint is a single transaction and requires no new permissions.
Winners who (intentionally or accidentally) mint after joining cause all withdrawals for that team to revert.
Attacker avoids participation fees while locking the entire prize pool.
User deposits and joins before the event starts.
After eventStartDate, user calls briVault.mint(briVault.balanceOf(user), user).
Owner finalizes with setWinner(team).
Calling withdraw() reverts with "ERC20: transfer amount exceeds balance".
(Captured in test/BriVaultAttack.t.sol:179 as testMintAfterJoinBreaksWinnerWithdrawal.)
Override/disable ERC4626 mint, withdraw, and redeem unless they honour the tournament lifecycle and fee model.
Keep userSharesToCountry synchronized with live balances or compute allocations from current shares when withdrawing.
Add invariant tests ensuring assetToWithdraw never exceeds the vault’s actual balance.
Proposed patch (Solidity-like pseudocode):
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.