BriVault

First Flight #52
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

withdraw() Uses balanceOf() Instead of stakedAsset() — Attacker Can Drain Entire Vault

Root + ImpactRoot + Impact

Description

  • Normal Behavior:
    During withdrawals, a participant should only be able to redeem tokens proportional to their actual deposited shares (stakedAsset[msg.sender]).
    The vault’s payout calculation should be based on the legitimate shares each user obtained through deposits.

  • Specific Issue:
    The withdraw() function incorrectly uses balanceOf(msg.sender) instead of stakedAsset[msg.sender].
    Since balanceOf() is based on minted ERC20 shares — not actual deposits — an attacker can artificially inflate their balance through direct token transfers to the vault.
    When withdraw() is called, this inflated share balance is used in the reward ratio, allowing the attacker to drain the entire vault.

// withdraw()
uint256 shares = balanceOf(msg.sender); // @> WRONG — can be manipulated
uint256 assetToWithdraw = Math.mulDiv(shares, vaultAsset, totalWinnerShares);
IERC20(asset()).safeTransfer(msg.sender, assetToWithdraw);

Risk

Likelihood:

  • Very High — Exploitable by any user with direct ERC-20 access to the vault.

  • No permission or special setup required.

Impact:

  • Vault Drained: Attacker can withdraw all funds.

  • Permanent Fund Loss: Honest users receive nothing.

  • Systemic Exploit: A single malicious participant can bankrupt the vault.


Proof of Concept

NA

Recommended Mitigation

// withdraw()
- uint256 shares = balanceOf(msg.sender);
+ uint256 shares = stakedAsset[msg.sender]; // ✅ Withdraw only legitimate deposits
+ stakedAsset[msg.sender] = 0; // Clear record after withdrawal
Updates

Appeal created

bube Lead Judge 21 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Inflation attack

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!