BriVault

First Flight #52
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Confusing token setup (duplicate symbol/name)

Description

  • The ERC‑4626 share token (the vault token users receive) should have a distinct name & symbol from the underlying asset token to prevent UI, explorer, integration, and router confusion. Typically, vault shares use a prefix/suffix like vBTT, bvBTT, or BTTv.

  • Both contracts define the same name and symbol:

    • BriTechToken: ERC20("BriTechLabs", "BTT")

    • BriVault (ERC4626 shares): also ERC20("BriTechLabs", "BTT")

  • This creates two different tokens with identical metadata, making it ambiguous which token a user holds, breaking integrations and potentially leading to wrong approvals, transfers, or accounting.

// briTechToken.sol
contract BriTechToken is ERC20, Ownable {
constructor() ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {}
...
}
// briVault.sol
contract BriVault is ERC4626, Ownable {
...
constructor(IERC20 _asset, ...) ERC4626(_asset) ERC20("BriTechLabs", "BTT") Ownable(msg.sender) { // @> duplicate name+symbol
...
}
...
}

Risk

Likelihood: Low

  • Any UI or script that reads token metadata will see two “BTT” tokens named “BriTechLabs” and can easily select the wrong one for approvals, transfers, balances, or portfolio views.

  • Wallets/explorers commonly cache by symbol/name, causing mislabeling or aggregation bugs when two different contracts share the same identifiers.

Impact: Low

  • User fund loss due to wrong action: Users may approve or transfer the asset token when they intended to move vault shares, or vice‑versa, causing failed withdrawals, stuck funds, or mispriced trades.

  • User fund loss due to wrong action: Users may approve or transfer the asset token when they intended to move vault shares, or vice‑versa, causing failed withdrawals, stuck funds, or mispriced trades.

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Test} from "forge-std/Test.sol";
import {BriTechToken} from "../src/briTechToken.sol";
import {BriVault} from "../src/briVault.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract DuplicateSymbolNameTest is Test {
BriTechToken asset;
BriVault vault;
function setUp() public {
asset = new BriTechToken();
vault = new BriVault(IERC20(address(asset)), 150, block.timestamp + 1 days, address(0xFEE), 1, block.timestamp + 8 days);
}
function test_DuplicateMetadata() public {
// Both tokens present the same name & symbol
assertEq(asset.name(), "BriTechLabs");
assertEq(asset.symbol(),"BTT");
assertEq(vault.name(), "BriTechLabs");
assertEq(vault.symbol(),"BTT"); // ← duplicate
}
function test_UserConfusionScenario() public {
address user = makeAddr("user");
// User approves "BTT" by symbol in their UI, but it's ambiguous which one.
// Many UIs list both as “BTT”, leading to wrong approval target selection
// (cannot assert UI behavior on-chain, but this documents the practical hazard).
vm.prank(user);
asset.approve(address(vault), 100 ether); // user might think this approves shares, not the asset
// Later, vault interactions fail or behave unexpectedly due to mismatch.
}
}

Recommended Mitigation

  • Assign unique metadata to the vault share token and keep the asset token metadata unchanged. Optionally add an explicit decimals() override for clarity.

@@
-contract BriVault is ERC4626, Ownable {
+contract BriVault is ERC4626, Ownable {
@@
- constructor (IERC20 _asset, uint256 _participationFeeBsp, uint256 _eventStartDate, address _participationFeeAddress, uint256 _minimumAmount, uint256 _eventEndDate)
- ERC4626(_asset) ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {
+ constructor (
+ IERC20 _asset,
+ uint256 _participationFeeBsp,
+ uint256 _eventStartDate,
+ address _participationFeeAddress,
+ uint256 _minimumAmount,
+ uint256 _eventEndDate
+ )
+ ERC4626(_asset)
+ // Give shares a distinct name/symbol to avoid ambiguity with the underlying asset.
+ ERC20("BriVault Share", "bvBTT")
+ Ownable(msg.sender)
+ {
...
}
Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!