QuantAMM

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

Unhandled leftInt Value in Odd-Matrix Packing Causes Missing Covariance Elements

Summary

The QuantAMM system's matrix packing mechanism has a significant vulnerability in the _quantAMMPack128Matrix function where matrix elements are lost during packing operations for odd-sized matrices. This issue directly affects the covariance calculations that are critical for the AMM's operation.

Here's the problematic code in VectorRuleQuantAMMStorage:

https://github.com/Cyfrin/2024-12-quantamm/blob/main/pkg/pool-quantamm/contracts/QuantAMMStorage.sol#L373

if (((_sourceMatrix.length * _sourceMatrix.length) % 2) != 0) {
_targetArray[targetArrayLength - 1] = int256(
int128(_sourceMatrix[_sourceMatrix.length - 1][_sourceMatrix.length - 1])
);
}

The issue occurs because when packing an odd-sized matrix (for example, a 3x3 matrix with 9 elements), the function maintains a leftInt value that is meant to be paired with the next element. However, when processing the final element, it ignores any stored leftInt and simply writes the last value alone. This manifests in the covariance calculations:

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

// Example with 3x3 matrix (9 elements)
// Elements: [1,2,3,4,5,6,7,8,9]
// Current state before last element:
// leftInt = 8, right = 1
// Processing element 9
// Current behavior: Stores just 9, losing 8
// Expected: Should store [8,9]
// This corrupted data then flows into:
function _calculateQuantAMMCovariance(
int256[] memory _newData,
QuantAMMPoolParameters memory _poolParameters
) internal returns (int256[][] memory) {
// Will use incomplete matrix data for calculations
int256[][] memory intermediateCovarianceState = _quantAMMUnpack128Matrix(
intermediateCovarianceStates[_poolParameters.pool],
locals.n
);
// ... calculations proceed with missing data
}

Impact

The loss of matrix elements during packing operations has direct consequences for the QuantAMM's price calculations. When processing odd-sized covariance matrices, the function drops one element (the stored leftInt) when handling the final value. In a 3x3 matrix for example, element 8 would be lost when processing element 9. This missing data creates a systemic error in the covariance calculations used by _calculateQuantAMMCovariance(), leading to skewed price calculations and incorrect pool weight adjustments. While the pattern of data loss is consistent and predictable, its effect on pricing compounds over time as the corrupted covariance matrix continues to influence trading decisions. The silent nature of this error and its direct impact on pricing calculations makes this a significant risk to the AMM's core operation.

Recommended Mitigation Steps

Modify the final element handling to consider unpacked values:

function *quantAMMPack128Matrix(int256[][] memory *sourceMatrix, int256[] storage _targetArray) internal {
// ... existing code ...
if (((_sourceMatrix.length * _sourceMatrix.length) % 2) != 0) {
int256 lastValue = *sourceMatrix[*sourceMatrix.length - 1][_sourceMatrix.length - 1];
if (right == 1) {
// We have an unpacked leftInt, pack it with the last value
_targetArray[targetArrayLength - 1] = (leftInt << 128) |
int256(uint256(lastValue << 128) >> 128);
} else {
// No unpacked value, store just the last value
_targetArray[targetArrayLength - 1] = int256(int128(lastValue));
}
}
}
Updates

Lead Judging Commences

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

Support

FAQs

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