Normal behavior: ERC‑4626 exposes public entry points (deposit, mint, withdraw, redeem) that funnel to internal workflows (_deposit, _withdraw). Implementations that add custom rules (fees, participation checks, per-user bookkeeping) must ensure all public flows execute the same internal rules so shares always represent the same economic claim.
Actual problem: BriVault implements participation fees and per-user bookkeeping in its public deposit(...) override, but leaves the standard ERC‑4626 mint/redeem (and their internal _deposit/_withdraw behavior) pointing at OpenZeppelin’s base flows. This allows callers to use mint/redeem to acquire or redeem shares without the participation fee or the stakedAsset / userSharesToCountry bookkeeping being updated, creating accounting inconsistencies and economic bypasses.
Likelihood:
External users, integrators, or bots use the standard mint(...) entrypoint (exposed by ERC‑4626) to acquire shares.
Wallets, aggregators, or other smart contracts that assume standard ERC‑4626 behavior call mint/redeem instead of the custom deposit/withdraw.
Impact:
Participation fees are bypassed and participationFeeAddress receives fewer fees, causing revenue leakage.
Shares can be created without stakedAsset or userSharesToCountry bookkeeping; resulting shares are not tracked for the tournament logic and can be moved/transferred to corrupt winner calculations or be redeemed via ERC‑4626 flows, corrupting final payouts.
Explanation of this PoC:
user5 approves the vault to spend 5 ETH worth of the mock token.
mint() is called directly, bypassing the deposit() logic that would normally handle:
Participation fee transfer to participationFeeAddress.
Updating stakedAsset[user].
Any country/tournament bookkeeping (userSharesToCountry).
Assertions confirm that no vault bookkeeping occurred (stakedAsset and userSharesToCountry remain 0).
user5 can transfer the shares to another participant, effectively inflating their voting/withdrawal power without paying the fee.
Short explanation: unify BriVault’s custom rules (participation fee, minimum amount, per-user stakedAsset bookkeeping, and any restrictions on timing) into the internal ERC‑4626 workflows by overriding _deposit and _withdraw (the internal hooks). That way all public entrypoints (deposit and mint) go through the same logic and cannot bypass fees or bookkeeping. Also ensure preview and limit functions reflect the new semantics.
Functions to update: _deposit, _withdraw, and (optionally) previewMint, previewRedeem, maxDeposit, maxMint.
Notes and follow-ups:
Update previewMint, previewRedeem, maxDeposit, maxMint to reflect the effective assets/shares and any caps the vault imposes (OpenZeppelin warns that overrides must be consistent across public and preview functions).
Carefully test rounding edge cases in _convertToShares / _convertToAssets after integrating fee logic.
If exact proportional decrement of stakedAsset on redeem is not desired (because tournament logic treats deposits as locked until end), consider disallowing redeem for tournament shares (but keep ERC‑4626 compatibility by documenting this behavior and implementing maxRedeem/maxWithdraw appropriately).
This change preserves ERC‑4626 public surface (mint/redeem) while guaranteeing no public path can bypass participation fees or the vault’s bookkeeping.
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.