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:
The 'grantRole' function can be called by anyone to assign the 'MINTER_ROLE' to themselves.
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.
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:
The 'MintExploit' contract takes the address of the 'BeanstalkERC20' contract as a constructor argument.
The 'exploit' function grants the 'MINTER_ROLE' to the 'MintExploit' contract using the 'grantRole' function.
With the 'MINTER_ROLE', the 'MintExploit' contract calls the 'mint' function on the 'BeanstalkERC20' contract, minting a large amount of tokens (1e18) to itself.
The 'balanceOf' function is called to verify that the tokens have been successfully minted.
How to reproduce:
Deploy the 'BeanstalkERC20' contract.
Deploy the 'MintExploit' contract, passing the address of the 'BeanstalkERC20' contract as a constructor argument.
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");
}
}