The use of delegatecall
in the batch
function creates a potential reentrancy vulnerability, allowing malicious contracts to exploit the state of the Batch
contract.
The batch
function uses delegatecall
to execute arbitrary functions specified in the calls
array. Since delegatecall
executes the called function in the context of the Batch
contract, any state changes made by the called function can affect the Batch
contract's state.
A malicious contract could be designed to call a function that modifies its own state, which, if executed within the batch
function, could lead to unexpected behavior or state corruption. For example, an attacker could manipulate state variables in the Batch
contract or perform actions that they shouldn't be allowed to.
This vulnerability breaks the security guarantees of:
Reentrancy Protection: By allowing an external contract to execute code within the context of the Batch
contract, it undermines the integrity of state management.
Controlled Execution Flow: The contract cannot guarantee that state is safe to modify when external calls are executed.
The risk arises from the combination of delegatecall
and user-supplied input. If an attacker crafts a malicious payload that modifies the contract's state, they can exploit this reentrancy vulnerability to perform unauthorized actions or extract funds.
A malicious contract could send a payload that triggers a function which calls back into the batch
function before the state has been finalized, allowing it to bypass checks or double-spend funds.
The impact of this vulnerability could be severe, potentially leading to loss of funds, unauthorized access to contract functions, or corruption of the contract’s state. Given the nature of delegatecall
, the attacker can manipulate the execution flow and potentially steal funds or disrupt normal contract operations.
Here’s a simple proof of concept demonstrating the reentrancy risk:
Create a malicious contract that invokes a function in the Batch
contract.
Within that function, call the batch
function again before the initial call completes.
To mitigate the reentrancy risk, implement a reentrancy guard pattern in the batch
function. This can be achieved using a simple boolean flag or using the OpenZeppelin ReentrancyGuard library.
Using the nonReentrant
modifier from OpenZeppelin will help prevent reentrant calls and protect the contract's state.
src/abstracts/Batch.sol
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.