QuantAMM

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

Lack of Minimum Weight Validation in setWeights() Enables Pool Manipulation via Extreme Weight Settings

Summary

The setWeights function in the QuantAMMWeightedPool contract lacks validation to ensure individual weights meet the minimum absoluteWeightGuardRail threshold. This parameter is critical for pool safety as demonstrated by its validation during pool initialization in the _setInitialWeights function.

While the contract validates weights against absoluteWeightGuardRail during initialization, this check is omitted in the setWeights function:

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-quantamm/contracts/QuantAMMWeightedPool.sol#L617

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 against absoluteWeightGuardRail
...
}

The absence of minimum weight validation creates a fundamental security vulnerability in the pool's weight mechanism. When weights can be set below the absoluteWeightGuardRail, it breaks the core assumption that all weights maintain a safe minimum threshold. This enables exploitation through weight manipulation - an attacker could force weights to extremely low values, causing severe numerical precision loss in the pool's core calculations.

These precision issues cascade through the entire pricing model since weights are used in critical mathematical operations for determining exchange rates and pool share values. Furthermore, the ability to set arbitrarily low weights violates protocol invariants that rely on the minimum weight threshold for safety, potentially breaking cross-contract interactions and automated position management systems that depend on these weight constraints. This is especially dangerous in a weighted pool where price calculations and pool dynamics are directly derived from weight ratios, making the entire pool vulnerable to manipulation through extreme weight settings.

For example, if a weight is set to 0.001% when the minimum should be 1%, an attacker could exploit the resulting precision loss and price calculation errors to extract value through carefully crafted trades taking advantage of the broken weight ratios.
This is particularly concerning as setWeights can be called multiple times throughout the pool's lifecycle, potentially introducing unsafe states that were explicitly prevented during initialization.

Recommended Mitigation Steps

Add explicit validation of weights against the absoluteWeightGuardRail in the setWeights function:

function setWeights(
int256[] calldata _weights,
address _poolAddress,
uint40 _lastInterpolationTimePossible
) external override {
require(msg.sender == address(updateWeightRunner), "ONLYUPDW");
require(_weights.length == _totalTokens * 2, "WLDL");
// Validate each weight against minimum threshold
uint256 halfLength = _weights.length / 2;
for (uint256 i = 0; i < halfLength; i++) {
if (_weights[i] < int256(uint256(absoluteWeightGuardRail))) {
revert MinWeight();
}
}
// Rest of the function...
}
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

invalid_weights_can_be_negative_or_extreme_values

_clampWeights will check that these weights are positive and in the boundaries before writing them in storage.

Support

FAQs

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