QuantAMM

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

`UpdateWeightRunner.setWeightsManually` bypasses initialization checks

Summary

The UpdateWeightRunner.setWeightsManually function lets owners set weights manually. The problem is the function does not check if the weights are correct as it happens during initialization. This can break the protocol functionality.

Vulnerability Details

The function implements only common checks:

function setWeightsManually(
int256[] calldata _weights,
address _poolAddress,
uint40 _lastInterpolationTimePossible,
uint _numberOfAssets
) external {
uint256 poolRegistryEntry = QuantAMMWeightedPool(_poolAddress).poolRegistry();
if (poolRegistryEntry & MASK_POOL_OWNER_UPDATES > 0) {
require(msg.sender == poolRuleSettings[_poolAddress].poolManager, "ONLYMANAGER");
} else if (poolRegistryEntry & MASK_POOL_QUANTAMM_ADMIN_UPDATES > 0) {
require(msg.sender == quantammAdmin, "ONLYADMIN");
} else {
revert("No permission to set weight values");
}
//though we try to keep manual overrides as open as possible for unknown unknows
//given how the math library works weights it is easiest to define weights as 18dp
//even though technically G3M works of the ratio between them so it is not strictly necessary
//CYFRIN L-02
for (uint i; i < _weights.length; i++) {
if (i < _numberOfAssets) {
>> require(_weights[i] > 0, "Negative weight not allowed");
>> require(_weights[i] < 1e18, "greater than 1 weight not allowed");
}
}

Important checks are bypassed:

function _setInitialWeights(int256[] memory _weights) internal {
require(_normalizedFirstFourWeights == 0, "init");
require(_normalizedSecondFourWeights == 0, "init");
InputHelpers.ensureInputLengthMatch(_totalTokens, _weights.length);
int256 normalizedSum;
int256[] memory _weightsAndBlockMultiplier = new int256[]();
for (uint i; i < _weights.length; ) {
>> if (_weights[i] < int256(uint256(absoluteWeightGuardRail))) {
revert MinWeight();
}
_weightsAndBlockMultiplier[i] = _weights[i];
normalizedSum += _weights[i];
//Initially register pool with no movement, first update will come and set block multiplier.
_weightsAndBlockMultiplier[i + _weights.length] = int256(0);
unchecked {
++i;
}
}
// Ensure that the normalized weights sum to ONE
>> if (uint256(normalizedSum) != FixedPoint.ONE) {
revert NormalizedWeightInvariant();
}

Impact

Unexpected behavior

Tools used

Manual Review

Recommendations

Consider using corresponding checks as during initialization

Updates

Lead Judging Commences

n0kto Lead Judge 7 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.