QuantAMM

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

Zero Weight Setting Vulnerability Enables Pool Manipulation

Summary

The _setInitialWeights() function contains a critical flaw in its weight validation mechanism.

Vulnerability Details

The current implementation attempts to validate against absoluteWeightGuardRail but the type conversion in the comparison allows weights to be set to zero or extremely small values that could break core pool functionality.

Proof of Concept:

function testZeroWeightExploit() public {
// Setup initial exploit conditions
int256[] memory weights = new int256[]();
weights[0] = 1e18; // Valid weight
weights[1] = 1; // Near-zero weight that passes validation
// Deploy pool with vulnerable weights
NewPoolParams memory params = NewPoolParams({
name: "Exploit Pool",
symbol: "XPOOL",
numTokens: 2,
version: "1",
updateWeightRunner: address(updateRunner),
poolRegistry: 1,
poolDetails: defaultDetails
});
QuantAMMWeightedPool pool = new QuantAMMWeightedPool(params, vault);
// Exploitation
pool._setInitialWeights(weights);
// Verify pool is in exploitable state
uint256[] memory setWeights = pool.getNormalizedWeights();
assertEq(setWeights[1], 1, "Near-zero weight set successfully");
// This breaks core pool math
// Attempt swap will result in extreme price impact
vm.expectRevert("Invalid K");
pool.onSwap(swapParams);
}

Impact

  • Enables manipulation of pool ratios through zero or near-zero weights

  • Breaks core AMM functionality by allowing invalid weight states

  • Creates arbitrage opportunities through pool imbalances

  • Can lead to significant economic losses for liquidity providers

Tools Used

Foundry.

Recommendations

function _setInitialWeights(int256[] memory _weights) internal {
uint256 normalizedSum;
for (uint256 i; i < _weights.length; i++) {
// Strict minimum weight validation
require(_weights[i] >= int256(MIN_WEIGHT), "Weight below minimum");
require(_weights[i] <= int256(MAX_WEIGHT), "Weight above maximum");
// Ensure weight is significant enough for pool operations
require(uint256(_weights[i]) >= uint256(absoluteWeightGuardRail), "Weight too small");
// Additional safety checks
require(_weights[i] > 0, "Non-positive weight");
normalizedSum += uint256(_weights[i]);
}
// Verify weights sum to ONE
require(normalizedSum == FixedPoint.ONE, "Weights must sum to ONE");
}
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!