Vanguard

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

Deployment Script uses incorrect hook flags causing revert

Author Revealed upon completion

Deployment Script uses incorrect hook flags causing revert

Description

The deployment script script/deployLaunchHook.s.sol calculates the hook address using Hooks.BEFORE_INITIALIZE_FLAG. However, the TokenLaunchHook contract implements afterInitialize permissions, not beforeInitialize.

The BaseHook constructor validates that the deployed address flags match the contract's getHookPermissions(). Because of this mismatch, the deployment transaction will inevitably revert with HookAddressNotValid.

// script/deployLaunchHook.s.sol
@> uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_INITIALIZE_FLAG);
// Contract requires AFTER_INITIALIZE_FLAG

Risk

Likelihood:

  • Occurs every deployment.

Impact:

  • Prevents deployment of the protocol until fixed.

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {Test} from "forge-std/Test.sol";
import {TokenLaunchHook} from "../src/TokenLaunchHook.sol";
import {Hooks} from "v4-core/libraries/Hooks.sol";
import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol";
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol";
contract DeployScriptBugTest is Test {
IPoolManager manager = IPoolManager(address(0x123));
function test_DeployScriptBug_WrongFlags() public {
// The script uses these flags:
uint160 scriptFlags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_INITIALIZE_FLAG);
// Verify that the flags used in the script DO NOT match the hook's expected requirements
bool hasAfterInitialize = (scriptFlags & Hooks.AFTER_INITIALIZE_FLAG) != 0;
bool hasBeforeInitialize = (scriptFlags & Hooks.BEFORE_INITIALIZE_FLAG) != 0;
assertFalse(hasAfterInitialize, "Script flags missing AFTER_INITIALIZE_FLAG");
assertTrue(hasBeforeInitialize, "Script flags incorrectly include BEFORE_INITIALIZE_FLAG");
// Attempting to mine a salt with these WRONG flags
bytes memory constructorArgs = abi.encode(manager, 100, 100, 100, 500, 5, 2, 1000, 500);
(address hookAddress, bytes32 salt) =
HookMiner.find(address(this), scriptFlags, type(TokenLaunchHook).creationCode, constructorArgs);
// Deployment will revert because BaseHook validates that the address flags match getHookPermissions()
// getHookPermissions() returns AFTER_INITIALIZE, but we mined an address for BEFORE_INITIALIZE.
vm.expectRevert(abi.encodeWithSelector(Hooks.HookAddressNotValid.selector, hookAddress));
new TokenLaunchHook{salt: salt}(manager, 100, 100, 100, 500, 5, 2, 1000, 500);
}
}

Recommended Mitigation

Update the flags in the deployment script to match the contract's permissions.

- uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_INITIALIZE_FLAG);
+ uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_INITIALIZE_FLAG);

Support

FAQs

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

Give us feedback!