QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: high
Valid

Error in Unpack Operation Causes Failure When `requiresPrevAverage` is True

Title

Error in Unpack Operation Causes Failure When requiresPrevAverage is True

Summary

The CalculateNewWeights function exposed an error when handling pools where requiresPrevAverage is true. This issue arises due to incorrect handling of moving averages during unpacking by the _quantAMMUnpack128Array function. Specifically, when previous averages are required, the unpacking logic fails, leading to index out-of-bound errors. This causes the performUpdate function to fail after the first execution, resulting in a denial of service (DoS) for affected pools.

Vulnerability Details

Here's the implementation of CalculateNewWeights function of UpdateRule contract:

function CalculateNewWeights(
int256[] calldata _prevWeights,
int256[] calldata _data,
address _pool,
int256[][] calldata _parameters,
uint64[] calldata _lambdaStore,
uint64 _epsilonMax,
uint64 _absoluteWeightGuardRail
) external returns (int256[] memory updatedWeights) {
...
locals.requiresPrevAverage = _requiresPrevMovingAverage() == REQ_PREV_MAVG_VAL;
locals.intermediateMovingAverageStateLength = locals.numberOfAssets;
if (locals.requiresPrevAverage) {
unchecked {
locals.intermediateMovingAverageStateLength *= 2;
}
}
locals.currMovingAverage = new int256[](locals.numberOfAssets);
locals.updatedMovingAverage = new int256[](locals.numberOfAssets);
locals.calculationMovingAverage = new int256[](locals.intermediateMovingAverageStateLength);
>> locals.currMovingAverage = _quantAMMUnpack128Array(movingAverages[_pool], locals.numberOfAssets);
...
}

Root Issue

In weighted pools using the minimum variance rule, the contract stores both the current and previous moving averages. These values are packed into a 128 array and stored in movingAverages[pool]. When the performUpdate function is called, it fetches the packed data and invokes the CalculateNewWeights function to determine new weights for the pool.

When requiresPrevAverage is true, the previous average is included in the packed data, effectively doubling its length (e.g., from 2 to 4 for a two-asset pool). However, the _quantAMMUnpack128Array function fails to correctly handle this scenario, resulting in an index out-of-bound error during unpacking. This prevents the performUpdate function from being successfully executed after the initial call, halting all subsequent updates for affected pools.

Impact

This vulnerability causes a Denial of Service (DoS) for all pools using the minimum variance rule with requiresPrevAverage = true. Notably, after the first call to performUpdate, subsequent updates fail due to unpacking errors, making the pools inoperable.

This disrupts pool rebalancing and weight adjustments, potentially leading to financial losses and system inefficiencies.

Tools Used

Manual Review

Recommendations

To address this issue, the _quantAMMUnpack128Array function should be updated to correctly handle cases where the packed data includes both current and previous averages.

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_CalculateNewWeights_DoS_when_requiresPrevAverage_is_true

Likelihood: Medium, all rules using previous average. Impact: High, DoS CalculateNewWeights

Support

FAQs

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