Normal Behavior: The TokenLaunchHook is designed to enforce individual user swap limits and cooldown periods, ensuring no single actor can manipulate the price or drain liquidity during the sensitive initial launch period.
Specific Issue: The contract uses the sender address passed to the _beforeSwap hook to track usage via addressSwappedAmount and addressLastSwapBlock. However, in Uniswap V4, the sender address is the address that calls PoolManager.swap(). For standard swaps, this is the SwapRouter contract address, not the user's personal wallet.
Likelihood:
This occurs automatically for every user who trades using the canonical Uniswap V4 router or any standard frontend interface that interacts with the PoolManager through a periphery contract.
Impact:
Global Denial of Service: Once the cumulative swap volume of all users hits the phaseLimitBps, the Router is deemed to have exhausted its limit. Every subsequent user is then unfairly penalized with the maximum fee.
Perpetual Cooldown: Every swap resets the addressLastSwapBlock for the Router. If any trade occurs within the phaseCooldown window (e.g., 5 blocks), the "global" cooldown is extended, potentially locking the entire pool in a penalty state for all participants indefinitely.
The following Foundry test demonstrates how the SwapRouter's address is used for tracking instead of the actual user's wallet. It proves that User 2 is unfairly blocked by a cooldown triggered by User 1's previous transaction.
Identify the actual transaction initiator using tx.origin or require the periphery router to pass the actual user's address through the hookData parameter.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.