QuantAMM

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

Dual Weight System Initialization Mismatch Breaks QuantAMM's Automated Market Making

Summary

A critical architectural flaw exists in the QuantAMMWeightedPoolFactory's weight initialization system that could compromise the core functionality of deployed pools. The factory attempts to bridge standard Balancer V3 weighted pool mechanics with QuantAMM's specialized automated weight management, but creates a dangerous disconnect in how these systems interact.

The root of the vulnerability lies in the dual weight system design where the factory accepts both normalizedWeights (standard Balancer) and _initialWeights (QuantAMM) but silently ignores the standard weights during initialization. This creates a serious risk because QuantAMM pools, while built on Balancer's architecture, implement sophisticated automated weight adjustment mechanisms that need to properly interface with the base Balancer functionality. The current implementation could allow pools to be deployed with mismatched weight configurations between the two systems, potentially leading to catastrophic failures in the pool's automated market making capabilities when weight adjustments are triggered.

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-quantamm/contracts/QuantAMMWeightedPoolFactory.sol#L131

struct NewPoolParams {
// ... other fields
uint256[] normalizedWeights; // Standard Balancer weights (unused)
int256[] _initialWeights; // QuantAMM weights (used)
}
function create(NewPoolParams memory params) external returns (address pool, bytes memory poolArgs) {
pool = _create(poolArgs, params.salt);
QuantAMMWeightedPool(pool).initialize(
params._initialWeights, // Only QuantAMM weights used
params._poolSettings,
params._initialMovingAverages,
params._initialIntermediateValues,
params._oracleStalenessThreshold
);
}

Recommended Mitigation Steps

  1. Validate that both weight sets match

function validateWeightConsistency(
uint256[] memory standardWeights,
int256[] memory quantWeights
) internal pure {
require(
standardWeights.length == quantWeights.length,
"Weight arrays must match"
);
// Validate weights match within acceptable precision
for (uint i = 0; i < standardWeights.length; i++) {
require(
abs(int256(standardWeights[i]) - quantWeights[i]) <= WEIGHT_PRECISION_TOLERANCE,
"Weight mismatch"
);
}
}
  1. Update the initialization flow to acknowledge both weight systems:

function create(NewPoolParams memory params) external returns (address pool, bytes memory poolArgs) {
// Validate standard weights
validateBalancerWeights(params.normalizedWeights);
// Validate QuantAMM weights
validateQuantAMMWeights(params._initialWeights);
// Ensure consistency between both systems
validateWeightConsistency(
params.normalizedWeights,
params._initialWeights
);
// Create and initialize pool
pool = _create(poolArgs, params.salt);
QuantAMMWeightedPool(pool).initialize(
params._initialWeights,
params._poolSettings,
params._initialMovingAverages,
params._initialIntermediateValues,
params._oracleStalenessThreshold
);
}
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.