Although the protocol defines per-block swap limits during launch phases, these limits are never enforced.
When a user exceeds the allowed swap amount, the contract merely applies a penalty fee instead of reverting the transaction.
This allows bots or malicious actors to swap unlimited amounts simply by paying the penalty, completely bypassing the intended launch protections.
Run this test:
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/TokenLaunchHook.sol";
contract ExploitLimitBypass is Test {
TokenLaunchHook hook;
function testLimitsNotEnforced() public {
hook = new TokenLaunchHook(
poolManager,
100,
100,
100,
200,
5,
3,
3000,
1500
);
SwapParams memory params = SwapParams({
zeroForOne: true,
amountSpecified: -50000,
sqrtPriceLimitX96: 0
});
uint256 botLimit = hook.getUserRemainingLimit(botAddress);
assertEq(botLimit, 1000);
hook.beforeSwap(botAddress, poolKey, params, "");
uint256 swappedAmount = hook.addressSwappedAmount(botAddress);
assertEq(swappedAmount, 50000);
}
}
- remove this code
if (addressLastSwapBlock[sender] > 0) {
uint256 blocksSinceLastSwap = block.number - addressLastSwapBlock[sender];
if (blocksSinceLastSwap < phaseCooldown) {
applyPenalty = true;
}
}
if (!applyPenalty && addressSwappedAmount[sender] + swapAmount > maxSwapAmount) {
applyPenalty = true;
}
uint24 feeOverride = 0;
if (applyPenalty) {
feeOverride = uint24((phasePenaltyBps * 100));
}
+ add this code
// Enforce cooldown strictly
if (addressLastSwapBlock[sender] > 0) {
uint256 blocksSinceLastSwap = block.number - addressLastSwapBlock[sender];
if (blocksSinceLastSwap < phaseCooldown) {
revert CooldownNotMet(addressLastSwapBlock[sender] + phaseCooldown);
}
}
// Enforce max swap amount strictly
if (addressSwappedAmount[sender] + swapAmount > maxSwapAmount) {
revert SwapLimitExceeded(
maxSwapAmount,
addressSwappedAmount[sender] + swapAmount
);
}
The recommended mitigation replaces the penalty-only enforcement model with hard limit enforcement.
Instead of allowing swaps to proceed with increased fees, the hook now reverts transactions that violate cooldown or per-block swap limits. This ensures that launch restrictions are enforced at the protocol level and cannot be bypassed by paying a fee.
By reverting on violations:
Oversized swaps are fully blocked
Bots cannot economically bypass protections