QuantAMM

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

Incorrect 128-bit Storage Position in QuantAMM's Odd-Length Array Packing Leads to Value Scaling Errors in Pool Calculations

Summary

A data corruption vulnerability exists in the _quantAMMPack128Array function within the ScalarRuleQuantAMMStorage contract. The vulnerability centers on the incorrect bit positioning of stored data for odd-length arrays, which is called by multiple critical pool components.

In QuantAMMVarianceBasedRule, this vulnerable packing is used to store intermediate variance states:

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

intermediateVarianceStates[_poolParameters.pool][locals.storageIndex] = locals.intermediateVarianceState[locals.nMinusOne];

The corruption of these states causes incorrect calculation of Σ(t) = (1-λ)A(t), the critical variance metric that determines how the pool assesses and responds to price volatility. This could lead to the pool maintaining incorrect risk assessments and potentially failing to adjust to market conditions appropriately.

Similarly in QuantAMMGradientBasedRule, it affects gradient storage:

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

intermediateGradientStates[_poolParameters.pool][locals.storageArrayIndex] = locals.intermediateValue;

When these gradient states are corrupted, the final calculation λ³/(1-λ) * a(t) produces incorrect values. Since this gradient determines how pool weights are adjusted, corrupted values could cause the pool to adjust weights incorrectly, leading to mispricing of assets and creating arbitrage opportunities that could be exploited.

The root issue manifests in the handling of odd-length arrays in ScalarRuleQuantAMMStorage, where the final element is improperly stored in the lower 128 bits rather than the expected upper bits of the storage slot:

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

targetArray[storageIndex] = int256(int128(_sourceArray[sourceArrayLength - 1]));

This creates a fundamental mismatch between the packing and unpacking operations, as the unpacking function expects the last element of odd-length arrays to be positioned in the upper 128 bits through a left shift operation. When these misaligned values are unpacked, they are interpreted at 1/2^128 times their actual value due to the position mismatch. This corrupted data then feeds into the AMM's core calculations - the variance matrix Σ(t) that measures price volatility and the gradient calculations that determine weight adjustments. The severity is amplified because these corrupted values directly influence how the pool prices assets and manages risk, potentially leading to exploitable pricing errors.

Recommended mitigation steps

Modify the storage of the last element in odd-length arrays to use the upper 128 bits:

// For odd-length arrays, left-shift the last element to upper 128 bits
targetArray[storageIndex] = _sourceArray[sourceArrayLength - 1] << 128;
Updates

Lead Judging Commences

n0kto Lead Judge 10 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.