QuantAMM

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

Insufficient checks on the source array

Summary

In the QuantAMMStorage contract the checks carried out on the source array length are insufficient as it can result in the last element being stored as [0] in the target matrix for the cases where the input square matrix has odd number of elements and the source array length specified is more than that necessary.

Vulnerability Details

Refer to the function quantAMMUnpack128Matrix in the QuantAMMStorage contract. This function is used to unpack packed array of n 256 bit integers (int256[] memory _sourceArray) into 2n (or (2n – 1) if n is odd) 128 bit integers (int256[][] memory targetArray).

In the function, the only check done on the length of the source array is

require(_sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets, "Source cannot provide target");

This check is not sufficient to take care of all conditions. The presence of this check itself implies that the _sourceArray.length can be different from the one actually required.

Take, for instance, any target square matrix with odd number of Assets (i.e. n x n matrix where ‘n’ is an odd number). The matrix with odd number of Assets will have exactly (n x n) elements and these should normally be in the first (((n * n) + 1) /2) consecutive locations of the source array, with the last element being stored as least significant 128 bits in the source array. In case, the source array length is less than that required to store all the elements of the array, the function reverts.

However, in the cases where the source array length is more than that required to store all the elements of the array, the function does not revert. In such cases, the last element of the matrix will be computed from the last element of the source array. Assuming the packing was proper, this element will be erroneous.

if ((_numberOfAssets * _numberOfAssets) % 2 != 0) {
targetArray[_numberOfAssets - 1][_numberOfAssets - 1] = int256(
int128(_sourceArray[_sourceArray.length - 1])
);
}

Tools Used

Manual review

Recommended Mitigation

The best way to mitigate the issue is to ensure that the source array length specified is neither smaller nor bigger than required. This can be done by adding one more require statement in the codebase on the length of the source array.

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-quantamm/contracts/QuantAMMStorage.sol#L436-L437

require(_sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets, "Source cannot provide target");
targetArray = new int256[][]();

can be modified to

require(_sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets, "Source cannot provide target");
require((_sourceArray.length - 1) * 2 < _numberOfAssets * _numberOfAssets, "Source exceeds target");
targetArray = new int256[][]();

The additional require statement is as much necessary as the existing require statement in the codebase. If any abnormal source array length is passed to the function, the function must revert.

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.