QuantAMM

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

Hook-liquidity configuration validation bug in QuantAMMWeightedPoolFactory.sol

Summary

The vulnerability manifests in the QuantAMMWeightedPoolFactory's pool creation process. During pool creation, the factory accepts parameters for both hook configuration and liquidity management settings but fails to validate their relationship. When hooks have enableHookAdjustedAmounts = true, disableUnbalancedLiquidity must be true, but this constraint is not enforced.

Vulnerability Details

Here's a comment in the code:

// disableUnbalancedLiquidity must be set to true if a hook has the flag enableHookAdjustedAmounts = true.

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

What this means is that if:

enableHookAdjustedAmounts = true

disableUnbalancedLiquidity must also be true.

However, in the pool creation functions, this important validation wasn't checked.

Here's a code snippet of the contract creation:

function create(NewPoolParams memory params) external returns (address pool) {
// Step 1: Sets up liquidity management without validation
LiquidityManagement memory liquidityManagement = getDefaultLiquidityManagement();
liquidityManagement.enableDonation = params.enableDonation;
liquidityManagement.disableUnbalancedLiquidity = params.disableUnbalancedLiquidity;
// Step 2: Registers pool with potentially incompatible settings
_registerPoolWithVault(
pool,
params.tokens,
params.swapFeePercentage,
false,
params.roleAccounts,
params.poolHooksContract, // Hook contract with its flags
liquidityManagement // Liquidity settings that should be validated
);
}

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

The core of this vulnerability starts in the VaultTypes.sol contract, where two essential structures are defined: HookFlags and LiquidityManagement. These structures are designed to work together in maintaining pool security and operational integrity. The HookFlags structure contains the enableHookAdjustedAmounts flag, which when set to true, grants hooks the ability to modify token amounts during pool operations.

struct HookFlags {
bool enableHookAdjustedAmounts; // Critical flag for amount modifications
// ... other flags
}

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/interfaces/contracts/vault/VaultTypes.sol#L60

struct LiquidityManagement {
bool disableUnbalancedLiquidity; // Should be true when hooks can adjust amounts
bool enableDonation;
// ... other fields
}

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/interfaces/contracts/vault/VaultTypes.sol#L18

During pool creation, the factory accepts parameters for both hook configuration and liquidity management settings but fails to validate their relationship.

This combination creates a dangerous scenario where hooks can adjust amounts while the pool still permits unbalanced liquidity operations, potentially leading to manipulation of pool balances and economic exploits. Every swap, liquidity addition, or removal operation could potentially be affected by this misconfiguration.

Current implementation flow(Buggy)

  • Pool Creation Starts

    • Factory accepts hook configuration with enableHookAdjustedAmounts

    • Factory accepts liquidity settings with disableUnbalancedLiquidity

    • No validation between these settings

    • Pool deploys with potentially incompatible configuration

    • Operations proceed with security risk

function create(NewPoolParams memory params) external returns (address pool) {
LiquidityManagement memory liquidityManagement = getDefaultLiquidityManagement();
liquidityManagement.enableDonation = params.enableDonation;
liquidityManagement.disableUnbalancedLiquidity = params.disableUnbalancedLiquidity;
// No validation - Proceeds directly to pool creation
}


Whereas, the correct implementation should be:

  • Pool Creation Starts

    • Factory accepts hook configuration with enableHookAdjustedAmounts

    • Factory accepts liquidity settings with disableUnbalancedLiquidity

    • Factory checks: if enableHookAdjustedAmounts = true then requires disableUnbalancedLiquidity = true

    • Pool only deploys if validation passes

    • Operations proceed safely

function create(NewPoolParams memory params) external returns (address pool) {
LiquidityManagement memory liquidityManagement = getDefaultLiquidityManagement();
liquidityManagement.enableDonation = params.enableDonation;
liquidityManagement.disableUnbalancedLiquidity = params.disableUnbalancedLiquidity;
// Validation before pool creation
if (IHooks(params.poolHooksContract).getHookFlags().enableHookAdjustedAmounts) {
require(liquidityManagement.disableUnbalancedLiquidity, "Hook amounts require disabled unbalanced liquidity");
}
}

Impact

Pools can be created with incompatible settings. Hooks that adjust amounts can operate with unbalanced liquidity enabled. This may cause manipulation of pool balances as unbalanced liquidity remains enabled.

Tools Used

Manual review

Recommendations

The correct implementation should be:

  • Pool Creation Starts

    • Factory accepts hook configuration with enableHookAdjustedAmounts

    • Factory accepts liquidity settings with disableUnbalancedLiquidity

    • Factory checks: if enableHookAdjustedAmounts = true then requires disableUnbalancedLiquidity = true

    • Pool only deploys if validation passes

    • Operations proceed safely

function create(NewPoolParams memory params) external returns (address pool) {
LiquidityManagement memory liquidityManagement = getDefaultLiquidityManagement();
liquidityManagement.enableDonation = params.enableDonation;
liquidityManagement.disableUnbalancedLiquidity = params.disableUnbalancedLiquidity;
// Validation before pool creation
if (IHooks(params.poolHooksContract).getHookFlags().enableHookAdjustedAmounts) {
require(liquidityManagement.disableUnbalancedLiquidity, "Hook amounts require disabled unbalanced liquidity");
}
}

This should be applied to the two pool creation functions.

Updates

Lead Judging Commences

n0kto Lead Judge 11 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.

Appeal created

sabit Submitter
11 months ago
sabit Submitter
11 months ago
n0kto Lead Judge
11 months ago
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!