Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

[M-11] Unbounded Loop in configureCollateralLiquidationPriority Allows Potential DoS

Summary

The configureCollateralLiquidationPriority function processes an unbounded array (collateralTypes) in a loop without enforcing a maximum length. If any untrusted party can supply a large array, it can cause excessive gas consumption and revert the transaction, resulting in a denial-of-service (DoS).

Vulnerability Details

This issue arises because the function unconditionally loops through all elements of collateralTypes. If there is no upstream check (e.g., an admin-only constraint or max array length), an attacker could submit an extremely large array. In doing so, the transaction might exceed the block gas limit, causing a revert and prevent legitimate calls from succeeding.

Although this function is marked internal, the risk remains if any publicly accessible or partially trusted function calls it without restricting who can supply the array or how large it can be.

function configureCollateralLiquidationPriority(Data storage self, address[] memory collateralTypes) internal {
uint256 cachedCollateralTypesCached = collateralTypes.length;
for (uint256 i; i < cachedCollateralTypesCached; i++) {
if (collateralTypes[i] == address(0)) {
revert Errors.ZeroInput("collateralType");
}
if (!self.collateralLiquidationPriority.add(collateralTypes[i])) {
revert Errors.MarginCollateralAlreadyInPriority(collateralTypes[i]);
}
}
}

Impact

If only a privileged admin can call this function, the risk is significantly lower because the admin is unlikely to sabotage their own system.

  • If untrusted or partially trusted actors can influence the size of collateralTypes, repeated DoS attempts can block crucial contract functionality—such as changing collateral priorities used in liquidation logic.

If an attacker has any path (directly or indirectly) to pass massive arrays, the DoS scenario is feasible. If it is strictly admin-only, then the likelihood is low. Otherwise, it can be moderately high for real-world exploitation.

Tools Used

function testConfigureCollateralPriorityDoS() public {
// an untrusted caller can indirectly trigger configureCollateralLiquidationPriority
address[] memory largeArray = new address[](100000); // extremely large
for (uint256 i = 0; i < largeArray.length; i++) {
largeArray[i] = address(0xDEADBEEF); // valid non-zero addresses
}
// This call likely reverts if it exceeds block gas limit
configureCollateralLiquidationPriority(perpsEngine, largeArray);
}

Recommendations

Enforce Access Control: Ensure only a trusted role (e.g., owner or governance) can invoke the higher-level function that calls configureCollateralLiquidationPriority. This prevents untrusted users from supplying an oversized array.

  • Set a Maximum Array Length: If partially trusted parties can invoke it, add a check:

    require(collateralTypes.length <= MAX_LENGTH, "Array too large");

    This ensures the loop stays within safe gas limits and avoids revert scenarios due to block gas constraints.

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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