TokenLaunchHook::initialLiquidity to malicious valueThe initialLiquidity value is read from the pool's current liquidity either in TokenLaunchHook::_afterInitialize or on the first swap in TokenLaunchHook::_beforeSwap. Since pool initialization and adding liquidity are separate transactions, an attacker can frontrun the legitimate liquidity provider to manipulate TokenLaunchHook::initialLiquidity.
Attack scenario:
Pool is initialized → initialLiquidity = 0 (no liquidity exists yet)
Legitimate LP broadcasts transaction to add 100 ETH liquidity
Attacker sees this in mempool and frontruns with:
Add 0.0001 ETH of liquidity
Execute a swap (triggering _beforeSwap)
initialLiquidity is permanently set to the tiny amount (0.0001 ETH worth)
Legitimate LP's 100 ETH liquidity is added, but initialLiquidity doesn't change
maxSwapAmount = (0.0001 ETH * 100) / 10000 = 0.000001 ETH
Every user's swap exceeds the limit and pays penalty fees
Likelihood:
Pool initialization and liquidity addition are always separate transactions
This attack is very easy for a searcher to execute
The attack is profitable: attacker can grief the launch and add liquidity to extract from the increased penalty fees
Impact:
initialLiquidity is permanently locked to attacker-set value
If set too low: all swaps pay penalty fees, legitimate users are griefed
If set too high: limits are ineffective, anti-bot protection is weakened
The token launch is sabotaged with no way to fix (value is not updateable)
Someone initializes a new pool
An attacker sees this in the mempool
The attacker front-runs the deployer in adding liquidity and executing a swap
The initialLiquidity storage variable in the TokenLaunchHook is now permanently set to the liquidity added by the attacker
Add the following test to TokenLaunchHookUnit.t.sol:
Consider requiring a minimum amount of liquidity before first the first swap
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.