BriVault

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

deposit() mints shares to msg.sender instead of receiver, breaking accounting and allowing fund misallocation

deposit() mints shares to msg.sender instead of receiver, breaking accounting and allowing fund misallocation


Description

  • In a standard ERC-4626 vault, the deposit() function is expected to transfer assets from the depositor (msg.sender) and mint the corresponding vault shares to the specified receiver. This enables third-party deposits, preserves accounting consistency, and maintains compliance with the ERC-4626 specification.

  • In BriVault.deposit(), the implementation incorrectly mints vault shares to msg.sender instead of receiver. This creates a logical mismatch because the function records stakedAsset under receiver but grants the minted shares to msg.sender. As a result, the vault’s internal accounting becomes inconsistent: stakedAsset[receiver] and balanceOf(receiver) no longer represent the same participant. This breaks subsequent functions like joinEvent(), cancelParticipation(), and withdraw() that assume these two mappings belong to the same user.

// BriVault.sol (inside deposit function)
stakedAsset[receiver] = stakeAsset;
uint256 participantShares = _convertToShares(stakeAsset);
IERC20(asset()).safeTransferFrom(msg.sender, participationFeeAddress, fee);
IERC20(asset()).safeTransferFrom(msg.sender, address(this), stakeAsset);
@> _mint(msg.sender, participantShares); // ❌ Should mint to receiver, not msg.sender
emit deposited(receiver, stakeAsset);

Risk

Likelihood:

  • This occurs whenever a user deposits assets into the vault, the error is inherent in every deposit call.

  • Any function relying on stakedAsset[msg.sender] and balanceOf(msg.sender) alignment (like joinEvent() and withdraw()) will behave incorrectly.

Impact:

  • The participant recorded as a depositor (receiver) will not receive vault shares, causing a mismatch between stakedAsset[receiver] and balanceOf(receiver). As a result, the legitimate participant will fail checks such as stakedAsset[msg.sender] == 0 in joinEvent() and cancelParticipation(), preventing them from joining the event or withdrawing their stake.

  • The depositor (msg.sender), who incorrectly receives the shares via _mint(msg.sender, participantShares), can still call functions like balanceOf(msg.sender), withdraw(), and cancelParticipation() to interact with the vault as if they were the rightful participant. This misalignment allows unauthorized withdrawals, incorrect reward claims, and potential total loss of funds belonging to the actual participant (receiver).


Proof of Concept

// 1. Karen deposits on behalf of Sid
vault.deposit(1000e6, address(Sid)); // msg.sender = Karen, receiver = Sid
// 2. Contract records:
stakedAsset[Sid] = 1000e6; // ✅ recorded for Sid
balanceOf(Karen) = 1000e6; // ❌ shares minted to Karen, not Sid
// 3. Sid attempts to join event
vault.joinEvent(1); // reverts with noDeposit() because stakedAsset[Sid]!=0 but balanceOf(Sid)==0
// 4. Karen (who is not the participant) can now withdraw as if she were Sid,
// potentially receiving rewards for a country she never joined.

The proof of concept shows that when one user deposits on behalf of another, the receiver is recorded as the participant but does not receive shares, breaking subsequent participation and withdrawal logic.


Recommended Mitigation

- _mint(msg.sender, participantShares);
+ _mint(receiver, participantShares)

Additionally, consider accumulating staked amounts to prevent overwriting:

- stakedAsset[receiver] = stakeAsset;
+ stakedAsset[receiver] += stakeAsset;

Mint vault shares to the specified receiver instead of msg.sender to align with ERC-4626 standards and ensure consistent ownership and accounting.

Updates

Appeal created

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

Shares Minted to msg.sender Instead of Specified Receiver

Support

FAQs

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

Give us feedback!