QuantAMM

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

Integer Overflow in QuantAMMMathGuard Weight Calculations

Summary

The QuantAMMMathGuard contract is vulnerable to integer overflow/underflow in its weight calculations, allowing weights to reach extreme negative values (~-1e34) that completely break the system's mathematical foundations. This vulnerability could be exploited to manipulate pool prices and potentially drain assets.

Vulnerability Details

Location: pkg/pool-quantamm/contracts/rules/base/QuantAMMMathGuard.sol

The issue occurs when processing extreme input values during weight calculations. The contract fails to properly validate and bound input weights, leading to arithmetic overflow in the normalization process.

Proof of Concept

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.26;
import "forge-std/Test.sol";
import "@prb/math/contracts/PRBMathSD59x18.sol";
import { MockCalculationRule } from "../../../contracts/mock/MockCalculationRule.sol";
import { MockPool } from "../../../contracts/mock/MockPool.sol";
import { MockQuantAMMMathGuard } from "../../../contracts/mock/MockQuantAMMMathGuard.sol";
contract QuantAMMMathGuardWeightNormalizationTest is Test {
using PRBMathSD59x18 for int256;
MockQuantAMMMathGuard mockQuantAMMMathGuard;
function setUp() public {
mockQuantAMMMathGuard = new MockQuantAMMMathGuard();
}
function testFuzz_WeightNormalizationGuardRailViolation(
uint8 numAssets,
int256[] calldata weights,
int256 epsilonMax
) public {
vm.assume(numAssets >= 2 && numAssets <= 8);
vm.assume(weights.length == numAssets);
epsilonMax = bound(epsilonMax, 0.01e18, 0.5e18);
// Create initial weights with extreme concentration
int256[] memory prevWeights = new int256[]();
prevWeights[0] = 0.98e18; // 98% in first asset
int256 remainingWeight = 0.02e18;
// Convert numAssets to int256 for division
int256 numAssetsInt = int256(uint256(numAssets));
int256 divisor = numAssetsInt - 1;
for(uint i = 1; i < numAssets - 1; i++) {
prevWeights[i] = remainingWeight.div(divisor);
}
// Calculate final weight to ensure exact sum of 1e18
int256 distributedWeight = prevWeights[0];
for(uint i = 1; i < numAssets - 1; i++) {
distributedWeight += prevWeights[i];
}
prevWeights[numAssets - 1] = 1e18 - distributedWeight;
// Create target weights that force normalization issues
int256[] memory newWeights = new int256[]();
for(uint i = 0; i < numAssets; i++) {
newWeights[i] = bound(weights[i], 0.3e18, 0.98e18); // Force large changes
}
int256[] memory result = mockQuantAMMMathGuard.mockGuardQuantAMMWeights(
newWeights,
prevWeights,
epsilonMax,
0.01e18 // absoluteWeightGuardRail
);
// Verify invariants
int256 sum = 0;
for(uint i = 0; i < numAssets; i++) {
sum += result[i];
assertGe(result[i], 0.01e18, "Weight below minimum");
int256 change = (result[i] - prevWeights[i]).abs();
assertLe(change, epsilonMax, "Change exceeded epsilonMax");
}
assertEq(sum, 1e18, "Weights don't sum to 1");
}
}

Exploit Conditions:

  • Input weights: [6.837e50, 1.167e33]

  • Previous weights: [0.98e18, 0.01e18, 0.01e18]

  • epsilonMax: 0.01e18 (1%)

Result:

// Test failure output
[FAIL] Weight below minimum: -9999999999999999969999999999999999 < 10000000000000000

Attack Scenario

  1. Attacker identifies pool with concentrated weights

  2. Submits transaction with carefully crafted weight values

  3. Triggers overflow in normalization calculation

  4. Pool enters invalid state with extreme negative weights

  5. Price calculations become invalid

  6. Attacker exploits price discrepancies for profit

Impact

Severity: CRITICAL

  1. Technical Impact:

    • Integer overflow leads to extreme negative weights (~-1e34)

    • Completely breaks pool mathematics and pricing

    • Bypasses existing guard rails

    • System becomes unusable

    • Affects all pools using QuantAMMMathGuard

  2. Economic Impact:

    • Potential for complete pool failure

    • Could be exploited for economic gain through arbitrage

    • May affect connected pools or protocols

    • Loss of user funds possible

    • Reputational damage to protocol

Tools Used

  • Foundry fuzzing tests

  • Manual code review

  • Mathematical analysis of normalization algorithm

  • Custom test suite for weight boundary conditions

Recommendations

  1. Add Comprehensive Input Validation:

function guardQuantAMMWeights(
int256[] memory newWeights,
int256[] memory prevWeights,
int256 epsilonMax,
int256 absoluteWeightGuardRail
) public pure returns (int256[] memory) {
// Input validation
require(newWeights.length == prevWeights.length, "Length mismatch");
require(epsilonMax > 0 && epsilonMax <= 1e18, "Invalid epsilon");
require(absoluteWeightGuardRail > 0 && absoluteWeightGuardRail <= 1e18, "Invalid guard rail");
for (uint i = 0; i < newWeights.length; i++) {
require(newWeights[i] >= 0 && newWeights[i] <= 1e18, "Weight out of bounds");
require(prevWeights[i] >= 0 && prevWeights[i] <= 1e18, "Previous weight out of bounds");
}
// ... existing code ...
}
  1. Implement Safe Arithmetic:

    • Use OpenZeppelin's SafeMath for all calculations

    • Add overflow checks at critical points

    • Consider using uint256 instead of int256 for weights

    • Implement safe normalization algorithm

  2. Add System-Wide Safeguards:

    • Implement circuit breakers for extreme weight changes

    • Add monitoring for unusual weight distributions

    • Consider gradual weight adjustment mechanism

    • Add invariant checks throughout weight update process

Differentiation from Previous Finding

This is distinct from the previously reported negative weights issue (mathguard-negative-weights.md):

  1. Different root cause (arithmetic overflow vs algorithmic flaw)

  2. Much larger magnitude (-9.999e33 vs -0.096e18)

  3. Requires different mitigation strategies

  4. More severe impact on system stability

  5. Potentially more exploitable for economic gain

References

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.