Improper ERC20 Handling in LibTransfer Enables Tokenless Deposits and Illegitimate Minting
Report ID
#44213
Report Type
Smart Contract
Has PoC
Yes
Target
https://etherscan.io/address/0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5
Impacts
- Illegitimate minting of protocol native assets
- Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Contract fails to deliver promised returns, but doesn't lose value
Details
The Beanstalk protocol uses a custom safeTransferFrom() function inside LibTransfer that fails to properly validate return values from ERC20 token transfers. This allows an attacker to use a malicious ERC20 token that omits the return value, leading the protocol to believe a transfer succeeded when in reality it may have failed or not occurred at all. As a result, the attacker can interact with functions like deposit() and receive protocol-native credits or rewards without actually transferring any tokens.
Vulnerability Details
According to the ERC20 standard, transferFrom() must return a boolean value indicating success. However, not all ERC20 tokens strictly follow this rule. In the current Beanstalk implementation, the function safeTransferFrom() does not properly decode or check this return value. Instead, it assumes success even if the transfer result is missing or malformed.
This opens the door for attackers to:
- Deploy a custom ERC20 token where
transferFrom()does not return a value. - Use this token in functions like
deposit()or any function that invokesLibTransfer.safeTransferFrom(). - Trick the protocol into recording a successful deposit, thus potentially receiving unearned rewards or triggering additional downstream logic.
Example malicious token:
function transferFrom(address from, address to, uint256 amount) public override returns () {
_transfer(from, to, amount);
// No return value at all
}Impact Details
This vulnerability leads to false assumptions within the protocol's internal accounting. The attacker can use the above token to:
- Falsely increase their deposited balance
- Claim rewards or BEAN tokens without actually contributing value
- Manipulate the state of the system or dilute the value of legitimate users' deposits
If chained with other logic that allows withdrawal or reward conversion, this can escalate into direct financial loss or inflation of the BEAN supply. At minimum, it represents a significant integrity flaw and opens the door to systemic abuse.
References
- Affected main contract: https://etherscan.io/address/0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5
- ERC20 spec: https://eips.ethereum.org/EIPS/eip-20
Proof of Concept
- Deploy a malicious ERC20 token with a
transferFrom()function that does not return a value (as shown below). - Whitelist this token in the Beanstalk protocol (if needed, depending on integration).
- Call
deposit()or any function that usesLibTransfer.safeTransferFrom()with the malicious token. - Observe that the transaction succeeds and the protocol assumes tokens were transferred — even though they were not.
- Internal accounting is updated, and the attacker can receive credits or rewards without providing real value.
Malicious Token Contract
Why It Works
- Beanstalk's
LibTransfer.safeTransferFrom()fails to validate the return value of thetransferFrom()call. - As a result, the protocol assumes success even when the token does not return true/false, allowing attackers to trick the system.
- This creates a vector for:
- Reward abuse
- Fake deposits
- Potential downstream exploits through inflated balances
Recommendation
Update safeTransferFrom() to validate the return value as follows:
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)
);
require(success && (data.length == 0 || abi.decode(data, (bool))), "Transfer failed");BIC Response
The vulnerability you describe would only apply if malicious ERC20 tokens were whitelisted for deposit. Therefore we are closing this report and no reward will be issued.