QuantAMM

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

The `QuantAMMMathGuard::__clampWeights` function does not check whether `(absoluteMin < absoluteMax)` after calculating and assigning these values.

Summary

The QuantAMMMathGuard::__clampWeights function does not include a check to verify whether (absoluteMin < absoluteMax) after calculating these values from the weight.length and _absoluteWeightGuardRail.

Vulnerability Details

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-quantamm/contracts/rules/base/QuantammMathGuard.sol#L46

  1. The funciton missing a check for the value of absoluteMin is always less than absoluteMax.

absoluteMinand absoluteMaxare calcualted from weight.length and _absoluteWeightGuardRailas given below :-

function _clampWeights(
int256[] memory _weights,
int256 _absoluteWeightGuardRail
) internal pure returns (int256[] memory) {
unchecked {
uint weightLength = _weights.length;
if (weightLength == 1) {
return _weights;
}
@>> int256 absoluteMin = _absoluteWeightGuardRail;
@>> int256 absoluteMax = ONE -
@>> (PRBMathSD59x18.fromInt(int256(_weights.length - 1)).mul(_absoluteWeightGuardRail));
int256 sumRemainerWeight = ONE;
int256 sumOtherWeights;
for (uint i; i < weightLength; ++i) {
if (_weights[i] < absoluteMin) {
_weights[i] = absoluteMin;
sumRemainerWeight -= absoluteMin;
} else if (_weights[i] > absoluteMax) {
_weights[i] = absoluteMax;
sumOtherWeights += absoluteMax;
}
}
if (sumOtherWeights != 0) {
int256 proportionalRemainder = sumRemainerWeight.div(sumOtherWeights);
for (uint i; i < weightLength; ++i) {
if (_weights[i] != absoluteMin) {
_weights[i] = _weights[i].mul(proportionalRemainder);
}
}
}
}
return _weights;
}

2 Also in the natspec about _absoluteWeightGuardRailsays that these are maximim allowed weight above _guardQuantAMMWeightsfunction. But in _clampWeightsfunction it is assigned to absoluteMin.

Either the NatSpec documentation or the implementation is incorrect.

/// @notice Guards QuantAMM weights updates
/// @param _weights Raw weights to be guarded and normalized
/// @param _prevWeights Previous weights to be used for normalization
/// @param _epsilonMax Maximum allowed change in weights per update step (epsilon) in the QuantAMM whitepaper
@>> /// @param _absoluteWeightGuardRail Maximum allowed weight in the QuantAMM whitepaper
function _guardQuantAMMWeights(
int256[] memory _weights,
int256[] calldata _prevWeights,
int256 _epsilonMax,
int256 _absoluteWeightGuardRail
) internal pure returns (int256[] memory guardedNewWeights) {
// first see if the weights go beyond the maximum/minimum weights
_weights = _clampWeights(_weights, _absoluteWeightGuardRail);
//then reduce even further if the weight change is beyond the allowed "speed limit" that protects the changes from front running
guardedNewWeights = _normalizeWeightUpdates(_prevWeights, _weights, _epsilonMax);
}

Impact

  1. The value of absoluteMin can be greater than absoluteMax, leading to incorrect calculations downstream.

  2. Incorrect NatSpec documentation or improper assignment of _absoluteWeightGuardRail can also cause further calculation errors.

Tools Used

Manual Review

Recommendations

1 Add a check for value of absoluteMin is always less than absoluteMax

+ require(absoluteMin < absoluteMax, "Wrong value of absoluteMin and absoluteMax")

2 Correct the natspce or implementation of _absoluteWeightGuardRail.as needed

Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational or Gas / Admin is trusted / Pool creation is trusted / User mistake / Suppositions

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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

Give us feedback!