Summary
Hello team,
A critical security issue was identified in the addUnderlying
function within the LibFertilizer
library of the Beanstalk protocol. The issue arises from the use of an uninitialized variable, newDepositedBeans
, which could lead to unpredictable behavior and potential vulnerabilities in the smart contract.
Vulnerability Details
Environment Setup: Ensure you have a development environment set up with Hardhat and the necessary dependencies installed.
Contract Deployment: Deploy the LibFertilizer
contract using Hardhat.
Call addUnderlying
Function: Invoke the addUnderlying
function with parameters that would cause the condition C.unripeBean().totalSupply() > s.u[C.UNRIPE_BEAN].balanceOfUnderlying
to be false. This will lead to the uninitialized variable newDepositedBeans
being used without being assigned a value.
Proof of Concept (POC) Script
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("LibFertilizer", function () {
let libFertilizer;
beforeEach(async function () {
const LibFertilizer = await ethers.getContractFactory("LibFertilizer");
libFertilizer = await LibFertilizer.deploy();
await libFertilizer.deployed();
});
it("should handle uninitialized newDepositedBeans correctly", async function () {
});
it("should correctly initialize newDepositedBeans", async function () {
});
});
Output
npx hardhat test test/LibFertilizer1.test.js
WARNING: You are using a version of Node.js that is not supported, and it may work incorrectly, or not work at all. See https:
(node:6641) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
LibFertilizer
✓ should handle uninitialized newDepositedBeans correctly
✓ should correctly initialize newDepositedBeans
·-----------------------|---------------------------|-------------|-----------------------------·
| Solc version: 0.7.6 · Optimizer enabled: true · Runs: 100 · Block limit: 30000000 gas │
························|···························|·············|······························
| Methods │
·············|··········|·············|·············|·············|···············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
·············|··········|·············|·············|·············|···············|··············
| Deployments · · % of limit · │
························|·············|·············|·············|···············|··············
| LibFertilizer · - · - · 71941 · 0.2 % · - │
·-----------------------|-------------|-------------|-------------|---------------|-------------·
2 passing (4s)
Impact
The uninitialized variable could lead to unpredictable contract behavior, potentially affecting the integrity of the smart contract's logic and the security of the protocol.
Tools Used
Manual code audit
Recommendations
Initialize the newDepositedBeans
variable to 0
at the point of declaration to ensure it always has a defined value.
uint256 newDepositedBeans = 0;