QuantAMM

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

QuantAMMWeightedPoolFactory's constructor lacks parameters sanitization and validation. Protocol functionality disruption.

Summary

In the QuantAMMWeightedPoolFactory contract, constructor is used to setup prominent parameter for security, attack response mechanisms etc. The parameters however, not santized due to which some severe consequences could occur like, Liquidity Lock-In, Market dynamics impact, Reputation damage, exploitations, no time to response to issues, etc.

Vulnerability Details

QuantAMMWeightedPoolFactory::constructor:

constructor(
IVault vault,
uint32 pauseWindowDuration,
string memory factoryVersion,
string memory poolVersion,
address updateWeightRunner
) BasePoolFactory(vault, pauseWindowDuration, type(QuantAMMWeightedPool).creationCode) Version(factoryVersion) {
@> // @info: pool creator can set pause window duration to zero or max upto type(uint32).max
// pause window duration should be an interval of time in seconds
// and it should be passed as a parameter to the base pool factory constructor after
// adding it to a timestamp therefore interval management should be on-chain
// i.e., block.timestamp + interval and interval > 0 AND interval <= intervalMax which is indeed happening under the hood
// however, internally there's no check for too frequent and too large intervals
@> // vulnerability: if interval is too small like 0 - 10 seconds then there would be a worthless pause, and
// if interval is too large like 1 year then there would be a long pause
// so, here should have a min interval and max interval check
@> // @info: missing factoryVersion string length check
require(updateWeightRunner != address(0), "update weight runner cannot be default address");
@> // @info: missing poolVersion string length check
_poolVersion = poolVersion;
_updateWeightRunner = updateWeightRunner;
}

Impact

  1. Inadequate Time to Respond to Issues:

Admins or automation scripts might not have enough time to diagnose and fix the problem before the pause window expires.
Exploits or errors might persist after the short pause ends.

  1. Operational Disruptions:

Frequent pauses and unpauses due to repeated issues could disrupt pool functionality and user trust.

  1. Automation Ineffectiveness:

Automated mechanisms (e.g., Chainlink Keepers) may not react quickly enough to manage the situation within the short window.

  1. Exacerbated Losses:

If a bug or exploit is not resolved quickly, malicious actors can continue taking advantage of the system after the pause expires.

Example Problem:
A stale oracle price triggers the pause mechanism. If the window is only 10 seconds, the issue remains unresolved, and swaps resume with incorrect pricing, leading to arbitrage exploits or LP losses.

  1. Liquidity Lock-In:

LPs' funds remain inaccessible for an extended period, reducing trust in the protocol and discouraging participation.
Users needing liquidity may experience financial strain if they cannot withdraw their assets.

  1. Market Dynamics Impact:

A prolonged pause might cause the pool's token prices to diverge significantly from the external market.
Arbitrage opportunities could be missed, or traders may avoid the pool entirely.

  1. Protocol Reputation Damage:

Extended downtime can be seen as a failure, reducing user confidence and affecting adoption.

  1. Governance Challenges:

A long pause could lead to contentious governance debates about whether and when to resume the pool, creating uncertainty.

  1. Economic Inefficiency:

The protocol would miss out on swap fees and other revenue during the prolonged pause, affecting its sustainability.

  1. Exploitation Risk:

If malicious actors trigger the pause intentionally (e.g., by exploiting a vulnerability), they could lock the pool indefinitely, harming LPs and users.

Example Problem:
An attacker uses a governance loophole to trigger a year-long pause. LPs cannot withdraw, and users avoid the protocol, leading to loss of liquidity and trust.

Tools Used

  1. Manual Review

  2. Chat GPT

Recommendations

Please add proper checks to mitigate pointed issues. One possible solution is given below:

QuantAMMWeightedPoolFactory::constructor:

+ modifier validPauseWindowDuration(uint32 _pauseWindowDuration) {
+ if (_pauseWindowDuration < 300 && _pauseWindowDuration > 3600) {
+ revert("Invalid pause window duration");
+ }
+ _;
+ }
+ modifier validVersion(string memory _version) {
+ if (bytes(_version).length == 0) {
+ revert("Invalid version");
+ }
+ _;
+ }
constructor(
IVault vault,
uint32 pauseWindowDuration,
string memory factoryVersion,
string memory poolVersion,
address updateWeightRunner
- ) BasePoolFactory(vault, pauseWindowDuration, type(QuantAMMWeightedPool).creationCode) Version(factoryVersion) {
+ ) validPauseWindowDuration(pauseWindowDuration) validVersion(factoryVersion) BasePoolFactory(vault, pauseWindowDuration, type(QuantAMMWeightedPool).creationCode) Version(factoryVersion) {
require(updateWeightRunner != address(0), "update weight runner cannot be default address");
+ require(bytes(poolVersion).length > 0, "Invalid version");
_poolVersion = poolVersion;
_updateWeightRunner = updateWeightRunner;
}
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!