QuantAMM

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

Implicit Zero-Initialization of LiquidityManagement Struct Compromises Pool Configuration Safety

Description

The getDefaultLiquidityManagement() function in BasePoolFactory.sol declares that it returns a LiquidityManagement struct but has an empty function body that relies on implicit zero initialization:

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-utils/contracts/BasePoolFactory.sol#L188

function getDefaultLiquidityManagement() public pure returns (LiquidityManagement memory liquidityManagement) {
// solhint-disable-previous-line no-empty-blocks
}

The issue here is that LiquidityManagement configurations are fundamental to pool behavior in Balancer V3's architecture. This struct controls key pool functionality like enabling donations and unbalanced liquidity settings. By implicitly defaulting to zero values through an empty implementation, pools deployed through this factory could have critical features unintentionally disabled or misconfigured. This becomes especially problematic in the context of QuantAMM weighted pools, which have sophisticated requirements around liquidity management for their weight adjustment mechanisms. When these pools are registered with the Vault via _registerPoolWithVault, the zero-initialized settings could prevent proper pool operation or cause unexpected behavior in the weight adjustment logic that depends on specific liquidity constraints.

The silent reliance on default zero initialization also introduces a maintenance hazard - as new fields are added to the LiquidityManagement struct to support evolving pool features, developers may not realize the need to explicitly initialize these fields with appropriate non-zero defaults.

Recommended Mitigation Steps

  1. Explicitly initialize all struct fields with their intended default values:

function getDefaultLiquidityManagement() public pure returns (LiquidityManagement memory liquidityManagement) {
liquidityManagement = LiquidityManagement({
enableDonation: false,
disableUnbalancedLiquidity: false,
// Initialize any other fields with appropriate defaults
});
return liquidityManagement;
}
  1. Consider making the defaults configurable by admin if appropriate:

struct DefaultSettings {
bool defaultEnableDonation;
bool defaultDisableUnbalancedLiquidity;
}
DefaultSettings private defaultSettings;
function setDefaultSettings(DefaultSettings calldata _settings) external onlyAdmin {
defaultSettings = _settings;
emit DefaultSettingsUpdated(_settings);
}
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.