Vault shares remain transferable because BriVault inherits ERC20 from ERC4626. Tournament state, however, is keyed by the original depositor: userToCountry and userSharesToCountry are only set inside joinEvent (src/briVault.sol:260-262) and are never updated on transfers. If a participant transfers their shares—or grants an allowance that is pulled—the new holder lacks a team assignment and fails the didNotWin() branch in withdraw() (src/briVault.sol:299-303), while the original depositor owns no shares to redeem.
Likelihood: High – ERC4626 shares are designed to be transferred or pooled; even routine allowance patterns can trigger this.
Winners who move their shares lose 100% of their stake; the vault retains the funds.
Attackers can grief victims by pulling approved shares to another address.
User deposits, joins a team, then transfers all shares to another address.
Owner finalizes in favour of that team.
Original depositor calls withdraw() → receives 0 tokens (no shares).
New share holder calls withdraw() → reverts with didNotWin().
(Demonstrated in test/BriVaultAttack.t.sol:228 through testShareTransferLocksFunds.)
Either disable share transfers by overriding _update/_transfer to revert, or
Track team assignments and share snapshots per holder, updating mappings on every transfer/allowance consumption.
Add tests for transfer, transferFrom, and approval flows to ensure accounting remains consistent.
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.