BriVault

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

Centralized Minting of Vault's Underlying Asset

Root + Impact

Description

  • The underlying asset for a vault should be a hard asset with a predictable, trustworthy, and decentralized supply (like WETH, or USDC). This ensures that the value of the assets deposited by users is stable and not subject to arbitrary inflation.

  • The BriTechToken (BTT), which is used as the vault's asset, is not a hard asset. It has an unrestricted, onlyOwner mint() function that can be called repeatedly. This allows the owner to create a virtually unlimited supply of new tokens at no cost, whenever they wish.

contract BriTechToken is ERC20, Ownable {
constructor() ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {}
@> function mint() public onlyOwner {
@> _mint(owner(), 10_000_000 * 1e18);
}
}

Risk

Likelihood:

  • The attack is permissionless for the owner and has no pre-conditions. The owner can call the mint() function at any time, for free, with a single transaction.

  • This represents a critical conflict of interest, as the owner (who controls the vault) also has a print money button for the vault's underlying asset, giving them a direct and trivial path to steal all user funds.

Impact:

  • The owner can wait for users to deposit their BTT into the vault. The owner can then call mint() 100 times, create billions of new BTT, deposit them into the vault, and claim 99.9% of all vault shares. They can then withdraw all the legitimate users' funds.

  • The owner can mint billions of new BTT and dump them on the market, crashing the token's price to zero. All the BTT held in the BriVault would instantly become worthless.

Proof of Concept

This is a conceptual "rug pull" scenario:

  1. A victim buys 1,000,000 BTT on a DEX with 10 ETH and deposits them into the BriVault.

  2. The owner calls mint() 10 times, creating 100,000,000 new BTT for free.

  3. The owner deposits their 100M BTT into the vault. The victim now owns less than 1% of the vault's shares, and their deposit has been effectively stolen.

Recommended Mitigation

The token's minting function must not be based on the owner's trust. The contract should be refactored into a collateral-backed token, where anyone can mint new tokens, but only by locking up a 1:1 equivalent of a "hard" asset (like WETH or USDC).

+import {IERC20} from "@openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
+import {SafeERC20} from "@openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
-contract BriTechToken is ERC20, Ownable {
- constructor() ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {}
+contract BriTechToken is ERC20, Ownable {
+ using SafeERC20 for IERC20;
+
+ // The hard asset that backs BTT, e.g., WETH, USDC, or DAI
+ IERC20 public immutable collateral;
+
+ constructor(address _collateral)
+ ERC20("BriTechLabs", "BTT")
+ Ownable(msg.sender)
+ {
+ collateral = IERC20(_collateral);
+ }
+
+ /**
+ * @notice Mints new BTT by locking an equal amount of collateral.
+ * @param amount The amount of collateral to lock and BTT to mint.
+ */
+ function mint(uint256 amount) public {
+ require(amount > 0, "Mint amount must be > 0");
+
+ // 1. Pull the collateral from the user
+ collateral.safeTransferFrom(msg.sender, address(this), amount);
+
+ // 2. Mint the new BTT to the user
+ _mint(msg.sender, amount);
+ }
+
+ /**
+ * @notice Burns BTT and returns an equal amount of collateral.
+ * @param amount The amount of BTT to burn and collateral to redeem.
+ */
+ function redeem(uint256 amount) public {
+ require(amount > 0, "Redeem amount must be > 0");
+
+ // 1. Burn the user's BTT
+ _burn(msg.sender, amount);
+
+ // 2. Send the collateral back to the user
+ collateral.safeTransfer(msg.sender, amount);
+ }
- function mint() public onlyOwner {
- _mint(owner(), 10_000_000 * 1e18);
- }
}
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!