Base Sepolia Testnet

Contract

0x794B1409ef4b40a90eC8AF62EaF4c8bf275e5000

Overview

ETH Balance

0 ETH

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To Amount
304890572025-09-01 17:06:4299 days ago1756746402  Contract Creation0 ETH

Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x32e85224...5b5C89000
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
UniV4Hook

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 1 : Univ4Hook5.sol
// SPDX-License-Identifier: MIT
//   
//MUST CHANGE BELOW TO CORRECT SETTINGS FOR DIFFERENT CHAIN
//    IPoolManager_Hook public immutable manager = IPoolManager_Hook(0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408);
// Possibly set admin of poolFee to hardware wallet for easiest setup  ADMINOFHOOK
//ADMINOFHOOK





// B ZERO X Token - B0x Token Hook Miner and Hook Contract
//
// Website: https://bzerox.com/
// Github: https://github.com/B0x-Token/
// Discord: https://discord.gg/K89uF2C8vJ
// Twitter: https://x.com/B0x_Token/
//
//
// Distrubtion of B ZERO X Tokens - B0x Token is as follows:
//
// B0x Token is distributed to users by using Proof of work and is considered a Version 2 & Layer 2 of 0xBitcoin.  Our contract allows all 0xBitcoin to be converted to B0x Tokens.
// Computers solve a complicated problem to gain tokens!
// 100% of 0xBitcoin accepted for B0x Tokens
// 100% Of the Token is distributed to the users! No dev fee!
// Token Mining will take place on Base Blockchain, while having the token reside on Mainnet Ethereum.
//
// Symbol: B0x
// Decimals: 18
//31165100
// Total supply: 31,165,100.000000000000000000
//   =
// 10,835,900 0xBitcoin Tokens able to transfered to B0x Tokens.
// +
// 10,164,100 Mined over 100+ years using Bitcoins Distrubtion halvings every ~4 years. Uses Proof-oF-Work to distribute the tokens. Public Miner is available see https://bzerox.com/
// +
// 10,164,100 sent to Liquidity Providers of the 0xBTC/B0x liquidity pool. Distributes 1 token to the Staking contract for every 1 token minted by Proof-of-Work miners
//  
//
// No dev cut, or advantage taken at launch. Public miner available at launch. 100% of the token is given away fairly over 100+ years using Bitcoins model!
// 
// Mint 2016 answers per challenge in this cost savings Bitcoin!! Less failed transactions as the challenge only changes every 2016 answers instead of every answer.
//
// Credits: 0xBitcoin
//


pragma solidity ^0.8.0;
/// @title Library for reverting with custom errors efficiently
/// @notice Contains functions for reverting with custom errors with different argument types efficiently
/// @dev To use this library, declare `using CustomRevert for bytes4;` and replace `revert CustomError()` with
/// `CustomError.selector.revertWith()`
/// @dev The functions may tamper with the free memory pointer but it is fine since the call context is exited immediately
library CustomRevert {
    /// @dev ERC-7751 error for wrapping bubbled up reverts
    error WrappedError(address target, bytes4 selector, bytes reason, bytes details);

    /// @dev Reverts with the selector of a custom error in the scratch space
    function revertWith(bytes4 selector) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            revert(0, 0x04)
        }
    }

    /// @dev Reverts with a custom error with an address argument in the scratch space
    function revertWith(bytes4 selector, address addr) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, and(addr, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with an int24 argument in the scratch space
    function revertWith(bytes4 selector, int24 value) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, signextend(2, value))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with a uint160 argument in the scratch space
    function revertWith(bytes4 selector, uint160 value) internal pure {
        assembly ("memory-safe") {
            mstore(0, selector)
            mstore(0x04, and(value, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(0, 0x24)
        }
    }

    /// @dev Reverts with a custom error with two int24 arguments
    function revertWith(bytes4 selector, int24 value1, int24 value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), signextend(2, value1))
            mstore(add(fmp, 0x24), signextend(2, value2))
            revert(fmp, 0x44)
        }
    }

    /// @dev Reverts with a custom error with two uint160 arguments
    function revertWith(bytes4 selector, uint160 value1, uint160 value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(fmp, 0x44)
        }
    }

    /// @dev Reverts with a custom error with two address arguments
    function revertWith(bytes4 selector, address value1, address value2) internal pure {
        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(fmp, selector)
            mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
            revert(fmp, 0x44)
        }
    }

    /// @notice bubble up the revert message returned by a call and revert with a wrapped ERC-7751 error
    /// @dev this method can be vulnerable to revert data bombs
    function bubbleUpAndRevertWith(
        address revertingContract,
        bytes4 revertingFunctionSelector,
        bytes4 additionalContext
    ) internal pure {
        bytes4 wrappedErrorSelector = WrappedError.selector;
        assembly ("memory-safe") {
            // Ensure the size of the revert data is a multiple of 32 bytes
            let encodedDataSize := mul(div(add(returndatasize(), 31), 32), 32)

            let fmp := mload(0x40)

            // Encode wrapped error selector, address, function selector, offset, additional context, size, revert reason
            mstore(fmp, wrappedErrorSelector)
            mstore(add(fmp, 0x04), and(revertingContract, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(
                add(fmp, 0x24),
                and(revertingFunctionSelector, 0xffffffff00000000000000000000000000000000000000000000000000000000)
            )
            // offset revert reason
            mstore(add(fmp, 0x44), 0x80)
            // offset additional context
            mstore(add(fmp, 0x64), add(0xa0, encodedDataSize))
            // size revert reason
            mstore(add(fmp, 0x84), returndatasize())
            // revert reason
            returndatacopy(add(fmp, 0xa4), 0, returndatasize())
            // size additional context
            mstore(add(fmp, add(0xa4, encodedDataSize)), 0x04)
            // additional context
            mstore(
                add(fmp, add(0xc4, encodedDataSize)),
                and(additionalContext, 0xffffffff00000000000000000000000000000000000000000000000000000000)
            )
            revert(fmp, add(0xe4, encodedDataSize))
        }
    }
}


/// @title Safe casting methods
/// @notice Contains methods for safely casting between types
library SafeCast {
    using CustomRevert for bytes4;

    error SafeCastOverflow();

    /// @notice Cast a uint256 to a uint160, revert on overflow
    /// @param x The uint256 to be downcasted
    /// @return y The downcasted integer, now type uint160
    function toUint160(uint256 x) internal pure returns (uint160 y) {
        y = uint160(x);
        if (y != x) SafeCastOverflow.selector.revertWith();
    }

    /// @notice Cast a uint256 to a uint128, revert on overflow
    /// @param x The uint256 to be downcasted
    /// @return y The downcasted integer, now type uint128
    function toUint128(uint256 x) internal pure returns (uint128 y) {
        y = uint128(x);
        if (x != y) SafeCastOverflow.selector.revertWith();
    }

    /// @notice Cast a int128 to a uint128, revert on overflow or underflow
    /// @param x The int128 to be casted
    /// @return y The casted integer, now type uint128
    function toUint128(int128 x) internal pure returns (uint128 y) {
        if (x < 0) SafeCastOverflow.selector.revertWith();
        y = uint128(x);
    }

    /// @notice Cast a int256 to a int128, revert on overflow or underflow
    /// @param x The int256 to be downcasted
    /// @return y The downcasted integer, now type int128
    function toInt128(int256 x) internal pure returns (int128 y) {
        y = int128(x);
        if (y != x) SafeCastOverflow.selector.revertWith();
    }

    /// @notice Cast a uint256 to a int256, revert on overflow
    /// @param x The uint256 to be casted
    /// @return y The casted integer, now type int256
    function toInt256(uint256 x) internal pure returns (int256 y) {
        y = int256(x);
        if (y < 0) SafeCastOverflow.selector.revertWith();
    }

    /// @notice Cast a uint256 to a int128, revert on overflow
    /// @param x The uint256 to be downcasted
    /// @return The downcasted integer, now type int128
    function toInt128(uint256 x) internal pure returns (int128) {
        if (x >= 1 << 127) SafeCastOverflow.selector.revertWith();
        return int128(int256(x));
    }
}
/// @dev Two `int128` values packed into a single `int256` where the upper 128 bits represent the amount0
/// and the lower 128 bits represent the amount1.
type BalanceDelta is int256;

using {add as +, sub as -, eq as ==, neq as !=} for BalanceDelta global;
using BalanceDeltaLibrary for BalanceDelta global;
using SafeCast for int256;

function toBalanceDelta(int128 _amount0, int128 _amount1) pure returns (BalanceDelta balanceDelta) {
    assembly ("memory-safe") {
        balanceDelta := or(shl(128, _amount0), and(sub(shl(128, 1), 1), _amount1))
    }
}

function add(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
    int256 res0;
    int256 res1;
    assembly ("memory-safe") {
        let a0 := sar(128, a)
        let a1 := signextend(15, a)
        let b0 := sar(128, b)
        let b1 := signextend(15, b)
        res0 := add(a0, b0)
        res1 := add(a1, b1)
    }
    return toBalanceDelta(res0.toInt128(), res1.toInt128());
}

function sub(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
    int256 res0;
    int256 res1;
    assembly ("memory-safe") {
        let a0 := sar(128, a)
        let a1 := signextend(15, a)
        let b0 := sar(128, b)
        let b1 := signextend(15, b)
        res0 := sub(a0, b0)
        res1 := sub(a1, b1)
    }
    return toBalanceDelta(res0.toInt128(), res1.toInt128());
}

function eq(BalanceDelta a, BalanceDelta b) pure returns (bool) {
    return BalanceDelta.unwrap(a) == BalanceDelta.unwrap(b);
}

function neq(BalanceDelta a, BalanceDelta b) pure returns (bool) {
    return BalanceDelta.unwrap(a) != BalanceDelta.unwrap(b);
}

/// @notice Library for getting the amount0 and amount1 deltas from the BalanceDelta type
library BalanceDeltaLibrary {
    /// @notice A BalanceDelta of 0
    BalanceDelta public constant ZERO_DELTA = BalanceDelta.wrap(0);

    function amount0(BalanceDelta balanceDelta) internal pure returns (int128 _amount0) {
        assembly ("memory-safe") {
            _amount0 := sar(128, balanceDelta)
        }
    }

    function amount1(BalanceDelta balanceDelta) internal pure returns (int128 _amount1) {
        assembly ("memory-safe") {
            _amount1 := signextend(15, balanceDelta)
        }
    }
}
// -----------------------------------------------------------------------------
// Minimal Interfaces
// -----------------------------------------------------------------------------

/// @notice Defines the key parameters that uniquely identify a Uniswap V4 pool
/// @dev Used to specify which pool to interact with across various hook operations
struct PoolKey_Hook {
    /// @notice The first token in the pool pair (lexicographically smaller address)
    address currency0;
    /// @notice The second token in the pool pair (lexicographically larger address)  
    address currency1;
    /// @notice The fee tier for swaps in the pool, expressed in hundredths of a bip (e.g., 3000 = 0.3%)
    uint24 fee;
    /// @notice The tick spacing for the pool, determining price granularity and liquidity positions
    int24 tickSpacing;
    /// @notice Address of the hook contract associated with this pool
    address hooks;
}


/// @notice Interface for interacting with the Uniswap V4 Pool Manager for hook operations
/// @dev Provides essential functions needed by hook contracts to manage pool parameters
interface IPoolManager_Hook {
    /// @notice Updates the dynamic liquidity provider fee for a specific pool
    /// @dev Only callable by authorized hook contracts to adjust LP fees dynamically
    /// @param key The pool identifier containing currency pair and hook information
    /// @param newDynamicLPFee The new fee rate to set, expressed in hundredths of a bip (e.g., 3000 = 0.3%)
    function updateDynamicLPFee(PoolKey_Hook memory key, uint24 newDynamicLPFee) external;
}

interface IHooks5 {

    /// @notice Hook function called after a pool has been successfully initialized
    /// @param sender Address that initiated the pool initialization
    /// @param key Pool parameters including currencies, fee, and tick spacing
    /// @param sqrtPriceX96 Initial price of the pool encoded as sqrt(price) * 2^96
    /// @param tick The initial tick corresponding to the starting price
    /// @param hookData Additional data passed to the hook for custom logic
    /// @return bytes4 Function selector to validate successful execution
    function afterInitialize(
        address sender,
        PoolKey_Hook calldata key,
        uint160 sqrtPriceX96,
        int24 tick,
        bytes calldata hookData
    ) external returns (bytes4);


    /// @notice Defines which hook functions a contract wants to implement and when they should be called
    /// @dev Used by the pool manager to determine which hooks to call during pool operations
    struct Permissions {
        /// @notice Whether to call beforeInitialize when a pool is being created
        bool beforeInitialize;
        /// @notice Whether to call afterInitialize after a pool is created
        bool afterInitialize;
        /// @notice Whether to call beforeAddLiquidity when liquidity is being added
        bool beforeAddLiquidity;
        /// @notice Whether to call afterAddLiquidity after liquidity is added
        bool afterAddLiquidity;
        /// @notice Whether to call beforeRemoveLiquidity when liquidity is being removed
        bool beforeRemoveLiquidity;
        /// @notice Whether to call afterRemoveLiquidity after liquidity is removed
        bool afterRemoveLiquidity;
        /// @notice Whether to call beforeSwap when a swap is being executed
        bool beforeSwap;
        /// @notice Whether to call afterSwap after a swap is executed
        bool afterSwap;
        /// @notice Whether to call beforeDonate when tokens are being donated to the pool
        bool beforeDonate;
        /// @notice Whether to call afterDonate after tokens are donated to the pool
        bool afterDonate;
        /// @notice Whether beforeSwap should return a delta value to modify swap behavior
        bool beforeSwapReturnDelta;
        /// @notice Whether afterSwap should return a delta value to modify swap results
        bool afterSwapReturnDelta;
        /// @notice Whether afterAddLiquidity should return a delta value to modify results
        bool afterAddLiquidityReturnDelta;
        /// @notice Whether afterRemoveLiquidity should return a delta value to modify results
        bool afterRemoveLiquidityReturnDelta;
    }
}


/// @notice Parameter struct for `ModifyLiquidity` pool operations
struct ModifyLiquidityParams {
    // the lower and upper tick of the position
    int24 tickLower;
    int24 tickUpper;
    // how to modify the liquidity
    int256 liquidityDelta;
    // a value to set if you want unique liquidity positions at the same range
    bytes32 salt;
}






/**
 * @title UniV4Hook
 * @notice Implementation of a Uniswap V4 hook contract that passes address validation
 */
contract UniV4Hook {

    /// @notice Mapping to track current fee for each pool
    /// @dev Maps pool ID to current fee tier
    mapping(bytes32 => uint24) public poolCurrentFees;

    /// @notice The Uniswap Manager contract that allows us to update fees for our liquidity pool
    IPoolManager_Hook immutable public manager = IPoolManager_Hook(0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408);

    /// @notice The owner of the Hook contract that is able to adjust the liquidity pool fee
    address public owner;

    /// @notice The last updated Fee for the liquidity pool that this hook manages
    uint24 public currentFee = 0;
    
    /// @notice Emitted when a new Fee Rate is updated.
    /// @param newFee The new fee that will be used in the liquidity pool.
    /// @param oldFee The old fee that was used in the liquidity pool
    event NewFeeRate(uint24 newFee, uint24 oldFee);

    /// @notice Emitted when ownership of the contract is transferred
    /// @param previousOwner The address of the previous owner
    /// @param newOwner The address of the new owner
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /* ============ Constructor ============ */

    /// @notice Constructs a new Hook.
    /// @param _owner The owner we want of the Hook, will also be defined in the salt, see findValidSalt in HookMiner
    constructor(address _owner) {
        owner = _owner;
    }
    
    /* ============ Modifiers ============ */

    /// @notice Modifier that throws error if sender is not owner of this contract
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call");
        _;
    }
    
    

    /// @notice Gets the current fee for a pool
    /// @param poolKey The pool key to check
    /// @return currentFee The current fee tier on this Hook of the given poolKey
    function getCurrentPoolFee(PoolKey_Hook memory poolKey) public view returns (uint24 currentFee) {
       bytes32 poolId = toId(poolKey);
       currentFee = poolCurrentFees[poolId];
    }
    

    /// @notice Gets the current fee for a pool
    /// @param poolId The poolID in bytes32 to check
    /// @return currentFee The current fee tier of this Hook of the given poolID
    function getCurrentPoolFeeByPoolID(bytes32 poolId) public view returns (uint24 currentFee) {
       currentFee = poolCurrentFees[poolId];
    }

    
    /// @notice Generates a unique pool ID from pool key parameters
    /// @param poolKey The pool key structure containing currency pairs, fee, tick spacing, and hooks
    /// @return poolId The unique bytes32 identifier for the pool
    /// @dev Uses keccak256 hash of the entire poolKey struct (5 slots * 32 bytes = 0xa0)
    function toId(PoolKey_Hook memory poolKey) internal pure returns (bytes32 poolId) {
       assembly ("memory-safe") {
          // 0xa0 represents the total size of the poolKey struct (5 slots of 32 bytes)
          poolId := keccak256(poolKey, 0xa0)
       }
    }











   /// @notice Transfers ownership of the contract to a new address
   /// @param newOwner The address of the new owner
   /// @dev Can only be called by the current owner, validates newOwner is not zero address
   function transferOwner(address newOwner)public onlyOwner{
      require(newOwner != address(0), "New owner cannot be zero address");
      emit OwnershipTransferred(owner, newOwner);
      owner = newOwner;
   }
    /**
     * @notice Returns the hook's permissions
     * @return Permissions struct with afterInitialize set to true
     */
    function getHookPermissions() public pure returns (IHooks5.Permissions memory) {
        return IHooks5.Permissions({
            beforeInitialize: false,
            afterInitialize: true,
            beforeAddLiquidity: false,
            afterAddLiquidity: false,
            beforeRemoveLiquidity: false,
            afterRemoveLiquidity: false,
            beforeSwap: false,
            afterSwap: false,
            beforeDonate: false,
            afterDonate: false,
            beforeSwapReturnDelta: false,
            afterSwapReturnDelta: false,
            afterAddLiquidityReturnDelta: false,
            afterRemoveLiquidityReturnDelta: false
        });
    }
    /**
     * @notice Hook called after pool initialization
     * @dev Must return the correct selector to validate the hook
     * @return IHooks.afterInitialize.selector Function selector
     */
    function afterInitialize(
        address sender,
        PoolKey_Hook calldata key,
        uint160 sqrtPriceX96,
        int24 tick
    ) external returns (bytes4) {
        // Only allow the PoolManager to call this function
        require(msg.sender == address(manager), "Only PoolManager can call");
            
        // Set a default fee when the pool is initialized
        uint24 INITIAL_FEE = 20000; //2%

        bytes32 poolId = toId(key);
        poolCurrentFees[poolId] = INITIAL_FEE;
        emit NewFeeRate(INITIAL_FEE, 0);

        manager.updateDynamicLPFee(key, INITIAL_FEE);
        
        // IMPORTANT: Must return this exact selector
        return this.afterInitialize.selector;
    }


    /**
     * @notice Manually update the LP fee
     * @param key The pool key for the pool to update
     * @param newFee The new fee to charge for the given key
     */
    function forceUpdateLPFee(PoolKey_Hook calldata key, uint24 newFee) external onlyOwner {
        require (newFee<=90 * 10000 && newFee > 100, "Max is 90% fee rate ");
        manager.updateDynamicLPFee(key, newFee);
        emit NewFeeRate(newFee, currentFee);
        currentFee = newFee;
        bytes32 poolId = toId(key);
        poolCurrentFees[poolId] = currentFee;

    }
    
    /// @notice Allows the contract to receive ETH payments directly
    /// @dev This function is called when ETH is sent to the contract without any function call data
    receive() external payable {}
}








/**
 * @title HookMiner
 * @notice Contract to find a valid salt for deploying Uniswap V4 hooks
 */
contract HookMiner {
    /// @notice Bitmask containing all possible hook flags from the Uniswap V4 Hooks library
    /// @dev Used to validate that only valid hook flags are set in hook addresses
    uint160 constant ALL_HOOK_MASK = uint160((1 << 14) - 1); // Mask for all possible hook flags
    
    //uint160 constant BEFORE_INITIALIZE_FLAG = 1 << 13;
    uint160 constant AFTER_INITIALIZE_FLAG = 1 << 12;
    //uint160 constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 11;
    //uint160 constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 10;
    //uint160 constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 9;
    //uint160 constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 8;
    //uint160 constant BEFORE_SWAP_FLAG = 1 << 7;
    //uint160 constant AFTER_SWAP_FLAG = 1 << 6;
    //uint160 constant BEFORE_DONATE_FLAG = 1 << 5;
    //uint160 constant AFTER_DONATE_FLAG = 1 << 4;
    //uint160 constant BEFORE_SWAP_RETURNS_DELTA_FLAG = 1 << 3;
    //uint160 constant AFTER_SWAP_RETURNS_DELTA_FLAG = 1 << 2;
    //uint160 constant AFTER_ADD_LIQUIDITY_RETURNS_DELTA_FLAG = 1 << 1;
    //uint160 constant AFTER_REMOVE_LIQUIDITY_RETURNS_DELTA_FLAG = 1 << 0;
    // Define only the flags you want to be TRUE
    // For example, if we only want AFTER_INITIALIZE_FLAG to be true:
    uint160 public constant DESIRED_FLAGS = AFTER_INITIALIZE_FLAG;
    
    /// @notice Address that will be set as the owner of deployed hook contracts
    /// @dev Initially set to zero address, then updated to deployer in constructor
    address public ADMINOFHOOK = address(0);

    /// @notice Initializes the HookMiner contract and sets the admin for future hook deployments
    /// @dev Sets ADMINOFHOOK to the deployer's address, which will be used as owner in deployed hooks
    constructor() {
        ADMINOFHOOK = msg.sender;
    }


    /**
     * @notice Check if a hook address has exactly the desired flags
     * @param hook The hook address to check
     * @return True if the address has exactly the desired flags
     */
    function isValidHookAddress(address hook) public pure returns (bool) {
        // Convert to uint160 to work with the entire value
        uint160 hookInt = uint160(hook);
        
        // Check that:
        // 1. All DESIRED_FLAGS are set
        // 2. No other flags within ALL_HOOK_MASK are set
        return (hookInt & ALL_HOOK_MASK) == DESIRED_FLAGS;
    }
    
    /**
     * @notice Mine for a valid hook address
     * @param salt The starting salt value
     * @param deployer The deployer address
     * @param initCodeHash The init code hash of the hook contract
     * @param iterations Max number of iterations to try
     * @return The valid hook address and the successful salt
     */

    /**
     * @notice Find a salt value that will produce a valid hook address
     * @param startSalt The starting salt to search from
     * @param maxAttempts Maximum number of attempts to try
     * @return The valid salt value
     */
    function findValidSalt(uint256 startSalt, uint256 maxAttempts) public view returns (uint256, address) {
        // Get the bytecode and constructor args for the contract
        bytes memory bytecode = type(UniV4Hook).creationCode;
        bytes memory args = abi.encode(address(ADMINOFHOOK));
        
        // Try different salt values until we find a valid one
        for (uint256 i = 0; i < maxAttempts; i++) {
            uint256 salt = startSalt + i;
            address predictedAddress = computeAddress(salt, bytecode, args);
            
            if (isValidHookAddress(predictedAddress)) {
                return (salt, predictedAddress);
            }
        }
        
        revert("No valid salt found in range");
    }
    
    /**
     * @notice Compute the address a contract will be deployed to using CREATE2
     * @param salt The salt value
     * @param bytecode The contract bytecode
     * @param args The constructor arguments
     * @return The predicted contract address
     */
    function computeAddress(uint256 salt, bytes memory bytecode, bytes memory args) public view returns (address) {
        return address(uint160(uint256(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            keccak256(abi.encodePacked(bytecode, args))
        )))));
    }
    
    /**
     * @notice Deploy the hook with a valid address
     * @param salt The salt value to use (must be pre-validated)
     * @return The deployed hook address
     */
    function deployHook(uint256 salt) public returns (address) {
        // Create the combined bytecode with constructor arguments
        bytes memory bytecode = type(UniV4Hook).creationCode;
        bytes memory args = abi.encode(address(ADMINOFHOOK));
        bytes memory combined = abi.encodePacked(bytecode, args);
        
        // Deploy using CREATE2
        address payable hook;
        assembly {
            hook := create2(0, add(combined, 32), mload(combined), salt)
            if iszero(extcodesize(hook)) { revert(0, 0) }
        }
        
        // Verify the hook address is valid
        require(isValidHookAddress(hook), "Deployed hook address is not valid");
        
        return hook;
    }
}



/*
*
* MIT License
* ===========
*
* Copyright (c) 2025 B0x Token (B0x)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.   
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "viaIR": true,
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"newFee","type":"uint24"},{"indexed":false,"internalType":"uint24","name":"oldFee","type":"uint24"}],"name":"NewFeeRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"currency0","type":"address"},{"internalType":"address","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"address","name":"hooks","type":"address"}],"internalType":"struct PoolKey_Hook","name":"key","type":"tuple"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tick","type":"int24"}],"name":"afterInitialize","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"currency0","type":"address"},{"internalType":"address","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"address","name":"hooks","type":"address"}],"internalType":"struct PoolKey_Hook","name":"key","type":"tuple"},{"internalType":"uint24","name":"newFee","type":"uint24"}],"name":"forceUpdateLPFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"currency0","type":"address"},{"internalType":"address","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"address","name":"hooks","type":"address"}],"internalType":"struct PoolKey_Hook","name":"poolKey","type":"tuple"}],"name":"getCurrentPoolFee","outputs":[{"internalType":"uint24","name":"currentFee","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getCurrentPoolFeeByPoolID","outputs":[{"internalType":"uint24","name":"currentFee","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHookPermissions","outputs":[{"components":[{"internalType":"bool","name":"beforeInitialize","type":"bool"},{"internalType":"bool","name":"afterInitialize","type":"bool"},{"internalType":"bool","name":"beforeAddLiquidity","type":"bool"},{"internalType":"bool","name":"afterAddLiquidity","type":"bool"},{"internalType":"bool","name":"beforeRemoveLiquidity","type":"bool"},{"internalType":"bool","name":"afterRemoveLiquidity","type":"bool"},{"internalType":"bool","name":"beforeSwap","type":"bool"},{"internalType":"bool","name":"afterSwap","type":"bool"},{"internalType":"bool","name":"beforeDonate","type":"bool"},{"internalType":"bool","name":"afterDonate","type":"bool"},{"internalType":"bool","name":"beforeSwapReturnDelta","type":"bool"},{"internalType":"bool","name":"afterSwapReturnDelta","type":"bool"},{"internalType":"bool","name":"afterAddLiquidityReturnDelta","type":"bool"},{"internalType":"bool","name":"afterRemoveLiquidityReturnDelta","type":"bool"}],"internalType":"struct IHooks5.Permissions","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract IPoolManager_Hook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"poolCurrentFees","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

0x60a0346100a357601f610a6e38819003918201601f19168301916001600160401b038311848410176100a8578084926020946040528339810103126100a357516001600160a01b038116908190036100a3577305e73354cfdd6745c338b50bcfdfa3aa6fa03408608052600180546001600160b81b0319169190911790556040516109af90816100bf82396080518181816102de0152818161051401526107ba0152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816336f4cef5146107e957508063481c6a75146107a45780634fb2e45d146106e65780636fe7e6eb146104cf5780638da5cb5b146104a657806399e9406914610289578063beed6c5614610252578063c4e833ce146100ea578063cbb27fb5146100bc5763da3c300d0361000f57346100b957806003193601126100b957602062ffffff60015460a01c16604051908152f35b80fd5b50346100b95760203660031901126100b95762ffffff60406020926004358152808452205416604051908152f35b50346100b957806003193601126100b957806101c0916101a060405161010f8161083f565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152826101608201528261018082015201526040519061016e8261083f565b80825260208201916001835260408101828152606082018381526080830184815260a0840185815260c0850186815260e08601908782526101008701928884526101208801948986526101408901968a88526101608a01988b8a526101a06101808c019b8d8d52019b808d5260206040519e8f92835251151591015251151560408d015251151560608c015251151560808b015251151560a08a015251151560c089015251151560e08801525115156101008701525115156101208601525115156101408501525115156101608401525115156101808301525115156101a0820152f35b50346100b95760a03660031901126100b95762ffffff604060209260a0610278366108b0565b208152808452205416604051908152f35b50346100b957366003190160c0811261045c5760a0136100b95760a43562ffffff811690818103610449576102c960018060a01b03600154163314610937565b620dbba08211158061049c575b1561046057827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b1561045c57604051635275965160e01b8152906004356001600160a01b038116908190036104585760048301526024356001600160a01b0381169081900361045857602483015260443562ffffff81168091036104585760448301526064358060020b8091036104585760648301526084356001600160a01b03811691908290036104585760c483858193819560848401528960a48401525af1801561044d57610434575b50507f90704c6be6fd7d51000ce48f7b48a93ebaf53b877f41a12d7cad21fbdf522af1604060015493815190815262ffffff8560a01c166020820152a162ffffff60a01b1990911660a091821b62ffffff60a01b1617600181905590610412366108b0565b2082528160205262ffffff604083209160a01c1662ffffff1982541617905580f35b8161043e9161088e565b6104495782386103ad565b8280fd5b6040513d84823e3d90fd5b8380fd5b5080fd5b60405162461bcd60e51b8152602060048201526014602482015273026b0bc1034b9901c9812903332b2903930ba32960651b6044820152606490fd5b50606482116102d6565b50346100b957806003193601126100b9576001546040516001600160a01b039091168152602090f35b50346100b9576101003660031901126100b9576104ea610814565b5060a03660231901126100b95760c4356001600160a01b038116036100b95761051161082f565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316338190036106a1578160405161055181610872565b6024356001600160a01b038116919082810361045857808252604435946001600160a01b0386169081870361069d578660208501526064359362ffffff8516808603610699578560408301526084358060020b908181036106955780606085015260a4359260018060a01b03841694858503610691578085608060a0930152208b528a60205260408b20614e2062ffffff198254161790557f90704c6be6fd7d51000ce48f7b48a93ebaf53b877f41a12d7cad21fbdf522af160408051614e2081528d6020820152a1853b1561068d5760c4988b976040519d8e9c8d9b635275965160e01b8d525060048c01525060248a0152506044880152506064860152506084840152614e2060a48401525af1801561044d5761067d575b604051636fe7e6eb60e01b8152602090f35b816106879161088e565b3861066b565b8a80fd5b8b80fd5b8980fd5b8780fd5b8580fd5b60405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920506f6f6c4d616e616765722063616e2063616c6c000000000000006044820152606490fd5b50346100b95760203660031901126100b957610700610814565b6001546001600160a01b03811691610719338414610937565b6001600160a01b03169182156107605782907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08580a36001600160a01b0319161760015580f35b606460405162461bcd60e51b815260206004820152602060248201527f4e6577206f776e65722063616e6e6f74206265207a65726f20616464726573736044820152fd5b50346100b957806003193601126100b9576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b90503461045c57602036600319011261045c5762ffffff604060209360043581528085522054168152f35b600435906001600160a01b038216820361082a57565b600080fd5b60e435908160020b820361082a57565b6101c0810190811067ffffffffffffffff82111761085c57604052565b634e487b7160e01b600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761085c57604052565b90601f8019910116810190811067ffffffffffffffff82111761085c57604052565b60a090600319011261082a57604051906108c982610872565b816004356001600160a01b038116810361082a5781526024356001600160a01b038116810361082a57602082015260443562ffffff8116810361082a5760408201526064358060020b810361082a576060820152608435906001600160a01b038216820361082a5760800152565b1561093e57565b60405162461bcd60e51b815260206004820152601360248201527213db9b1e481bdddb995c8818d85b8818d85b1b606a1b6044820152606490fdfea26469706673582212200a323e6cbba96e464e9ccd8de5949a62ed17d2c4bb596949725ad235a020d86764736f6c634300081c00330000000000000000000000007e2b7f161c0376f69c62bffd345da07843a7b733

Deployed Bytecode

0x608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816336f4cef5146107e957508063481c6a75146107a45780634fb2e45d146106e65780636fe7e6eb146104cf5780638da5cb5b146104a657806399e9406914610289578063beed6c5614610252578063c4e833ce146100ea578063cbb27fb5146100bc5763da3c300d0361000f57346100b957806003193601126100b957602062ffffff60015460a01c16604051908152f35b80fd5b50346100b95760203660031901126100b95762ffffff60406020926004358152808452205416604051908152f35b50346100b957806003193601126100b957806101c0916101a060405161010f8161083f565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152826101608201528261018082015201526040519061016e8261083f565b80825260208201916001835260408101828152606082018381526080830184815260a0840185815260c0850186815260e08601908782526101008701928884526101208801948986526101408901968a88526101608a01988b8a526101a06101808c019b8d8d52019b808d5260206040519e8f92835251151591015251151560408d015251151560608c015251151560808b015251151560a08a015251151560c089015251151560e08801525115156101008701525115156101208601525115156101408501525115156101608401525115156101808301525115156101a0820152f35b50346100b95760a03660031901126100b95762ffffff604060209260a0610278366108b0565b208152808452205416604051908152f35b50346100b957366003190160c0811261045c5760a0136100b95760a43562ffffff811690818103610449576102c960018060a01b03600154163314610937565b620dbba08211158061049c575b1561046057827f00000000000000000000000005e73354cfdd6745c338b50bcfdfa3aa6fa034086001600160a01b0316803b1561045c57604051635275965160e01b8152906004356001600160a01b038116908190036104585760048301526024356001600160a01b0381169081900361045857602483015260443562ffffff81168091036104585760448301526064358060020b8091036104585760648301526084356001600160a01b03811691908290036104585760c483858193819560848401528960a48401525af1801561044d57610434575b50507f90704c6be6fd7d51000ce48f7b48a93ebaf53b877f41a12d7cad21fbdf522af1604060015493815190815262ffffff8560a01c166020820152a162ffffff60a01b1990911660a091821b62ffffff60a01b1617600181905590610412366108b0565b2082528160205262ffffff604083209160a01c1662ffffff1982541617905580f35b8161043e9161088e565b6104495782386103ad565b8280fd5b6040513d84823e3d90fd5b8380fd5b5080fd5b60405162461bcd60e51b8152602060048201526014602482015273026b0bc1034b9901c9812903332b2903930ba32960651b6044820152606490fd5b50606482116102d6565b50346100b957806003193601126100b9576001546040516001600160a01b039091168152602090f35b50346100b9576101003660031901126100b9576104ea610814565b5060a03660231901126100b95760c4356001600160a01b038116036100b95761051161082f565b507f00000000000000000000000005e73354cfdd6745c338b50bcfdfa3aa6fa034086001600160a01b0316338190036106a1578160405161055181610872565b6024356001600160a01b038116919082810361045857808252604435946001600160a01b0386169081870361069d578660208501526064359362ffffff8516808603610699578560408301526084358060020b908181036106955780606085015260a4359260018060a01b03841694858503610691578085608060a0930152208b528a60205260408b20614e2062ffffff198254161790557f90704c6be6fd7d51000ce48f7b48a93ebaf53b877f41a12d7cad21fbdf522af160408051614e2081528d6020820152a1853b1561068d5760c4988b976040519d8e9c8d9b635275965160e01b8d525060048c01525060248a0152506044880152506064860152506084840152614e2060a48401525af1801561044d5761067d575b604051636fe7e6eb60e01b8152602090f35b816106879161088e565b3861066b565b8a80fd5b8b80fd5b8980fd5b8780fd5b8580fd5b60405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920506f6f6c4d616e616765722063616e2063616c6c000000000000006044820152606490fd5b50346100b95760203660031901126100b957610700610814565b6001546001600160a01b03811691610719338414610937565b6001600160a01b03169182156107605782907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08580a36001600160a01b0319161760015580f35b606460405162461bcd60e51b815260206004820152602060248201527f4e6577206f776e65722063616e6e6f74206265207a65726f20616464726573736044820152fd5b50346100b957806003193601126100b9576040517f00000000000000000000000005e73354cfdd6745c338b50bcfdfa3aa6fa034086001600160a01b03168152602090f35b90503461045c57602036600319011261045c5762ffffff604060209360043581528085522054168152f35b600435906001600160a01b038216820361082a57565b600080fd5b60e435908160020b820361082a57565b6101c0810190811067ffffffffffffffff82111761085c57604052565b634e487b7160e01b600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761085c57604052565b90601f8019910116810190811067ffffffffffffffff82111761085c57604052565b60a090600319011261082a57604051906108c982610872565b816004356001600160a01b038116810361082a5781526024356001600160a01b038116810361082a57602082015260443562ffffff8116810361082a5760408201526064358060020b810361082a576060820152608435906001600160a01b038216820361082a5760800152565b1561093e57565b60405162461bcd60e51b815260206004820152601360248201527213db9b1e481bdddb995c8818d85b8818d85b1b606a1b6044820152606490fdfea26469706673582212200a323e6cbba96e464e9ccd8de5949a62ed17d2c4bb596949725ad235a020d86764736f6c634300081c0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0x794B1409ef4b40a90eC8AF62EaF4c8bf275e5000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.