Vanguard

First Flight #56
Beginner FriendlyDeFiFoundry
0 EXP
Submission Details
Impact: high
Likelihood: high

Attackers can permanently break anti-bot scaling by pre-initializing pools with near-zero liquidity

Author Revealed upon completion

Root + Impact

Description

  • Description The TokenLaunchHook relies on initialLiquidity to calculate the maximum swap amounts allowed during Phase 1 and Phase 2. This variable is set once during the _afterInitialize callback.

    In Uniswap v4, pool initialization is permissionless. An attacker can monitor the mempool for a new token launch and front-run the legitimate liquidity provision by calling initialize() themselves with a negligible amount of liquidity (e.g., 1 wei).Description The TokenLaunchHook relies on initialLiquidity to calculate the maximum swap amounts allowed during Phase 1 and Phase 2. This variable is set once during the _afterInitialize callback.

    In Uniswap v4, pool initialization is permissionless. An attacker can monitor the mempool for a new token launch and front-run the legitimate liquidity provision by calling initialize() themselves with a negligible amount of liquidity (e.g., 1 wei).

//in file TokenLaunchHook.sol::Line-125
function _afterInitialize(address, PoolKey calldata key, uint160, int24) internal override returns (bytes4) {
// ...
@> launchStartBlock = block.number;
@> uint128 liquidity = StateLibrary.getLiquidity(poolManager, key.toId());
@> initialLiquidity = uint256(liquidity);
// ...
}
//and line-50
@> uint256 public initialLiquidity; // defined globally

Risk

Likelihood:

  • This will occur because there is no access control on who can initialize a pool.

  • Sniper bots frequently use this tactic to "brick" protection logic or to ensure the launchStartBlock is set at a time that favors their scripts.

Impact:

  • Bypass of Swap Limits: If initialLiquidity is set to 1 wei, the maxSwapAmount (which is a percentage of initial liquidity) becomes effectively 0. This bricks the pool for all legitimate users.

  • Permanent Logic Corruption: Since these variables are global and set only once, the "Anti-Bot" hook remains permanently configured with the wrong data, rendering the launch protection useless or destructive.

Proof of Concept

Permissionless Initialization: In Uniswap v4, anyone can call initialize(), which triggers the hook's afterInitialize callback before the owner can add liquidity.

  • Zero-Liquidity Capture: If a bot initializes the pool first, the hook records initialLiquidity as 0 because the pool is empty at that exact moment.

  • Corrupted Baseline: Once initialLiquidity is set to 0, it is stored in the hook's global state and cannot be updated by subsequent legitimate liquidity additions.

  • Mathematical Bricking: Any limit calculation based on a 0 baseline (e.g., $0 \times 1\%$) results in a 0 maximum swap amount.

  • Permanent Denial of Service: Every swap attempt thereafter is rejected by the hook because the transaction amount will always exceed the corrupted "0" limit.

  • Critical Impact: The token launch is permanently ruined, as the anti-bot protection effectively bans all trading instead of just restricting it.

Recommended Mitigation

  • Access Control: Add an owner or factory check in _afterInitialize so only an authorized address can trigger the setup.

- remove this code
+ add this code

Support

FAQs

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

Give us feedback!