QuantAMM

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

Imprecise Matrix Size Validation in _quantAMMUnpack128Matrix() Allows Oversized Arrays to Pass Validation Leading to AMM Price Manipulation

Summary

In the VectorRuleQuantAMMStorage contract, the _quantAMMUnpack128Matrix function is used for unpacking matrix data used in covariance calculations:

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

function _quantAMMUnpack128Matrix(
int256[] memory _sourceArray,
uint _numberOfAssets
) internal pure returns (int256[][] memory targetArray) {
require(_sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets, "Source cannot provide target");
targetArray = new int256[][]();
for (uint i; i < _numberOfAssets; ) {
targetArray[i] = new int256[]();
unchecked {
++i;
}
}
//... matrix unpacking logic
}

This function is called by QuantAMMCovarianceBasedRule during covariance matrix updates:

int256[][] memory intermediateCovarianceState = _quantAMMUnpack128Matrix(
intermediateCovarianceStates[_poolParameters.pool],
locals.n
);

The validation is flawed because it only checks if _sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets. This means an attacker could provide an oversized array that passes validation but contains excess data that would be incorrectly unpacked into the covariance matrix. For example, if a 2x2 matrix requires a source array of length 2, an attacker could pass an array of length 3 that would pass validation but cause incorrect unpacking.

Given that these matrices directly determine price calculations through the covariance update formula:

locals.intermediateState =
locals.convertedLambda.mul(intermediateCovarianceState[i][j]) +
locals.u[i].mul(locals.v[j]).div(TENPOWEIGHTEEN);

An attacker could manipulate the AMM's pricing by providing malformed matrix data that passes the loose validation.

The implementation assumes that having sufficient data length is adequate protection, not considering that excess data could corrupt the matrix operations used for price calculations.

Scenario

An attacker wants to manipulate the AMM's price calculations. They observe that a 2x2 covariance matrix is being used for a specific trading pair. The matrix should have a source array of length 2, but they provide an array of length 3. The extra element contains carefully crafted data.

When calling the pool's update function, their array passes validation since 32 >= 22 (the current check). The unpacking function processes this oversized array, incorrectly incorporating the extra data into the covariance matrix. This corrupted matrix is then used in the next price calculation, causing the AMM to calculate incorrect prices for the trading pair.

Recommended mitigation steps

Implement exact size validation using ceiling division for odd-sized matrices:

function _quantAMMUnpack128Matrix(
int256[] memory _sourceArray,
uint _numberOfAssets
) internal pure returns (int256[][] memory targetArray) {
uint256 expectedLength = (_numberOfAssets * _numberOfAssets + 1) / 2; // Ceiling division for odd cases
require(_sourceArray.length == expectedLength, "Invalid source array length");
// ... rest of the function
}
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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