The hook should enforce per-user swap limits to prevent bots from dumping tokens.
function _beforeSwap(address sender, ...) {
if (addressLastSwapBlock[sender] > 0) {
uint256 blocksSinceLastSwap = block.number - addressLastSwapBlock[sender];
if (blocksSinceLastSwap < phaseCooldown) {
applyPenalty = true;
}
}
if (!applyPenalty && addressSwappedAmount[sender] + swapAmount > maxSwapAmount) {
applyPenalty = true;
}
addressSwappedAmount[sender] += swapAmount;
addressLastSwapBlock[sender] = block.number;
}
function test_HookTracksRouterNotUsers() public {
vm.deal(user1, 1 ether);
vm.prank(user1);
swapRouter.swap{value: 0.0001 ether}(
key,
SwapParams({zeroForOne: true, amountSpecified: -0.0001 ether, sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),
PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}),
ZERO_BYTES
);
address alice = makeAddr("alice");
token.mint(alice, 100 ether);
vm.deal(alice, 100 ether);
vm.startPrank(alice);
token.approve(address(swapRouter), type(uint256).max);
swapRouter.swap{value: 0.01 ether}(
key,
SwapParams({zeroForOne: true, amountSpecified: -0.01 ether, sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),
PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}),
ZERO_BYTES
);
vm.stopPrank();
address bob = makeAddr("bob");
token.mint(bob, 100 ether);
vm.deal(bob, 100 ether);
vm.startPrank(bob);
token.approve(address(swapRouter), type(uint256).max);
vm.roll(block.number + phase1Cooldown + 1);
swapRouter.swap{value: 0.01 ether}(
key,
SwapParams({zeroForOne: true, amountSpecified: -0.01 ether, sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1}),
PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}),
ZERO_BYTES
);
vm.stopPrank();
console.log("Alice's tracking:", antiBotHook.addressSwappedAmount(alice));
console.log("Bob's tracking:", antiBotHook.addressSwappedAmount(bob));
console.log("Router's tracking:", antiBotHook.addressSwappedAmount(address(swapRouter)));
assertEq(antiBotHook.addressSwappedAmount(alice), 0, "Alice not tracked");
assertEq(antiBotHook.addressSwappedAmount(bob), 0, "Bob not tracked");
}
function _beforeSwap(address sender, ...) {
+ address actualUser = tx.origin;
- if (addressLastSwapBlock[sender] > 0) {
+ if (addressLastSwapBlock[actualUser] > 0) {
- uint256 blocksSinceLastSwap = block.number - addressLastSwapBlock[sender];
+ uint256 blocksSinceLastSwap = block.number - addressLastSwapBlock[actualUser];
if (blocksSinceLastSwap < phaseCooldown) {
applyPenalty = true;
}
}
- if (!applyPenalty && addressSwappedAmount[sender] + swapAmount > maxSwapAmount) {
+ if (!applyPenalty && addressSwappedAmount[actualUser] + swapAmount > maxSwapAmount) {
applyPenalty = true;
}
- addressSwappedAmount[sender] += swapAmount;
+ addressSwappedAmount[actualUser] += swapAmount;
- addressLastSwapBlock[sender] = block.number;
+ addressLastSwapBlock[actualUser] = block.number;
}