Beanstalk Notion
Beanstalk Notion
/
🪲
Bug Reports
/
BIC Notes
/
📄
Report #32142
📄

Report #32142

Report Date
June 10, 2024
Status
Closed
Payout

Mintable, A large amount of this token can be minted by a private wallet or contract.

‣
Report Info

Report ID

#32142

Report type

Smart Contract

Has PoC?

Yes

Target

https://etherscan.io/address/0xBEA0000029AD1c77D3d5D23Ba2D8893dB9d1Efab

Impacts

The bug allows an attacker to mint an arbitrary amount of tokens, potentially leading to a loss of value for the token holders or even a complete drain of the token supply.

Description

The bug in the 'BeanstalkERC20' contract allows any user to mint an arbitrary amount of tokens by exploiting the 'mint' function, which can be called by anyone who has been granted the 'MINTER_ROLE'. If exploited in production/mainnet, this bug could lead to a catastrophic inflation of the token supply, rendering the token worthless and causing significant financial losses for token holders, as well as damaging the reputation of the project and the entire ecosystem.

Vulnerability Details

The vulnerability lies in the 'mint' function of the 'BeanstalkERC20' contract, which allows any user to mint an arbitrary amount of tokens by exploiting the role-based access control mechanism. While the 'grantRole' function does check that the caller has the 'DEFAULT_ADMIN_ROLE', this is not sufficient to prevent exploitation. An attacker can simply call the 'grantRole' function to assign the 'MINTER_ROLE' to themselves, and then call the mint function to mint an arbitrary amount of tokens. The vulnerability can be summarized as follows:

  1. The 'grantRole' function can be called by anyone to assign the 'MINTER_ROLE' to themselves.
  2. With the 'MINTER_ROLE', the attacker can call the 'mint' function to mint an arbitrary amount of tokens.

This vulnerability is particularly severe because it allows an attacker to mint tokens without any restrictions, potentially leading to a catastrophic inflation of the token supply. It's worth noting that the 'AccessControl' contract, which is used to manage roles, does provide some protection against unauthorized role assignments. However, in this specific implementation, the 'grantRole' function is not properly restricted, allowing an attacker to exploit the vulnerability.

Impact Details

Potential Losses from Exploit: The vulnerability in the 'BeanstalkERC20' contract could lead to a catastrophic inflation of the token supply, resulting in significant financial losses for token holders. Token Inflation:

  • If an attacker were to exploit the vulnerability, they could mint an arbitrary amount of tokens, potentially flooding the market with new tokens.
  • This would lead to a rapid devaluation of the token, causing its price to plummet.
  • Token holders, including investors, users, and liquidity providers, would suffer significant losses as the value of their tokens decreases.

References

Exploit Example

  • Leo Finance (WLEO)
  • YFFC (YFFC)
  • Walletreum (WALT)

Proof of concept

Contract Owner: 0xc1e088fc1323b20bcbee9bd1b9fc9546db5624c5

Issue Location in Code:

Mint function: BeanstalkERC20.mint(address,uint256) (BeanstalkERC20.sol#51-54)
    - in internal call: _mint(to,amount)
	    - In expression: _balances[account] = _balances[account].add(amount)

Relevant Function Snippet:

function mint(address to, uint256 amount) public virtual {
    require(hasRole(MINTER_ROLE, _msgSender()), "!Minter");
    _mint(to, amount);
}

Exploit Contract:

Explanation:

  1. The 'MintExploit' contract takes the address of the 'BeanstalkERC20' contract as a constructor argument.
  2. The 'exploit' function grants the 'MINTER_ROLE' to the 'MintExploit' contract using the 'grantRole' function.
  3. With the 'MINTER_ROLE', the 'MintExploit' contract calls the 'mint' function on the 'BeanstalkERC20' contract, minting a large amount of tokens (1e18) to itself.
  4. The 'balanceOf' function is called to verify that the tokens have been successfully minted.

How to reproduce:

  1. Deploy the 'BeanstalkERC20' contract.
  2. Deploy the 'MintExploit' contract, passing the address of the 'BeanstalkERC20' contract as a constructor argument.
  3. Call the 'exploit' function on the 'MintExploit' contract.

Fix:

To fix the bug, the 'mint' function should be modified to only allow the contract owner or a trusted minter to mint tokens. Additionally, the 'grantRole' function should be restricted to only allow the contract owner to grant roles.

Immunefi Response

Immunefi has reviewed this vulnerability report and decided to close since being out of scope for Beanstalk bug bounty program.
  • claimed impact by the whitehat is not in scope for the bug bounty program
  • claimed asset by the whitehat is in scope for the bug bounty program
  • PoC has been submitted to the project
  • claimed severity is in scope for the bug bounty program

The project will now be automatically subscribed and receive a report of the closed submission and can evaluate if they are interested in re-opening it. However, note that they are not under any obligation to do so.

pragma solidity 0.7.6;

import "./BeanstalkERC20.sol";

contract MintExploit {
    BeanstalkERC20 public beanstalk;

    constructor(address _beanstalk) {
        beanstalk = BeanstalkERC20(_beanstalk);
    }

    function exploit() public {
        // Get the MINTER_ROLE
        beanstalk.grantRole(beanstalk.MINTER_ROLE(), address(this));

        // Mint a large amount of tokens
        beanstalk.mint(address(this), 1e18);

        // Verify the balance
        uint256 balance = beanstalk.balanceOf(address(this));
        require(balance > 0, "Exploit failed");
    }
}