QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: low
Invalid

Discrepancy in lambda value validation between poolSettings and ruleSettings

Summary

Due differing validation used for lambdas it's likely that the pool can't be set to the full available range.

Vulnerability Details

The pool setting lambda is validated as:

for (uint i; i < _poolSettings.lambda.length; ++i) {
int256 currentLambda = int256(uint256(_poolSettings.lambda[i]));
require(currentLambda > PRBMathSD59x18.fromInt(0) && currentLambda < PRBMathSD59x18.fromInt(1), "INVLAM"); //Invalid lambda value
}

Which ends up limit λ as 0 < λ < 1e18. Notice that it cannot equal either of the end values 0 or 1e18.

While DifferenceMomentumUpdateRule, which uses has a "shortLambda" parameter in it has the validation of:

int256[] memory shortLambda = _parameters[1];
for (uint i; i < shortLambda.length; ) {
// @audit unnecessary check as below shortLambda[i] > int256(1e18) is more restrictive
if (shortLambda[i] > int256(type(int128).max)) {
return false;
}
// @audit checks only for negative (allows 0 value)
if (shortLambda[i] < int256(0)) {
return false;
}
// @audit fails if above 1e18 (allows exact 1e18 value)
if (shortLambda[i] > int256(1e18)) {
return false;
}
unchecked {
++i;
}
}

Where shortLambda in the end has to be 0 <= λ <= 1e18. And CAN equal 0 and 1e18.

Both shortLambda and the pool setting lambda are used in the same function _calculateQuantAMMMovingAverage and is likely that the pool validation is too restrictive.

Inside _calculateQuantAMMMovingAverage λ is used as int256 oneMinusLambda = ONE - convertedLambda;

and then in

movingAverageI + oneMinusLambda.mul(_newData[i] - movingAverageI);

Meaning that if λ = 0; the new difference has the biggest possible impact. While if λ = 1e18 the new difference is completely ignored and is equal to 0.

Impact

The pool is unnecessrily strict in its λ validation and prevents full available range (excludes values 0 and 1e18).

Tools Used

Manual review.

Recommendations

Since both variables are selected by the user and same function is used unless reason exists allow full range matching DifferenceMomentumUpdateRule unless, the range is actually specified in the whitepaper and was missed.

// @audit replace > and < with >= and <=
require(currentLambda >= PRBMathSD59x18.fromInt(0) && currentLambda <= PRBMathSD59x18.fromInt(1), "INVLAM");

Otherwise if there is a specific λ range for moving average adjust both places to match that range.

Updates

Lead Judging Commences

n0kto Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!