QuantAMM

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

After weights get initialized updateweightRunner can bypass minWeight (absoluteWeightGuardRail) when there is an update

Summary

This report highlights a critical vulnerability in the setWeights function of the QuantAMM contract. The function lacks a check to ensure that updated weights are not below the absoluteWeightGuardRail. This oversight allows administrators to set invalid weights during updates, potentially destabilizing the pool and opening the protocol to economic exploits.

Vulnerability Details

In the _setInitialWeights function, a check ensures that no weight in _weights is less than the absoluteWeightGuardRail:

if (_weights[i] < int256(uint256(absoluteWeightGuardRail))) {
revert MinWeight();
}

This guarantees that all initial weights meet the minimum threshold. In the setWeights function, there is no similar validation. Consequently, during updates, weights can be set below the absoluteWeightGuardRail, bypassing the safeguard enforced during initialization.

function _setInitialWeights(int256[] memory _weights) internal {
require(_normalizedFirstFourWeights == 0, "init");
require(_normalizedSecondFourWeights == 0, "init");
InputHelpers.ensureInputLengthMatch(_totalTokens, _weights.length);
for (uint i; i < _weights.length; ) {
@> if (_weights[i] < int256(uint256(absoluteWeightGuardRail))) {
revert MinWeight();
}
// Other logic omitted for brevity
}
}
function setWeights(
int256[] calldata _weights,
address _poolAddress,
uint40 _lastInterpolationTimePossible
) external override {
require(msg.sender == address(updateWeightRunner), "ONLYUPDW");
require(_weights.length == _totalTokens * 2, "WLDL");
// No validation for weights being above absoluteWeightGuardRail
// Other logic omitted for brevity
}

In the setWeight function, there is no similar validation. Consequently, during updates, weights can be set below the absoluteWeightGuardRail, bypassing the safeguard enforced during initialization.

The updateRunner calls the setWeights function to update the pool's weights, The _weights array contains values below the absoluteWeightGuardRail.

The function proceeds without reverting, allowing invalid weights to be set.

Impact

Invalid weights disrupt the intended balance and operation of the pool.

Tools Used

Manual review

Recommendations

Include a loop to validate that all weights meet the absoluteWeightGuardRail threshold before proceeding. For example:

function setWeights(
int256[] calldata _weights,
address _poolAddress,
uint40 _lastInterpolationTimePossible
) external override {
require(msg.sender == address(updateWeightRunner), "ONLYUPDW");
require(_weights.length == _totalTokens * 2, "WLDL"); //weight length different
+ for (uint i = 0; i < _weights.length / 2; i++) {
+ if (_weights[i] < int256(uint256(absoluteWeightGuardRail))) {
+ revert MinWeight();
+ }
+}
if (_weights.length > 8) {
int256[][] memory splitWeights = _splitWeightAndMultipliers(_weights);
_normalizedFirstFourWeights = quantAMMPack32Array(splitWeights[0])[0];
_normalizedSecondFourWeights = quantAMMPack32Array(splitWeights[1])[0];
} else {
_normalizedFirstFourWeights = quantAMMPack32Array(_weights)[0];
}
//struct allows one SSTORE
poolSettings.quantAMMBaseInterpolationDetails = QuantAMMBaseInterpolationVariables({
lastPossibleInterpolationTime: _lastInterpolationTimePossible,
lastUpdateIntervalTime: uint40(block.timestamp)
});
emit WeightsUpdated(_poolAddress, _weights);
}
Updates

Lead Judging Commences

n0kto Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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