QuantAMM

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

Token count validation missing in QuantAMM pool factory

Summary

The QuantAMMWeightedPoolFactory contract initializes pools with possible mismatched token counts and weights, leading to operational issues. The contract uses the length of normalizedWeights array to determine the number of tokens the pool will manage, instead of validating against the actual number of tokens provided. And both normalizedWeightsand tokens are not validated to be equal.

Vulnerability Details

Here's the NewPoolParams struct that declares both tokens and normalizedWeights:

struct NewPoolParams {
TokenConfig[] tokens; // Array of tokens for pool management
uint256[] normalizedWeights; // Array of corresponding weights
// ... other fields
}

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

However, in pool creation, normalizedWeights is wrongly passed as the number of tokens:

// In pool creation functions:
pool = _create(abi.encode(
QuantAMMWeightedPool.NewPoolParams({
name: params.name,
symbol: params.symbol,
numTokens: params.normalizedWeights.length, // Critical: Uses weight array length instead of token array length
version: "version",
updateWeightRunner: _updateWeightRunner,
poolRegistry: params.poolRegistry,
poolDetails: params.poolDetails
}),
getVault()
), params.salt);

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

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

There could be a scenario where there are more weights than token or more tokens than weights:

Scenario 1 - More Weights Than Tokens:
tokens = [WETH, USDC] // 2 tokens
weights = [0.3, 0.3, 0.4] // 3 weights
Result: Pool expects 3 tokens but only has 2
Scenario 2 - More Tokens Than Weights:
tokens = [WETH, USDC, DAI] // 3 tokens
weights = [0.5, 0.5] // 2 weights
Result: Pool missing weight for third token

This is because normalizedWeightsand token arrays length are not checked to be equal.

Impact

Token array length can differ from weight array length causing use of incorrect token count.

Tools Used

Manual review

Recommendations

Validate tokens and pass tokens to the numTokens parameter:function validateTokenConfiguration(
TokenConfig[] memory tokens,
uint256[] memory weights
) internal pure {
require(tokens.length == weights.length, "Token and weight counts must match");
require(tokens.length >= MIN_TOKENS, "Insufficient tokens");
require(tokens.length <= MAX_TOKENS, "Too many tokens");
// Validate token addresses are unique
for (uint256 i = 0; i < tokens.length - 1; i++) {
for (uint256 j = i + 1; j < tokens.length; j++) {
require(tokens[i].token ! = tokens[j].token, "Duplicate tokens");
}
}
}
function create(NewPoolParams memory params) external returns (address pool, bytes memory poolArgs) {
validateTokenConfiguration(params.tokens, params.normalizedWeights);
pool = _create(abi.encode(
QuantAMMWeightedPool.NewPoolParams({
numTokens: params.tokens.length, // Use validated token length
// ... other parameters
}),
getVault()
), params.salt);
}
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.

Give us feedback!