Gas limit DOS attack via unbounded operations
Multiple batch functions iterate over user-supplied arrays without size bounds, enabling out-of-gas reverts that can deny service and potentially lock assets.
Description
The project includes multiple functions that utilize loops without a defined or limited number of iterations, where the number of iterations depends on input from storage or external function calls. As Ethereum transactions have a gas limit, loops with an excessively high number of iterations could exhaust the transaction's available gas, leading to a transaction failure.
Functions such as balanceOfBatch, safeBatchTransferFrom, _batchMint, _burnBatch, batchBurn, and batchMint have unbounded loops that iterate based on the length of input arrays, which is a risky design pattern.
This issue is particularly concerning as it can inadvertently lead to a denial-of-service (DOS) condition where the functions become unresponsive or unusable if they consistently run out of gas, effectively stalling the contract's operation and potentially locking funds or assets.
These two loops are implemented in the above-mentioned functions:
for (uint256 i = 0; i < ids.length; ++i)for (uint256 i = 0; i < accounts.length; ++i)
Impact
- Denial of Service (DoS): A malicious actor or an unintentional scenario might lead to a transaction running out of gas, causing the function to fail and preventing further interactions with the contract.
- Funds Lock: If the contract consistently fails due to out-of-gas errors, users might be unable to withdraw or transfer their assets, leading to locked funds.
- Increased Gas Costs: Legitimate users might need to use higher gas fees to ensure their transactions do not fail, increasing the cost of interacting with the contract.
Recommendation
Limiting Iterations:
- Implement a limit on the number of iterations allowed in each function call. This limit should be well-documented and communicated to users.
- Implement paginated functions to handle operations that would otherwise require excessive iterations, allowing users to process transactions in manageable chunks.
Gas Checks:
- Perform checks to ensure sufficient gas is available before executing operations prone to high gas consumption, thereby preventing unintentional out-of-gas errors.
- Consider invalidating the nonces of failed transactions or implementing a more secure nonce generation and validation method.

