QuantAMM

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

Create2 Deployment Vulnerability in BasePoolFactory

Summary

The _create function in BasePoolFactory.sol is susceptible to front-running attacks during pool deployment, which could lead to denial of service (DOS) by blocking intended pool addresses.

Vulnerability Details

The vulnerability stems from predictable Create2 deployment addresses and unprotected pool creation mechanisms. an d it exists in the base factory implementation used by multiple pool types:

function `_create`(bytes memory constructorArgs, bytes32 salt) internal returns (address pool) {
bytes memory creationCode = abi.encodePacked(_creationCode, constructorArgs);
bytes32 finalSalt = _computeFinalSalt(salt);
pool = Create2.deploy(0, finalSalt, creationCode);
_registerPoolWithFactory(pool);
}

This function is called by multiple factory contracts:

QuantAMMWeightedPoolFactory:
pool = _create(abi.encode(
QuantAMMWeightedPool.NewPoolParams({...}),
getVault()
), params.salt);
WeightedPoolFactory:
pool = _create(
abi.encode(
WeightedPool.NewPoolParams({...}),
getVault()
),
salt
);

Similar patterns in:

  • WeightedPool8020Factory

  • StableSurgePoolFactory

  • Gyro2CLPPoolFactory

Impact

HIGH - Affects core protocol functionality:

  1. Pool Deployment:

  • Attackers can front-run pool creation transactions

  • Can force specific pool addresses to be unavailable

  • Affects all pool types in the protocol

  1. Protocol Operations:

  • DOS on pool deployment

  • Increased gas costs for deployers

  • Potential blocking of strategic pool addresses

Attack Flow

participant Deployer
participant Mempool
participant Attacker
participant Factory
Deployer->>Mempool: Submit pool creation tx
Attacker->>Mempool: Monitor creation tx
Attacker->>Factory: Front-run with identical salt
Factory->>Attacker: Deploy to target address
Deployer->>Factory: Tx fails (address taken)

Proof of Concept

  • Attacker monitors mempool for pool creation transactions

  • Front-runs with same salt value

  • Original transaction fails

  • Forces deployer to use different salt or parameters

Recommendations

Implement unique salt generation:

function _create(bytes memory constructorArgs, bytes32 salt) internal returns (address pool) {
bytes32 uniqueSalt = keccak256(abi.encodePacked(msg.sender, salt, block.timestamp));
bytes memory creationCode = abi.encodePacked(_creationCode, constructorArgs);
bytes32 finalSalt = _computeFinalSalt(uniqueSalt);
pool = Create2.deploy(0, finalSalt, creationCode);
_registerPoolWithFactory(pool);
}

You can also Add deployment protection:

mapping(address => bool) private _authorizedDeployers;
modifier onlyAuthorizedDeployer() {
require(_authorizedDeployers[msg.sender], "Unauthorized deployer");
_;
}
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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