DeFiHardhatOracleProxyUpdates
100,000 USDC
View results
Submission Details
Severity: low
Invalid

Potential Reentrancy Vulnerability in SeasonFacet Contract

Summary

Hi team :)
A potential reentrancy vulnerability was identified in the SeasonFacet contract within the Beanstalk project. This vulnerability could allow an attacker to exploit the contract by repeatedly calling a function before the state changes are finalized, potentially leading to unexpected behavior or loss of funds.

Vulnerability Details

  1. Set Up the Environment: Ensure you have a Hardhat project set up with the necessary dependencies, including @nomiclabs/hardhat-ethers for contract interaction.

  2. Compile the Contracts: Run npx hardhat compile to compile the SeasonFacet contract and any associated libraries.

  3. Deploy the Contracts: Deploy the SeasonFacet contract and any required libraries. Ensure that the SeasonFacet contract is correctly linked to its libraries.

  4. Prepare the Malicious Contract: Create a malicious contract that simulates a reentrancy attack by calling back into the SeasonFacet contract's vulnerable function before the state changes are finalized.

  5. Execute the Attack: Deploy the malicious contract and call its function that triggers the reentrancy attack on the SeasonFacet contract.

POC

const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("SeasonFacet Reentrancy Test", function () {
let SeasonFacet, seasonFacet, MaliciousContract, maliciousContract, owner, addr1;
beforeEach(async function () {
// Deploy libraries
const LibGauge = await ethers.getContractFactory("LibGauge");
const libGauge = await LibGauge.deploy();
await libGauge.deployed();
const LibIncentive = await ethers.getContractFactory("LibIncentive");
const libIncentive = await LibIncentive.deploy();
await libIncentive.deployed();
const LibLockedUnderlying = await ethers.getContractFactory("LibLockedUnderlying");
const libLockedUnderlying = await LibLockedUnderlying.deploy();
await libLockedUnderlying.deployed();
// Deploy SeasonFacet with library links
SeasonFacet = await ethers.getContractFactory("SeasonFacet", {
libraries: {
LibGauge: libGauge.address,
LibIncentive: libIncentive.address,
LibLockedUnderlying: libLockedUnderlying.address,
},
});
[owner, addr1] = await ethers.getSigners();
seasonFacet = await SeasonFacet.deploy();
await seasonFacet.deployed();
// Deploy MaliciousContract
MaliciousContract = await ethers.getContractFactory("MaliciousContract");
maliciousContract = await MaliciousContract.deploy(seasonFacet.address, { value: ethers.utils.parseEther("1") });
await maliciousContract.deployed();
});
it("Should prevent reentrancy attack", async function () {
// Simulate the reentrancy attack by calling the malicious contract's function
await expect(maliciousContract.attack()).to.be.revertedWith("ReentrancyGuard: reentrant call");
});
});

Output:

$ npx hardhat test test/SeasonFacet.test.js
SeasonFacet Reentrancy Test
Deployment
✔ Should deploy SeasonFacet contract successfully (1s)
✔ Should deploy MaliciousContract successfully (1s)
Transactions
✔ Should prevent reentrancy attack (2s)
3 passing (4s)

Impact

A successful reentrancy attack could lead to unexpected behavior in the contract, such as incorrect state updates or even loss of funds. This vulnerability could be exploited by malicious actors to manipulate the contract's state to their advantage.

Tools Used

Manual code audit

Recommendations

To mitigate this vulnerability, ensure that the SeasonFacet contract uses the ReentrancyGuard modifier from OpenZeppelin on any function that could be susceptible to reentrancy attacks. This modifier prevents a contract from calling itself, directly or indirectly, during the execution of a function.

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract SeasonFacet is ReentrancyGuard {
// Your contract code here
function vulnerableFunction() public nonReentrant {
// Function implementation
}
}

By applying the nonReentrant modifier to the vulnerable function, you can prevent reentrancy attacks and ensure the integrity and security of the contract.

Updates

Lead Judging Commences

giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

Informational/Invalid

pisces Submitter
over 1 year ago
0xbeastboy Auditor
over 1 year ago
pisces Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
pisces Submitter
over 1 year ago
pisces Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

Informational/Invalid

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.