QuantAMM

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

No check enforces an 8-token limit, allowing 9+ tokens to break the pool’s core packing logic

Vulnerability Details

When a user calls the factory’s create or createWithoutArgs function:

The factory encodes parameters into QuantAMMWeightedPool.NewPoolParams, including:

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

NewPoolParams({
name: params.name,
symbol: params.symbol,
@> numTokens: params.normalizedWeights.length,
...
})

It then calls:

pool = _create(poolArgs, params.salt);

which deploys a new QuantAMMWeightedPool instance.

  • Inside QuantAMMWeightedPool’s constructor, _totalTokens is set to params.numTokens without verifying params.numTokens <= 8.

Thus, a user can deploy a pool with 9 or more tokens, even though the code is tightly written for a maximum of 8.

Problem is the pool stores weights in two packed int256 slots, each holding 4 weights and 4 multipliers (total capacity = 8 tokens).

The constructor sets _totalTokens = params.numTokens directly, never checking if it exceeds 8:

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

constructor(
NewPoolParams memory params,
IVault vault
) BalancerPoolToken(vault, params.name, params.symbol) PoolInfo(vault) Version(params.version) {
@> _totalTokens = params.numTokens;
updateWeightRunner = UpdateWeightRunner(params.updateWeightRunner);
...

If the caller sets normalizedWeights.length to 9+, the internal code tries to read or write a “9th token” beyond these two packed slots, triggering array-out-of-bounds errors or corrupted math.

Impact

Deploying a pool with more than 8 tokens can irreparably break the contract’s math, causing reverts or exploit scenarios.

Tools Used

Manual Review

Recommendations

Add a Require Check
In the factory or the pool constructor, require:

+ require(params.numTokens <= 8, "Cannot exceed 8 tokens");
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!