QuantAMM

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

Non-Symmetric Covariance Matrix Generation in QuantAMM Risk Calculations Breaks Core Mathematical Properties

Description

The _calculateQuantAMMCovariance function in QuantAMMCovarianceBasedRule.sol fails to enforce matrix symmetry in its covariance calculations. The function computes each element independently without ensuring that C[i][j] = C[j][i], which violates a fundamental property of covariance matrices.

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

for (uint i; i < locals.n; ) {
newState[i] = new int256[]();
for (uint j; j < locals.n; ) {
locals.intermediateState =
locals.convertedLambda.mul(intermediateCovarianceState[i][j]) +
locals.u[i].mul(locals.v[j]).div(TENPOWEIGHTEEN);
newState[i][j] = locals.intermediateState.mul(locals.oneMinusLambda);
intermediateCovarianceState[i][j] = locals.intermediateState;
unchecked {
++j;
}
}
unchecked {
++i;
}
}

This implementation allows for the accumulation of numerical errors that can break the symmetry property, leading to mathematically invalid covariance matrices.

Impact

This symmetry violation in the covariance matrix calculation represents a critical flaw in the protocol's mathematical foundation. The issue manifests at the most fundamental level of the risk management system, where covariance matrices must maintain specific mathematical properties to produce valid results.

In the realm of linear algebra and portfolio mathematics, a covariance matrix must be symmetric positive semi-definite for its eigenvalues and eigenvectors to correctly characterize the system's risk properties. The current implementation, by failing to enforce symmetry, allows the accumulation of numerical errors that can result in complex eigenvalues in what should be a strictly real-valued system. This mathematical deterioration extends beyond mere numerical imprecision - it fundamentally breaks the guarantee of positive semi-definiteness, potentially introducing negative variances that are mathematically impossible in a valid covariance matrix.

The implications cascade through any operations involving matrix decomposition or principal component analysis. These operations, crucial for sophisticated portfolio optimization strategies, rely explicitly on the symmetry property. When this property is violated, the resulting calculations can produce mathematically inconsistent results, leading to invalid risk assessments and potentially destabilizing portfolio optimizations.

The economic implications are particularly severe because the protocol's weight adjustment mechanisms rely on these mathematical properties being preserved. Without guaranteed symmetry, the risk metrics derived from the covariance matrix become fundamentally unreliable. The system could begin making weight adjustments that appear valid numerically but are mathematically impossible or inconsistent with proper portfolio theory. This error compounds over time as each update builds upon previous asymmetric results, with no mathematical mechanism for self-correction.

Most concerning is that the protocol's existing safeguards are inadequate for detecting or preventing this issue. The guard rails and update intervals, while effective for managing magnitude changes, operate at a higher level and cannot detect violations of these fundamental matrix properties. The result is a system that may appear to function normally while harboring deep mathematical inconsistencies that could manifest in unexpected and potentially harmful ways during market stress events or complex trading scenarios.

Recommended Mitigation Steps

Modify the covariance calculation to enforce symmetry:

for (uint i; i < locals.n; ) {
newState[i] = new int256[]();
for (uint j = i; j < locals.n; ) { // Only compute upper triangular
locals.intermediateState =
locals.convertedLambda.mul(intermediateCovarianceState[i][j]) +
locals.u[i].mul(locals.v[j]).div(TENPOWEIGHTEEN);
newState[i][j] = locals.intermediateState;
if (i != j) {
newState[j][i] = locals.intermediateState; // Enforce symmetry
}
intermediateCovarianceState[i][j] = locals.intermediateState;
intermediateCovarianceState[j][i] = locals.intermediateState;
unchecked {
++j;
}
}
unchecked {
++i;
}
}
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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